# Path: offset/sync/atomic.py
# class AtomicLong(object):
#     def __init__(self, initial_value):
#     def __repr__(self):
#     def value(self):
#     def value(self, new):
#     def add(self, delta):
#     def __iadd__(self, inc):
#     def __isub__(self, dec):
#     def __eq__(self, other):
#     def __ne__(self, other):
#     def __lt__(self, other):
# 
# Path: offset/sync/sema.py
# class Semaphore(object):
#     """ Semaphore implementation exposed to offset
# 
#     Intended use is provide a sleep and wakeup primitive that can be used in the
#     contended case of other synchronization primitives.
# 
#     Thus it targets the same goal as Linux's futex, but it has much simpler
#     semantics.
# 
#     That is, don't think of these as semaphores. Think of them as a way to
#     implement sleep and wakeup such that every sleep is paired with a single
#     wakeup, even if, due to races, the wakeup happens before the sleep.
# 
#     See Mullender and Cox, ``Semaphores in Plan 9,''
#     http://swtch.com/semaphore.pdf
# 
#     Comment and code based on the Go code:
#     http://golang.org/src/pkg/runtime/sema.goc
#     """
# 
#     def __init__(self, value=0):
#         self.sema = AtomicLong(value)
#         self.nwait = AtomicLong(1)
#         self.waiters = deque()
# 
#     def can_acquire(self):
#         if self.sema > 0:
#             self.sema -= 1
#             return True
#         return False
# 
#     def acquire(self):
#         if self.can_acquire():
#             return
# 
#         t0 = 0
#         releasetime = 0
# 
#         while True:
#             self.nwait += 1
#             self.waiters.append(proc.current())
# 
#             if self.can_acquire():
#                 self.nwait -= 1
#                 self.waiters.remove(proc.current())
#                 return
# 
#             park()
# 
#     __enter__ = acquire
# 
#     def release(self):
#         self.sema += 1
# 
#         if self.nwait == 0:
#             return
# 
#         try:
#             waiter = self.waiters.pop()
#         except IndexError:
#             return
# 
#         self.nwait -= 1
#         waiter.ready()
# 
#     def __exit__(self, t, v, tb):
#         return self.release()


from .atomic import ffi, lib
from .sema import Semaphore

            if old & MUTEX_LOCKED:
                new = old + 1<<MUTEX_WAITER_SHIFT

            if awoke:
                new &= ~(1<<MUTEX_WOKEN)


            if lib.long_bool_compare_and_swap(self.state, old, new):
                if old & MUTEX_LOCKED == 0:
                    break

                self.sema.acquire()
                awoke = True

    def __enter__(self):
        return self.lock()

    def unlock(self):
        new = lib.long_add_and_fetch(self.state, -MUTEX_LOCKED)
        if (new + MUTEX_LOCKED) & MUTEX_LOCKED == 0:
            raise RuntimeError("sync: unlock of unlocked mutex")

        old = new
        while True:
            if (old >> MUTEX_WAITER_SHIFT == 0
                    or old & (MUTEX_LOCKED | MUTEX_WOKEN) != 0):
                return

            new = (old - 1 << MUTEX_WAITER_SHIFT) | MUTEX_WOKEN

# Path: offset/sync/atomic.py
# class AtomicLong(object):
#     def __init__(self, initial_value):
#     def __repr__(self):
#     def value(self):
#     def value(self, new):
#     def add(self, delta):
#     def __iadd__(self, inc):
#     def __isub__(self, dec):
#     def __eq__(self, other):
#     def __ne__(self, other):
#     def __lt__(self, other):
# 
# Path: offset/sync/sema.py
# class Semaphore(object):
#     """ Semaphore implementation exposed to offset
# 
#     Intended use is provide a sleep and wakeup primitive that can be used in the
#     contended case of other synchronization primitives.
# 
#     Thus it targets the same goal as Linux's futex, but it has much simpler
#     semantics.
# 
#     That is, don't think of these as semaphores. Think of them as a way to
#     implement sleep and wakeup such that every sleep is paired with a single
#     wakeup, even if, due to races, the wakeup happens before the sleep.
# 
#     See Mullender and Cox, ``Semaphores in Plan 9,''
#     http://swtch.com/semaphore.pdf
# 
#     Comment and code based on the Go code:
#     http://golang.org/src/pkg/runtime/sema.goc
#     """
# 
#     def __init__(self, value=0):
#         self.sema = AtomicLong(value)
#         self.nwait = AtomicLong(1)
#         self.waiters = deque()
# 
#     def can_acquire(self):
#         if self.sema > 0:
#             self.sema -= 1
#             return True
#         return False
# 
#     def acquire(self):
#         if self.can_acquire():
#             return
# 
#         t0 = 0
#         releasetime = 0
# 
#         while True:
#             self.nwait += 1
#             self.waiters.append(proc.current())
# 
#             if self.can_acquire():
#                 self.nwait -= 1
#                 self.waiters.remove(proc.current())
#                 return
# 
#             park()
# 
#     __enter__ = acquire
# 
#     def release(self):
#         self.sema += 1
# 
#         if self.nwait == 0:
#             return
# 
#         try:
#             waiter = self.waiters.pop()
#         except IndexError:
#             return
# 
#         self.nwait -= 1
#         waiter.ready()
# 
#     def __exit__(self, t, v, tb):
#         return self.release()


# Path: offset/sync/mutex.py
from .atomic import ffi, lib
from .sema import Semaphore


            if old & MUTEX_LOCKED:
                new = old + 1<<MUTEX_WAITER_SHIFT

            if awoke:
                new &= ~(1<<MUTEX_WOKEN)


            if lib.long_bool_compare_and_swap(self.state, old, new):
                if old & MUTEX_LOCKED == 0:
                    break

                self.sema.acquire()
                awoke = True

    def __enter__(self):
        return self.lock()

    def unlock(self):
        new = lib.long_add_and_fetch(self.state, -MUTEX_LOCKED)
        if (new + MUTEX_LOCKED) & MUTEX_LOCKED == 0:
            raise RuntimeError("sync: unlock of unlocked mutex")

        old = new
        while True:
            if (old >> MUTEX_WAITER_SHIFT == 0
                    or old & (MUTEX_LOCKED | MUTEX_WOKEN) != 0):
                return

            new = (old - 1 << MUTEX_WAITER_SHIFT) | MUTEX_WOKEN

            if lib.long_bool_compare_and_swap(self.state, old, new):