
load help;

@[name]
module.standard.jit
@[name]

@[title]
DaoJIT - JIT Compiler Based on LLVM
@[title]

@[text]

DaoJIT is a JIT compiler for Dao based on LLVM.
It provides JIT compiling for a subset of Dao virtual instructions.
DaoJIT is implemented as a automatically loadable module.
After it is enabled (by command line option @[green]-j@[green] or @[green]--jit@[green]),
it will search for a chunk of consecutive compilable instructions and
compile them into native code, and replace them with a single instruction (DVM_JITC)
which can invoke the JIT compiled code.
Currently, DaoJIT can only achieve good speedups for numeric intensive programs.

@[text]



@[name]
module.standard.sync
@[name]

@[title]
Synchronization
@[title]

@[text]


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.


@[subsection]Mutex@[subsection]

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.
@[code(dao)]
mutex = mutex();
@[code(dao)]
Then it can be locked or unlocked by,
@[code(dao)]
mutex.lock();
mutex.unlock();
mutex.trylock();
@[code(dao)]
By calling @[cyan]lock()@[cyan], 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 @[cyan]lock()@[cyan] may cause a deadlock. @[cyan]trylock()@[cyan] is the same
as @[cyan]lock()@[cyan] except that it will return immediately instead of blocking
the calling thread if the mutex is already locked.


@[subsection]Condition Variable@[subsection]

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.
@[code(dao)]
condvar = condition();
@[code(dao)]

Condition variable should always be used together
with a mutex. To wait on a condition,
@[code(dao)]
mtx.lock()
condvar.wait( mtx );
mtx.unlock();
@[code(dao)]

To wait on a condition for a maximum time,
@[code(dao)]
mtx.lock()
condvar.timedwait( mtx, seconds );
mtx.unlock();
@[code(dao)]

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


@[subsection]Semaphore@[subsection]

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,
@[code(dao)]
sema = semaphore( count );
@[code(dao)]

To access a resource guarded by a semaphore, use,
@[code(dao)]
sema.wait()
@[code(dao)]
If the resource is acquired, the count of @[cyan]sema@[cyan] will be decreased.

To release the resource, use
@[code(dao)]
sema.post()
@[code(dao)]
which will increase the count.


@[subsection]State@[subsection]
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 @[cyan]int@[cyan], @[cyan]float@[cyan], @[cyan]double@[cyan], @[cyan]complex@[cyan] or @[cyan]enum@[cyan] value:
@[code(dao)]
st = state<int>(0);

type status = enum<on; off; running; idle; finished; canceled>
st2 = state<status>($on + $idle);
@[code(dao)]

To perform basic read and write, @[cyan]value()@[cyan] and @[cyan]set()@[cyan] are provided,
the latter returns the old value of a state:
@[code(dao)]
if (st.value() == 0)
	old = st2.set($off);
@[code(dao)]

@[cyan]alter(old, new)@[cyan] can be used to assign @[cyan]new@[cyan] value to a state
if it currently contains @[cyan]old@[cyan] value. The routine returns non-zero if the
operation has succeeded:
@[code(dao)]
success = st.alter(0, 1);

if (success){
	... #will be executed by the only succeeded thread
}
@[code(dao)]

@[cyan]add()@[cyan] and @[cyan]sub()@[cyan] are meant to add/substract for numeric values and
append/remove symbols for a combined enum. The old value of state is returned:
@[code(dao)]
old = st.sub(1);
st2.add($finished);
@[code(dao)]

To block the current thread until a state is assigned the desired value, @[cyan]wait()@[cyan]
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, @[cyan]waitlist()@[cyan] is
provided:
@[code(dao)]
if (2 not in st.waitlist())
	success = st.wait(1, 5.0);
@[code(dao)]



@[text]
