<filename>samples/std/lock.py
from minpiler.std import MObject, L, M, inline, Processors, sync


class DekkersAlgorithm:
    """
    Seems to be slower than the Peterson's algorithm.
    https://en.wikipedia.org/wiki/Dekker%27s_algorithm
    """

    @inline
    @staticmethod
    def reset(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int) -> None:
        mem[addr_wants_to_enter_0] = 0
        mem[addr_wants_to_enter_1] = 0
        mem[addr_turn] = 0

    @inline
    @staticmethod
    def lock_processor0(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_wants_to_enter_0] = 1
        while mem[addr_wants_to_enter_1]:
            if mem[addr_turn] != 0:
                mem[addr_wants_to_enter_0] = 0
                while mem[addr_turn] != 0:
                    pass
                mem[addr_wants_to_enter_0] = 1

    @inline
    @staticmethod
    def lock_processor1(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_wants_to_enter_1] = 1
        while mem[addr_wants_to_enter_0]:
            if mem[addr_turn] != 1:
                mem[addr_wants_to_enter_1] = 0
                while mem[addr_turn] != 1:
                    pass
                mem[addr_wants_to_enter_1] = 1

    @inline
    @staticmethod
    def unlock_processor0(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_turn] = 1
        mem[addr_wants_to_enter_0] = 0

    @inline
    @staticmethod
    def unlock_processor1(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_turn] = 0
        mem[addr_wants_to_enter_1] = 0


class PetersonsAlgorithm:
    """
    A mutual exclusion algorithm for two processors. Uses 3 memory addresses.
    https://en.wikipedia.org/wiki/Peterson%27s_algorithm
    """

    @inline
    @staticmethod
    def reset(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int) -> None:
        mem[addr_wants_to_enter_0] = 0
        mem[addr_wants_to_enter_1] = 0
        mem[addr_turn] = 0

    @inline
    @staticmethod
    def lock_processor0(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_wants_to_enter_0] = 1
        mem[addr_turn] = 1
        while mem[addr_wants_to_enter_1] and mem[addr_turn] != 0:
            pass

    @inline
    @staticmethod
    def lock_processor1(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_wants_to_enter_1] = 1
        mem[addr_turn] = 0
        while mem[addr_wants_to_enter_0] and mem[addr_turn] != 1:
            pass

    @inline
    @staticmethod
    def unlock_processor0(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_wants_to_enter_0] = 0

    @inline
    @staticmethod
    def unlock_processor1(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_wants_to_enter_1] = 0


dekker: sync.SharedInt = 0
peterson: sync.SharedInt = 0
no_lock: sync.SharedInt = 0


@Processors.add
def dekker1():
    global dekker
    DekkersAlgorithm.lock_processor0(L.cell1, 10, 11, 12)
    dekker += 1
    DekkersAlgorithm.unlock_processor0(L.cell1, 10, 11, 12)


@Processors.add
def dekker2():
    global dekker
    DekkersAlgorithm.lock_processor1(L.cell1, 10, 11, 12)
    dekker += 1
    DekkersAlgorithm.unlock_processor1(L.cell1, 10, 11, 12)


@Processors.add
def peterson1():
    global peterson
    PetersonsAlgorithm.lock_processor0(L.cell1, 10, 11, 12)
    peterson += 1
    PetersonsAlgorithm.unlock_processor0(L.cell1, 10, 11, 12)


@Processors.add
def peterson2():
    global peterson
    PetersonsAlgorithm.lock_processor1(L.cell1, 10, 11, 12)
    peterson += 1
    PetersonsAlgorithm.unlock_processor1(L.cell1, 10, 11, 12)


@Processors.add
def processor3():
    global no_lock
    no_lock += 1


@Processors.add
def processor4():
    M.print(f'dekker={dekker}, peterson={peterson}, no_lock={no_lock}')
    M.print_flush(L.message1)


while True:
    pass

<filename>samples/std/lock.py
from minpiler.std import MObject, L, M, inline, Processors, sync


