StackThreads/MP: version 0.77 User's Guide
int st_join_counter_init(j, v); @ int st_join_counter_wait(j); @ int st_join_counter_finish_1(j, v); @ int st_join_counter_finish(j) @ int st_join_counter_spawn_1(j, v); @ int st_join_counter_spawn(j) @ int st_join_counter_destroy(j); @ st_join_counter_t * j, unsigned long v; @ st_join_counter_t x = ST_JOIN_COUNTER_INITIALIZER;
Join counter provides a simple producer-consume style
synchronization. It internally maintains a non-negative integer
(counter). st_join_counter_init(j, v)
initializes the
counter of j to v. It must be called when no other threads
access to j concurrently (e.g., immediately after creation).
st_join_counter_finish_1(j, v)
and
st_join_counter_spawn_1(j, v)
atomically decrements and
increments the counter of j by v,
respectively. st_join_counter_finish(j)
and
st_join_counter_spawn(j)
are synonyms for
st_join_counter_finish_1(j, 1)
and
st_join_counter_spawn_1(j, 1)
, respectively.
st_join_counter_wait(j)
waits for the counter of j to
become zero. st_join_counter_destroy(j)
destroys j. It
must be called when no other threads access to j concurrently. It
also checks if the counter is zero. If this is not the case, it signals
an error. st_join_counter_t x = ST_JOIN_COUNTER_INITIALIZER(c)
defines a global or static variable
that is initialized to c.
It is allowed to recycle a storage for a counter many times, as long as the counter is correctly initialized before each use and destroyed after each use.
Typically, you use a synchronization counter to wait for the completion (or an arrival to a certain point) of child threads. Here is a simple example.
{ st_join_counter_t j[1]; st_join_counter_init(j, n); for (i = 0; i < n; i++) { ST_THREAD_CREATE(f(..., j)); } st_join_counter_wait(j); }
Assume that f(..., j)
calls st_join_counter_finish(j)
when it is finished, st_join_counter_wait(j)
waits for the
completion of all threads created in the loop.
st_join_counter_spawn
and st_join_counter_spawn_1
are
provided in cases where you do not know how many threads are going to be
associated with the counter. Each time you create a thread, you
increment the counter by st_join_counter_spawn
and then create a
thread.
All these functions return zero upon success and signals an error if an error occurred.