StackThreads/MP: version 0.77 User's Guide
StackThreads/MP provides a convenient way to create a worker group that
executes a given StackThreads/MP procedure
(stf_create_sync_worker_group
and
stf_create_async_worker_group
). They serve as gates from a sequential
procedure to any StackThreads/MP procedure. They create a specified
number of workers, setup pointers to the worker local storages, and then
call the specified entry procedure. The entry procedure is a
StackThreads/MP procedure and thus is allowed to access any StackThreads/MP
primitives.
void* stf_create_sync_worker_group(wgc, n, f, a0, a1, a2, a3) @ worker_group_conf_t wgc; int n; @ void * (*f)(void *, void *, void *, void*); @ void * a0, * a1, * a2, * a3;
workers. The job of the worker group is given by an entry procedure
f and arguments to it (a0 ... a3). Specifically, the worker
group's job is to complete a procedure call f(a0, a1, a2, a3)
. stf_create_sync_worker_group
returns when
f(a0, a1, a2, a3)
returns. The return value
of f(a0, a1, a2, a3)
becomes the return value
of the stf_create_sync_worker_group
. If non-zero value is given
to wgc, it is a pointer to a structure that describes configuration
options of the worker. If wgc is zero, a default configuration is
used. stf_create_sync_worker_group
can be called both from a
sequential procedure and from a StackThreads/MP procedure. If you call
this procedure from a sequential module (a module that is compiled by
plain gcc
), include <st_foreign.h>
, which defines the
correct prototype for the procedure.
For example, suppose you are writing an X Window application and wish to add a callback function that uses StackThreads/MP primitives. Also assume that you don't want to recompile the Xlib or your administrator didn't allow you to replace nor duplicate it, thus the Xlib itself must remain sequential. In this case, you first write a StackThreads/MP procedure that accomplishes your job.
... my_st_proc(...) { @ /* do whatever you can do with @ StackThreads/MP */ @ ST_THREAD_CREATE(...); @ ... @ ST_THREAD_CREATE(...); @ ... }
You may want to write a wrapper procedure of the above function, so that
the entry procedure conforms to the interface of
stf_create_sync_worker_group
. The wrapper's job is simply to pass
parameters to the above procedure, possibly casting them to meaningful
types. It must be a StackThreads/MP procedure.
void * my_st_proc_wrapper(void * a0, void * a1, void * a2, void * a3) { @ /* you translate arguments somehow */ @ ... @ /* and call my_st_proc to do a real job */ @ my_st_proc(...); }
Finally, you write a callback procedure that invokes the entry procedure and registers it. This must be a sequential procedure (compiled by a plain C compiler), because X library calls that procedure.
void my_callback(...) { @ int n = ...; @ void * a0 = ..., * a1 = ..., @ * a2 = ...; * a3 = ...; @ stf_create_sync_worker(0, n, my_st_proc_entry, a0, a1, a2, a3); } @ @ ... @ XAddCallback(my_callback, ...); @ ...
stf_create_async_worker
is an asynchronous version of
stf_create_sync_worker
. See Workers and Worker Groups for details.