1 /*------------------------------------------------------------------------- 2 * 3 * pthread_barrier_wait.c 4 * Implementation of pthread_barrier_t support for platforms lacking it. 5 * 6 * Portions Copyright (c) 1996-2021, PostgreSQL Global Development Group 7 * 8 * IDENTIFICATION 9 * src/port/pthread_barrier_wait.c 10 * 11 *------------------------------------------------------------------------- 12 */ 13 14 #include "c.h" 15 16 #include "port/pg_pthread.h" 17 18 int pthread_barrier_init(pthread_barrier_t * barrier,const void * attr,int count)19pthread_barrier_init(pthread_barrier_t *barrier, const void *attr, int count) 20 { 21 int error; 22 23 barrier->sense = false; 24 barrier->count = count; 25 barrier->arrived = 0; 26 if ((error = pthread_cond_init(&barrier->cond, NULL)) != 0) 27 return error; 28 if ((error = pthread_mutex_init(&barrier->mutex, NULL)) != 0) 29 { 30 pthread_cond_destroy(&barrier->cond); 31 return error; 32 } 33 34 return 0; 35 } 36 37 int pthread_barrier_wait(pthread_barrier_t * barrier)38pthread_barrier_wait(pthread_barrier_t *barrier) 39 { 40 bool initial_sense; 41 42 pthread_mutex_lock(&barrier->mutex); 43 44 /* We have arrived at the barrier. */ 45 barrier->arrived++; 46 Assert(barrier->arrived <= barrier->count); 47 48 /* If we were the last to arrive, release the others and return. */ 49 if (barrier->arrived == barrier->count) 50 { 51 barrier->arrived = 0; 52 barrier->sense = !barrier->sense; 53 pthread_mutex_unlock(&barrier->mutex); 54 pthread_cond_broadcast(&barrier->cond); 55 56 return PTHREAD_BARRIER_SERIAL_THREAD; 57 } 58 59 /* Wait for someone else to flip the sense. */ 60 initial_sense = barrier->sense; 61 do 62 { 63 pthread_cond_wait(&barrier->cond, &barrier->mutex); 64 } while (barrier->sense == initial_sense); 65 66 pthread_mutex_unlock(&barrier->mutex); 67 68 return 0; 69 } 70 71 int pthread_barrier_destroy(pthread_barrier_t * barrier)72pthread_barrier_destroy(pthread_barrier_t *barrier) 73 { 74 pthread_cond_destroy(&barrier->cond); 75 pthread_mutex_destroy(&barrier->mutex); 76 return 0; 77 } 78