3 * @purpose Declaration for a pthread barrier
4 * @author Sam Moore (20503628) 2012
7 // The barrier can be used as follows:
9 // Think of the barrier as relating to a section of work that must be completed by a team of threads
10 // The barrier is initialised with the number of threads in the team
11 // Each thread in the team calls Barrier_Join when finished; this ensures all threads reach Barrier_Join before continuing.
13 // To make it conceptually easier to synchronise with threads that are not part of the "team":
14 // I have introduced Barrier_Wait, and Barrier_Enter
15 // Barrier_Wait is used to either:
16 // 1. Immediately continue if threads have already completed a task and called Barrier_Join
17 // 2. Sleep until all threads call Barrier_Join if they have not completed their task
18 // Barrier_Enter should be called in threads that belong to the "team", to indicate that they have started their task.
19 // Otherwise, Barrier_Wait will generally fail.
20 // This requires a single boolean, and makes things easier (for me) to understand, so I think it is worth it.
21 // Also, *any* number of threads may call Barrier_Wait; it is not restricted by the number of threads actually doing the "work".
22 // If there are no threads calling Barrier_Wait, then Barrier_Enter is not needed; the first thread to call Barrier_Join always activates the barrier. It is always deactivated when threads leave.
32 * Structure to represent a barrier for multiple threads
33 * @param mutex - Mutex around the counter
34 * @param busy - Counter of threads within the barrier
35 * @param threads_done_cv - Condition to wake up threads waiting on barrier once all working threads have left it
39 pthread_mutex_t mutex;
40 unsigned threads_done; // Counter of threads which are finished
41 unsigned total_threads; // Total number of threads participating in the barrier
42 bool active; // Indicates whether barrier is active
43 pthread_cond_t threads_done_cv;
48 void Barrier_Init(Barrier * b, unsigned total_threads);
49 void Barrier_Enter(Barrier * b);
50 void Barrier_Join(Barrier * b);
51 void Barrier_Wait(Barrier * b);
53 void * Barrier_JoinCall(Barrier * b, void*(*call)(void*), void * args);
55 void Barrier_ForceExit(Barrier * b); // Force all threads to exit barrier