/*
 * Filename: thread_barrier.c
 * Date:     2025/02/16 08:36
 * Author:   Jan Faigl
 */

#include <assert.h>
#include <pthread.h>

#include "thread_barrier.h"

typedef struct {
   pthread_mutex_t mtx;
   pthread_cond_t cond;
   int n; // number of threads
   int count; // number of threads
} thread_barrier;

static thread_barrier b;

// - function -----------------------------------------------------------------
void barrier_init(int n)
{
   assert(pthread_mutex_init(&b.mtx, NULL) == 0);
   assert(pthread_cond_init(&b.cond, NULL) == 0);
   b.n = n;
   b.count = 0;
}

// - function -----------------------------------------------------------------
void barrier(void)
{
   pthread_mutex_lock(&b.mtx);
   if (++b.count % b.n == 0) {
      pthread_cond_broadcast(&b.cond); // wake all threads
   } else {
      pthread_cond_wait(&b.cond, &b.mtx);
   }
   pthread_mutex_unlock(&b.mtx);
}

/* end of thread_barrier.c */
