PREV UP NEXT StackThreads/MP: version 0.77 User's Guide

3.3.1: Join Counter

        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.