class DekkersAlgorithm:
    """
    Seems to be slower than the Peterson's algorithm.
    https://en.wikipedia.org/wiki/Dekker%27s_algorithm
    """

    @inline
    @staticmethod
    def reset(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int) -> None:
        mem[addr_wants_to_enter_0] = 0
        mem[addr_wants_to_enter_1] = 0
        mem[addr_turn] = 0

    @inline
    @staticmethod
    def lock_processor0(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_wants_to_enter_0] = 1
        while mem[addr_wants_to_enter_1]:
            if mem[addr_turn] != 0:
                mem[addr_wants_to_enter_0] = 0
                while mem[addr_turn] != 0:
                    pass
                mem[addr_wants_to_enter_0] = 1

    @inline
    @staticmethod
    def lock_processor1(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_wants_to_enter_1] = 1
        while mem[addr_wants_to_enter_0]:
            if mem[addr_turn] != 1:
                mem[addr_wants_to_enter_1] = 0
                while mem[addr_turn] != 1:
                    pass
                mem[addr_wants_to_enter_1] = 1

    @inline
    @staticmethod
    def unlock_processor0(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_turn] = 1
        mem[addr_wants_to_enter_0] = 0

    @inline
    @staticmethod
    def unlock_processor1(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_turn] = 0
        mem[addr_wants_to_enter_1] = 0


class PetersonsAlgorithm:
    """
    A mutual exclusion algorithm for two processors. Uses 3 memory addresses.
    https://en.wikipedia.org/wiki/Peterson%27s_algorithm
    """

    @inline
    @staticmethod
    def reset(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int) -> None:
        mem[addr_wants_to_enter_0] = 0
        mem[addr_wants_to_enter_1] = 0
        mem[addr_turn] = 0

    @inline
    @staticmethod
    def lock_processor0(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_wants_to_enter_0] = 1
        mem[addr_turn] = 1
        while mem[addr_wants_to_enter_1] and mem[addr_turn] != 0:
            pass

    @inline
    @staticmethod
    def lock_processor1(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_wants_to_enter_1] = 1
        mem[addr_turn] = 0
        while mem[addr_wants_to_enter_0] and mem[addr_turn] != 1:
            pass

    @inline
    @staticmethod
    def unlock_processor0(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_wants_to_enter_0] = 0

    @inline
    @staticmethod
    def unlock_processor1(mem: MObject, addr_wants_to_enter_0: int, addr_wants_to_enter_1: int, addr_turn: int):
        mem[addr_wants_to_enter_1] = 0


dekker: sync.SharedInt = 0
peterson: sync.SharedInt = 0
no_lock: sync.SharedInt = 0


@Processors.add
def dekker1():
    global dekker
    DekkersAlgorithm.lock_processor0(L.cell1, 10, 11, 12)
    dekker += 1
    DekkersAlgorithm.unlock_processor0(L.cell1, 10, 11, 12)


@Processors.add
def dekker2():
    global dekker
    DekkersAlgorithm.lock_processor1(L.cell1, 10, 11, 12)
    dekker += 1
    DekkersAlgorithm.unlock_processor1(L.cell1, 10, 11, 12)


@Processors.add
def peterson1():
    global peterson
    PetersonsAlgorithm.lock_processor0(L.cell1, 10, 11, 12)
    peterson += 1
    PetersonsAlgorithm.unlock_processor0(L.cell1, 10, 11, 12)


@Processors.add
def peterson2():
    global peterson
    PetersonsAlgorithm.lock_processor1(L.cell1, 10, 11, 12)
    peterson += 1
    PetersonsAlgorithm.unlock_processor1(L.cell1, 10, 11, 12)


@Processors.add
def processor3():
    global no_lock
    no_lock += 1


@Processors.add
def processor4():
    M.print(f'dekker={dekker}, peterson={peterson}, no_lock={no_lock}')
    M.print_flush(L.message1)


while True:
    pass

Seems to be slower than the Peterson's algorithm.     https://en.wikipedia.org/wiki/Dekker%27s_algorithm A mutual exclusion algorithm for two processors. Uses 3 memory addresses.     https://en.wikipedia.org/wiki/Peterson%27s_algorithm