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:
@@ -38,9 +38,6 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
#ifdef illumos
|
|
||||||
#include <synch.h>
|
|
||||||
#endif
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "barrier.h"
|
#include "barrier.h"
|
||||||
@@ -49,12 +46,7 @@ void
|
|||||||
barrier_init(barrier_t *bar, int nthreads)
|
barrier_init(barrier_t *bar, int nthreads)
|
||||||
{
|
{
|
||||||
pthread_mutex_init(&bar->bar_lock, NULL);
|
pthread_mutex_init(&bar->bar_lock, NULL);
|
||||||
#ifdef illumos
|
pthread_cond_init(&bar->bar_cv, NULL);
|
||||||
sema_init(&bar->bar_sem, 0, USYNC_THREAD, NULL);
|
|
||||||
#else
|
|
||||||
sem_init(&bar->bar_sem, 0, 0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
bar->bar_numin = 0;
|
bar->bar_numin = 0;
|
||||||
bar->bar_nthr = nthreads;
|
bar->bar_nthr = nthreads;
|
||||||
}
|
}
|
||||||
@@ -65,26 +57,14 @@ barrier_wait(barrier_t *bar)
|
|||||||
pthread_mutex_lock(&bar->bar_lock);
|
pthread_mutex_lock(&bar->bar_lock);
|
||||||
|
|
||||||
if (++bar->bar_numin < bar->bar_nthr) {
|
if (++bar->bar_numin < bar->bar_nthr) {
|
||||||
|
pthread_cond_wait(&bar->bar_cv, &bar->bar_lock);
|
||||||
pthread_mutex_unlock(&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);
|
return (0);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
int i;
|
|
||||||
|
|
||||||
/* reset for next use */
|
/* reset for next use */
|
||||||
bar->bar_numin = 0;
|
bar->bar_numin = 0;
|
||||||
for (i = 1; i < bar->bar_nthr; i++)
|
pthread_cond_broadcast(&bar->bar_cv);
|
||||||
#ifdef illumos
|
|
||||||
sema_post(&bar->bar_sem);
|
|
||||||
#else
|
|
||||||
sem_post(&bar->bar_sem);
|
|
||||||
#endif
|
|
||||||
pthread_mutex_unlock(&bar->bar_lock);
|
pthread_mutex_unlock(&bar->bar_lock);
|
||||||
|
|
||||||
return (1);
|
return (1);
|
||||||
|
|||||||
@@ -33,12 +33,7 @@
|
|||||||
* APIs for the barrier synchronization primitive.
|
* APIs for the barrier synchronization primitive.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifdef illumos
|
#include <pthread.h>
|
||||||
#include <synch.h>
|
|
||||||
#else
|
|
||||||
#include <semaphore.h>
|
|
||||||
typedef sem_t sema_t;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
@@ -48,7 +43,7 @@ typedef struct barrier {
|
|||||||
pthread_mutex_t bar_lock; /* protects bar_numin */
|
pthread_mutex_t bar_lock; /* protects bar_numin */
|
||||||
int bar_numin; /* current number of waiters */
|
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 */
|
int bar_nthr; /* # of waiters to trigger release */
|
||||||
} barrier_t;
|
} barrier_t;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user