summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authortedu <tedu@openbsd.org>2016-04-15 17:54:17 +0000
committertedu <tedu@openbsd.org>2016-04-15 17:54:17 +0000
commit7446b51cb8845fe4e5a4767f1a4e046d29890fef (patch)
treee41f368df80f9499a12ad2204c4620b40c090cf6 /lib
parentprefer warn[x](3) over fprintf(3) where appropriate (diff)
downloadwireguard-openbsd-7446b51cb8845fe4e5a4767f1a4e046d29890fef.tar.xz
wireguard-openbsd-7446b51cb8845fe4e5a4767f1a4e046d29890fef.zip
make pthread_barrier_wait behave more like it does on other platforms.
from Kari Tristan Helgason
Diffstat (limited to 'lib')
-rw-r--r--lib/librthread/pthread.h4
-rw-r--r--lib/librthread/rthread.h5
-rw-r--r--lib/librthread/rthread_barrier.c23
3 files changed, 22 insertions, 10 deletions
diff --git a/lib/librthread/pthread.h b/lib/librthread/pthread.h
index 539f4ad82aa..2510c34789a 100644
--- a/lib/librthread/pthread.h
+++ b/lib/librthread/pthread.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pthread.h,v 1.1 2016/04/02 19:56:53 guenther Exp $ */
+/* $OpenBSD: pthread.h,v 1.2 2016/04/15 17:54:17 tedu Exp $ */
/*
* Copyright (c) 2016 Philip Guenther <guenther@openbsd.org>
*
@@ -51,7 +51,7 @@ PROTO_STD_DEPRECATED(pthread_cleanup_push);
PROTO_NORMAL(pthread_cond_broadcast);
PROTO_NORMAL(pthread_cond_destroy);
PROTO_NORMAL(pthread_cond_init);
-PROTO_STD_DEPRECATED(pthread_cond_signal);
+PROTO_NORMAL(pthread_cond_signal);
PROTO_STD_DEPRECATED(pthread_cond_timedwait);
PROTO_NORMAL(pthread_cond_wait);
PROTO_STD_DEPRECATED(pthread_condattr_destroy);
diff --git a/lib/librthread/rthread.h b/lib/librthread/rthread.h
index 284356fb857..6ef9a8c9733 100644
--- a/lib/librthread/rthread.h
+++ b/lib/librthread/rthread.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread.h,v 1.56 2016/04/02 19:00:51 guenther Exp $ */
+/* $OpenBSD: rthread.h,v 1.57 2016/04/15 17:54:17 tedu Exp $ */
/*
* Copyright (c) 2004,2005 Ted Unangst <tedu@openbsd.org>
* All Rights Reserved.
@@ -141,7 +141,8 @@ struct pthread_barrier {
pthread_mutex_t mutex;
pthread_cond_t cond;
int threshold;
- int sofar;
+ int in;
+ int out;
int generation;
};
diff --git a/lib/librthread/rthread_barrier.c b/lib/librthread/rthread_barrier.c
index 9643cb893b3..7ecdb1f4298 100644
--- a/lib/librthread/rthread_barrier.c
+++ b/lib/librthread/rthread_barrier.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: rthread_barrier.c,v 1.2 2012/04/23 08:30:33 pirofti Exp $ */
+/* $OpenBSD: rthread_barrier.c,v 1.3 2016/04/15 17:54:17 tedu Exp $ */
/*
* Copyright (c) 2012 Paul Irofti <pirofti@openbsd.org>
*
@@ -69,17 +69,24 @@ err:
int
pthread_barrier_destroy(pthread_barrier_t *barrier)
{
+ int rc;
pthread_barrier_t b;
if (barrier == NULL || *barrier == NULL)
return (EINVAL);
+ if ((rc = pthread_mutex_lock(&(*barrier)->mutex)))
+ return (rc);
+
b = *barrier;
- if (b->sofar > 0)
+ if (b->out > 0 || b->in > 0) {
+ pthread_mutex_unlock(&b->mutex);
return (EBUSY);
+ }
*barrier = NULL;
+ pthread_mutex_unlock(&b->mutex);
pthread_mutex_destroy(&b->mutex);
pthread_cond_destroy(&b->cond);
free(b);
@@ -103,11 +110,12 @@ pthread_barrier_wait(pthread_barrier_t *barrier)
if ((rc = pthread_mutex_lock(&b->mutex)))
goto cancel;
- _rthread_debug(6, "sofar: %d, threshold: %d\n", b->sofar, b->threshold);
- if (++b->sofar == b->threshold) {
- b->sofar = 0;
+ _rthread_debug(6, "in: %d, threshold: %d\n", b->in, b->threshold);
+ if (++b->in == b->threshold) {
+ b->out = b->in - 1;
+ b->in = 0;
b->generation++;
- if ((rc = pthread_cond_broadcast(&b->cond)))
+ if ((rc = pthread_cond_signal(&b->cond)))
goto err;
done = 1;
_rthread_debug(6, "threshold reached\n");
@@ -118,6 +126,9 @@ pthread_barrier_wait(pthread_barrier_t *barrier)
if ((rc = pthread_cond_wait(&b->cond, &b->mutex)))
goto err;
} while (gen == b->generation);
+ b->out--; /* mark thread exit */
+ if ((rc = pthread_cond_signal(&b->cond)))
+ goto err;
}
err: