# Path: offset/sync/mutex.py
# class Mutex(Locker):
#     """  A Mutex is a mutual exclusion lock. """
# 
#     def __init__(self):
#         self.state =  ffi.new('long *', 0)
#         self.sema = Semaphore(0)
# 
# 
#     def lock(self):
#         """ locks the coroutine """
# 
#         if lib.long_bool_compare_and_swap(self.state, 0, MUTEX_LOCKED):
#             return
# 
#         awoke = False
#         while True:
#             old = self.state[0]
#             new = old | MUTEX_LOCKED
# 
#             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):
#                 self.sema.release()
#                 return
#             old = self.state[0]
# 
#     def __exit__(self, t, v, tb):
#         self.unlock()
# 
# 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 .mutex import Mutex
from .sema import Semaphore
class Cond(object):
    """ Cond implements a condition variable, a rendezvous point for coroutines
    waiting for or announcing the occurrence of an event.

    Each Cond has an associated Locker L (often a Mutex or RWMutex), which
    must be held when changing the condition and when calling the ``wait`` method.
    """


    def __init__(self, l):
        self.l = l
        self.m = Mutex()

        # We must be careful to make sure that when ``signal``
        # releases a semaphore, the corresponding acquire is
        # executed by a coroutine that was already waiting at
        # the time of the call to ``signal``, not one that arrived later.
        # To ensure this, we segment waiting coroutines into
        # generations punctuated by calls to ``signal``.  Each call to
        # ``signal`` begins another generation if there are no coroutines
        # left in older generations for it to wake.  Because of this
        # optimization (only begin another generation if there
        # are no older coroutines left), we only need to keep track
        # of the two most recent generations, which we call old
        # and new.

        self.old_waiters = 0 # number of waiters in old generation...
        self.old_sema = Semaphore() # ... waiting on this semaphore

        self.new_waiters = 0 # number of waiters in new generation...

# Path: offset/sync/mutex.py
# class Mutex(Locker):
#     """  A Mutex is a mutual exclusion lock. """
# 
#     def __init__(self):
#         self.state =  ffi.new('long *', 0)
#         self.sema = Semaphore(0)
# 
# 
#     def lock(self):
#         """ locks the coroutine """
# 
#         if lib.long_bool_compare_and_swap(self.state, 0, MUTEX_LOCKED):
#             return
# 
#         awoke = False
#         while True:
#             old = self.state[0]
#             new = old | MUTEX_LOCKED
# 
#             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):
#                 self.sema.release()
#                 return
#             old = self.state[0]
# 
#     def __exit__(self, t, v, tb):
#         self.unlock()
# 
# 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/cond.py
from .mutex import Mutex
from .sema import Semaphore

class Cond(object):
    """ Cond implements a condition variable, a rendezvous point for coroutines
    waiting for or announcing the occurrence of an event.

    Each Cond has an associated Locker L (often a Mutex or RWMutex), which
    must be held when changing the condition and when calling the ``wait`` method.
    """


    def __init__(self, l):
        self.l = l
        self.m = Mutex()

        # We must be careful to make sure that when ``signal``
        # releases a semaphore, the corresponding acquire is
        # executed by a coroutine that was already waiting at
        # the time of the call to ``signal``, not one that arrived later.
        # To ensure this, we segment waiting coroutines into
        # generations punctuated by calls to ``signal``.  Each call to
        # ``signal`` begins another generation if there are no coroutines
        # left in older generations for it to wake.  Because of this
        # optimization (only begin another generation if there
        # are no older coroutines left), we only need to keep track
        # of the two most recent generations, which we call old
        # and new.

        self.old_waiters = 0 # number of waiters in old generation...
        self.old_sema = Semaphore() # ... waiting on this semaphore

        self.new_waiters = 0 # number of waiters in new generation...

        self.new_sema = Semaphore() # ... waiting on this semaphore