|
Schedulers
FairThreads explicitely introduces schedulers, of type ft_scheduler_t . Before being used, a scheduler must be created
by calling the function ft_scheduler_create .
In order to be executed, a scheduler must be started by a call to the
function ft_scheduler_start . Note that several schedulers
can be used without problem simultaneously in the same program.
Threads
Fair threads are of type ft_thread_t . The call ft_thread_create(s,r,c,a) creates a thread in the
scheduler s . The thread is automatically started as soon as
it is created. The function r is executed by the
thread, and the parameter a is transmitted to it.
The function c is executed by the thread if it is stopped
(by ft_scheduler_stop ). The parameter a is also
transmitted to it, if this happens.
Events
Events are of the type ft_event_t . An event is created by
calling the function ft_event_create which takes as
parameter the scheduler in charge of it.
Automata
Automata are fair threads of the type ft_thread_t created
with the function ft_automaton_create . The thread returned by
ft_automaton_create(s,r,c,a) is executed as an automaton by
the scheduler s . The function r executed by the
automaton must be defined with the macro DEFINE_AUTOMATON .
Control of Threads
The call ft_scheduler_stop(t) gives to the scheduler which
executes the thread t the order to stop it. The stop will
become actual at the begining of the next instant of the scheduler, in
order to assure that t is in a stable state when stopped.
The call ft_scheduler_suspend(t) gives to the scheduler
which executes t the order to suspend t . The
suspension will become actual at the begining of the next instant of
the scheduler. The function ft_scheduler_resume is used to
resume execution of suspended threads.
Broadcast of Events
The function ft_scheduler_broadcast(e) gives to the
scheduler of the event e the order to broadcast it to all
threads running in the scheduler. The event will be actually generated
at the begining of the next instant of the scheduler. The call ft_scheduler_broadcast_value(e,v) associates the value v
to e (v can be read using ft_thread_get_value ).
Cooperation
The call ft_thread_cooperate() is the explicit way for the
calling thread to return control to the scheduler running it. The
call ft_thread_cooperate_n(i) is equivalent to a sequence of
i calls ft_thread_cooperate() .
Termination
The call ft_thread_join(t) suspends the execution of the
calling thread until the thread t terminates (either
normally or because it is stopped). Note that t needs not to be
linked or running in the scheduler of the calling thread. With ft_thread_join_n(t,i) the suspension takes at most i
instants.
Generating Events
The call ft_thread_generate(e) generates the event e in the scheduler which was associated to it, when created. The
call ft_thread_generate_value(e,v) adds v to the list of values associated to e during the current
instant (these values can be read using ft_thread_get_value ).
Awaiting Events
The call ft_thread_await(e) suspends the execution of the calling thread
until the generation of the event e . Execution is resumed as soon as the
event is generated. With ft_thread_await_n(e,i) , the waiting takes at most
i instants.
Selecting Events
The call ft_thread_select(k,array,mask) suspends the execution of the calling thread
until the generation of one element of array which is an array of k events. Then,
mask , which is an array of k boolean values, is set accordingly.
With ft_thread_select_n(k,array,mask,i) , the waiting takes at most i instants.
Getting Events Values
The call ft_thread_get_value(e,i,r) is an attempt to get the i th value
associated to the event e during the current instant. If such a
value exists, it is returned in r and the call immediately terminates. Otherwise,
the value NULL is returned at the next instant. The return code of the call indicates if
the call was sucessful or not.
Link and Unlink
The call ft_thread_unlink() unlinks the calling thread
t from the scheduler in which it was previously
running. Then, t will no longer synchronize, instant after
instant, with other threads linked to the scheduler. Actually, after
unlinking, t behaves as a standard native thread.
The call ft_thread_link(s) links the calling thread to the
scheduler s . The calling thread must be unlinked when
executing the call. The linkage becomes actual at the begining of the
next instant of s .
Locks
In presence of unlinked threads, locks can be needed to protect data
shared between unlinked and linked threads. Standard mutexes are used
for this purpose. The call ft_thread_mutex_lock(p) , where
p is a mutex, suspends the calling thread until the moment
where p can be locked. The lock is released using ft_thread_mutex_unlock . Locks owned by a thread are automatically
released when the thread terminates definitively or is stopped.
Automata are coded using macros. Here are the macros to define the automaton structure:
-
AUTOMATON(aut) declares the automaton aut .
-
DEFINE_AUTOMATON(aut) starts definition of the automaton aut .
-
BEGIN_AUTOMATON starts the state list.
-
END_AUTOMATON ends the state list.
The following macros start the state whose number is num :
-
STATE(num) introduces a standard state.
-
STATE_AWAIT(num,event) and STATE_AWAIT_N(num,event,delay) are states
to await event .
-
STATE_JOIN(num,thread) and STATE_JOIN_N(num,thread,delay)
are states to join thread .
-
STATE_STAY(num,n) is a state which keeps execution in it for n instants.
-
STATE_GET_VALUE(num,event,n,result) is a state to get the n th value
associated to event .
-
STATE_SELECT (num,n,array,mask) and STATE_SELECT_N (num,n,array,mask,delay)
generalise STATE_AWAIT and STATE_AWAIT_N to an array of events of length n .
Going from state to state is possible with:
-
GOTO(num) blocks execution for the current instant
and sets the state for the next instant to be state num .
-
GOTO_NEXT blocks execution for the current instant
and sets the state for the next instant to be the next state.
-
IMMEDIATE(num) forces execution to jump to state num
which is immediately executed.
-
RETURN immediately terminates the automaton.
Finally, the following macros define some special variables:
-
SELF is the automaton.
-
SET_LOCAL(data) sets the local data of the automaton.
-
LOCAL is the local data of the automaton.
-
ARGS is the argument that is passed at creation to the automaton.
-
RETURN_CODE is the error code set by macros run during automaton execution.
Current Thread
The calling thread is returned by ft_thread_self() .
Current Scheduler
The scheduler of the calling thread is returned by ft_thread_scheduler() .
Pthread
The call ft_pthread(t) returns the native pthread which
executes the fair thread t . This function gives direct
access to the Pthreads implementation of FairThreads. In the rest of the
paper, native thread and pthread will be considered as synonymous.
Exiting
The function ft_exit is equivalent to pthread_exit . The basic use of ft_exit is to terminate
the pthread which is running the function main , without
exiting from the whole process.
|