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.