StackThreads/MP: version 0.77 User's Guide
The method just described is suitable when the following conditions are satisfied:
stf_create_sync_worker_group
or
stf_create_async_worker_group
is called. This will be the case when
the job you wish to accomplish is fairly large (taking a second or more
by a single CPU).
There are situations where the method is not very appropriate. For
example, you may want to write a tiny procedure for comparing two items
and pass it to qsort
function or write a tiny callback procedure
that just displays a menu. Such procedures have nothing to do with
parallelism, hence creating a worker group for each callback is
impractical.
StackThreads/MP provides a way to declare that a StackThreads/MP procedure may be called from a sequential procedure. Specifically, A StackThreads/MP procedure can be safely called from a sequential procedure when the following conditions are met:
ST_CALLBACK_BEGIN();
variable declaration, so make sure you put it in a place where a variable declaration is allowed.
ST_CALLBACK_END();
precisely, before returning from the procedure and after any procedure call performed within the procedure).
ST_CREATE_THREAD
,
ST_POLLING
, and any blocking synchronization primitives such as
st_mutex_lock
and st_mutex_unlock
).
Procedures written according to these rules may be called both from sequential procedures and from StackThreads/MP procedures. Here is an example:
int less_than_p(void * a, void * b) { @ ST_CALLBACK_BEGIN(); @ int xa = evaluate(a); @ int xb = evaluate(b); @ ST_CALLBACK_END(); @ return xa - xb; }
Here, evaluate
may be a sequential procedure, a regular
StackThreads/MP procedure, or another StackThreads/MP procedure that
again surrounds its body by ST_CALLBACK_BEGIN()
and
ST_CALLBACK_END()
.
With this setup, you can pass the function less_than_p
to the
qsort
:
qsort(a, n, sizeof(element), less_than_p);
In the above three rules, the last one is very restrictive. In essence,
it says that even though such a callback procedure is compiled as a
StackThreads/MP procedure, it must stay sequential, in the sense it does
not use any threading operation. In our example, evaluate
may not
use StackThreads/MP primitives such as ST_POLLING
,
ST_THREAD_CREATE
, and other synchronization primitives.
You might ask, "Given a callback cannot call any StackThreads/MP
primitives after all, why do I want to write it as a StackThreads/MP
procedure?" As a matter of fact, you can always write all such
procedures in a separate file and compile them using plain
gcc
. What the current StackThreads/MP currently supports is no
more powerful than this solution. We provide these declarations to allow
callbacks and proper StackThreads/MP procedures to be written in a
single file.