barrier.c
/**
* @file barrier.c
*
* Demonstrates how to build a barrier with condition variables.
*
* gcc -pthread barrier.c -o barrier
*/
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#define NUM_THREADS 25
pthread_mutex_t bar_mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t bar_condition = PTHREAD_COND_INITIALIZER;
int bar_count;
void barrier(void)
{
pthread_mutex_lock(&bar_mutex);
bar_count++;
if (bar_count == NUM_THREADS) {
// This is the LAST thread to enter the barrier
// Set bar_count to 0 so we can use the barrier again:
bar_count = 0;
// Tell all the sleeping threads to wake up!
pthread_cond_broadcast(&bar_condition);
} else {
// Wait unlocks mutex and puts thread to sleep.
// Put wait in while loop in case some other
// event awakens thread.
while (pthread_cond_wait(&bar_condition, &bar_mutex) != 0)
{
// Wait for a signal... if pthread_cond_wait returns a nonzero
// status code then it may have been a spurious wakeup, so keep
// waiting.
}
// Mutex is relocked at this point; we need to unlock it below.
}
pthread_mutex_unlock(&bar_mutex);
}
void *thread_procedure(void *arg)
{
/* Each thread will sleep for a random amount of time and then print a
* single dollar sign '$' character. Since we have a barrier below, all the
* dollar signs will appear at roughly the same time. */
int r = random() % 5;
sleep(r);
// ----------------- BARRIER ------------------ //
//
barrier();
//
// All threads MUST call barrier() before they
// can proceed. Try commenting out the call to
// barrier() to see how the program's output
// changes.
// -------------------------------------------- //
printf("$");
fflush(stdout);
return NULL;
}
int main(void)
{
printf("Starting threads...\n");
pthread_t threads[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; ++i) {
pthread_create(&threads[i], NULL, thread_procedure, NULL);
}
for (int i = 0; i < NUM_THREADS; ++i) {
pthread_join(threads[i], NULL);
}
puts("");
printf("Done!\n");
printf("Now rerun the program without the call to barrier()...\n");
return 0;
}