    [NAME]
    ALL.module.standard.sync

    [TITLE]
    Synchronization

    [DESCRIPTION]

    Mutex, conditional variable and semaphore are the convetional way for thread
    synchronization. These constructs synchronize tasklet by block the native threads, so
    they are not the recommended way for synchronization and communication channels are the
    preferrable way.

     0.1  Mutex

    Mutex can be used to synchronize the accessing of shared data structures. It has two
    state: locked and unlocked. A mutex can be locked by only one thread. A thread is
    suspended when it attempt to lock a mutex which has been locked by another thread.

       1  mutex = mutex();

    Then it can be locked or unlocked by,

       1  mutex.lock();
       2  mutex.unlock();
       3  mutex.trylock();

    By calling lock(), the calling thread will be block if the mutex is already locked by
    another thread. If the mutex is locked by the same thread, a second calling of lock()
    may cause a deadlock. trylock() is the same as lock() except that it will return
    immediately instead of blocking the calling thread if the mutex is already locked.

     0.2  Condition Variable

    Condition variable is a synchronization device which allow a thread to be suspended if a
    condition is not satisified and resume execution when it is signaled. The basic
    operations on a condition is: wait on the condition, or signal the condition.

       1  condvar = condition();

    Condition variable should always be used together with a mutex. To wait on a condition,

       1  mtx.lock()
       2  condvar.wait( mtx );
       3  mtx.unlock();

    To wait on a condition for a maximum time,

       1  mtx.lock()
       2  condvar.timedwait( mtx, seconds );
       3  mtx.unlock();

    seconds can be a decimal, for example, condvar.timedwait( mtx, 0.005 ) will wait for
    five miliseconds.

     0.3  Semaphore

    Semaphore can be used to set a limit on resources. It maintains a count for the resource,
    and allows a thread to proceed, when it attempts to decrease a non-zero count. If the
    count already reaches 0 before the decrement, the thread will be suspended until the
    count becomes non-zero. When the thread finished using the resource, it should increase
    the count of semaphore. A semaphore must be created with an initial count,

       1  sema = semaphore( count );

    To access a resource guarded by a semaphore, use,

       1  sema.wait()

    If the resource is acquired, the count of sema will be decreased.
    To release the resource, use

       1  sema.post()

    which will increase the count.

     0.4  State
    State is an abstraction layer for multiple condition variables coupled with the
    principles of atomic operations. Semantically, it represent a state of certain process or
    object which can be set, altered or waited upon by arbitrary number of concurrent tasks.
    A state contains single value which can be assigned or modified using test-and-set and
    fetch-and-add principles. One or more threads can wait until a state reaches certain
    value, in this case the synchronization is similar to using conditional variables with
    broadcasting.
    A state can represent an int, float, double, complex or enum value:

       1  st = state<int>(0);
       2
       3  type status = enum<on; off; running; idle; finished; canceled>
       4  st2 = state<status>($on + $idle);

    To perform basic read and write, value() and set() are provided, the latter returns the
    old value of a state:

       1  if (st.value() == 0)
       2      old = st2.set($off);

    alter(old, new) can be used to assign new value to a state if it currently contains old
    value. The routine returns non-zero if the operation has succeeded:

       1  success = st.alter(0, 1);
       2
       3  if (success){
       4      ... #will be executed by the only succeeded thread
       5  }

    add() and sub() are meant to add/substract for numeric values and append/remove symbols
    for a combined enum. The old value of state is returned:

       1  old = st.sub(1);
       2  st2.add($finished);

    To block the current thread until a state is assigned the desired value, wait() is to be
    used. A timeout may specified, in this case the routine will return zero if time-outed.
    To determine what values are currently awaited by other threads, waitlist() is provided:

       1  if (2 not in st.waitlist())
       2      success = st.wait(1, 5.0);