ctfmerge: fix segfault when building on macOS

The barrier code was using semaphores which have been deprecated in
macOS and not working at all, causing a race condition. Since macOS
does not have pthread_barrier_*(), this change uses a condition
variable instead.

PR:		290958
Reported by:	wosch
MFC after:	2 weeks
Reviewed by:	imp, markj
Differential Revision:	https://reviews.freebsd.org/D54018
This commit is contained in:
Mark Peek 2025-12-01 12:50:24 -08:00
parent 8d9a5d44b1
commit 732b4aa05d
2 changed files with 5 additions and 30 deletions

View file

@ -38,9 +38,6 @@
*/
#include <pthread.h>
#ifdef illumos
#include <synch.h>
#endif
#include <stdio.h>
#include "barrier.h"
@ -49,12 +46,7 @@ void
barrier_init(barrier_t *bar, int nthreads)
{
pthread_mutex_init(&bar->bar_lock, NULL);
#ifdef illumos
sema_init(&bar->bar_sem, 0, USYNC_THREAD, NULL);
#else
sem_init(&bar->bar_sem, 0, 0);
#endif
pthread_cond_init(&bar->bar_cv, NULL);
bar->bar_numin = 0;
bar->bar_nthr = nthreads;
}
@ -65,26 +57,14 @@ barrier_wait(barrier_t *bar)
pthread_mutex_lock(&bar->bar_lock);
if (++bar->bar_numin < bar->bar_nthr) {
pthread_cond_wait(&bar->bar_cv, &bar->bar_lock);
pthread_mutex_unlock(&bar->bar_lock);
#ifdef illumos
sema_wait(&bar->bar_sem);
#else
sem_wait(&bar->bar_sem);
#endif
return (0);
} else {
int i;
/* reset for next use */
bar->bar_numin = 0;
for (i = 1; i < bar->bar_nthr; i++)
#ifdef illumos
sema_post(&bar->bar_sem);
#else
sem_post(&bar->bar_sem);
#endif
pthread_cond_broadcast(&bar->bar_cv);
pthread_mutex_unlock(&bar->bar_lock);
return (1);

View file

@ -33,12 +33,7 @@
* APIs for the barrier synchronization primitive.
*/
#ifdef illumos
#include <synch.h>
#else
#include <semaphore.h>
typedef sem_t sema_t;
#endif
#include <pthread.h>
#ifdef __cplusplus
extern "C" {
@ -48,7 +43,7 @@ typedef struct barrier {
pthread_mutex_t bar_lock; /* protects bar_numin */
int bar_numin; /* current number of waiters */
sema_t bar_sem; /* where everyone waits */
pthread_cond_t bar_cv; /* where everyone waits */
int bar_nthr; /* # of waiters to trigger release */
} barrier_t;