[NAME]
ALL.module.standard.sync

[TITLE]
Synchronization

[DESCRIPTION]

Mutex, conditional variable and semaphore are the convetional way for thread synchroniza
tion. These constructs synchronize tasklet by block the native threads, so they are not t
he 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 stat
e: locked and unlocked. A mutex can be locked by only one thread. A thread is suspended w
hen 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 ano
ther thread. If the mutex is locked by the same thread, a second calling of lock() may ca
use a deadlock. trylock() is the same as lock() except that it will return immediately in
stead 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 operation
s 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 cou
nt already reaches 0 before the decrement, the thread will be suspended until the count b
ecomes non-zero. When the thread finished using the resource, it should increase the coun
t 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 principle
s of atomic operations. Semantically, it represent a state of certain process or object w
hich 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 o
ld 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 v
alue. 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 f
or 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. T
o 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);