Skip to content

Instantly share code, notes, and snippets.

@exbotanical
Created July 16, 2021 15:10
Show Gist options
  • Save exbotanical/41595446b7e3932897e737618784d49c to your computer and use it in GitHub Desktop.
Save exbotanical/41595446b7e3932897e737618784d49c to your computer and use it in GitHub Desktop.
simple implementation of POSIX thread barriers
#include <pthread.h>
#include <stdint.h>
#include <stdbool.h>
typedef struct barrier {
uint32_t threshold;
uint32_t curr_wait; /* from 0 -> threshold - 1*/
pthread_cond_t cv;
pthread_mutex_t mutex; /* perform mutually exclusive ops on a thread barrier */
bool is_ready; /* is barrier disposition in progress? */
pthread_cond_t busy_cv; /* thread barrier in disposition progress state, block inbound threads */
} barrier_t;
void barrier_init(barrier_t* barrier, uint32_t threshold);
void barrier_wait(barrier_t* barrier);
void barrier_init(barrier_t* barrier, uint32_t threshold) {
barrier->threshold = threshold;
barrier->curr_wait = 0;
pthread_cond_init(&barrier->cv, NULL);
pthread_mutex_init(&barrier->mutex, NULL);
barrier->is_ready = true;
pthread_cond_init(&barrier->busy_cv, NULL);
}
void barrier_wait(barrier_t* barrier) {
pthread_mutex_lock(&barrier->mutex);
while (!barrier->is_ready) {
pthread_cond_wait(&barrier->busy_cv, &barrier->mutex);
}
if (barrier->curr_wait + 1 == barrier->threshold) {
barrier->is_ready = false;
pthread_cond_signal(&barrier->cv);
pthread_mutex_lock(&barrier->mutex);
return;
}
barrier->curr_wait++;
pthread_cond_wait(&barrier->cv, &barrier->mutex);
barrier->curr_wait--;
if (barrier->curr_wait == 0) {
barrier->is_ready = true;
pthread_cond_broadcast(&barrier->cv);
} else {
pthread_cond_signal(&barrier->cv);
}
pthread_mutex_lock(&barrier->mutex);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment