svn commit: r233022 - head/lib/libthr/thread
David Xu
davidxu at FreeBSD.org
Fri Mar 16 04:35:53 UTC 2012
Author: davidxu
Date: Fri Mar 16 04:35:52 2012
New Revision: 233022
URL: http://svn.freebsd.org/changeset/base/233022
Log:
When destroying a barrier, waiting all threads exit the barrier,
this makes it possible a thread received PTHREAD_BARRIER_SERIAL_THREAD
immediately free memory area of the barrier.
Modified:
head/lib/libthr/thread/thr_barrier.c
head/lib/libthr/thread/thr_private.h
Modified: head/lib/libthr/thread/thr_barrier.c
==============================================================================
--- head/lib/libthr/thread/thr_barrier.c Fri Mar 16 03:22:37 2012 (r233021)
+++ head/lib/libthr/thread/thr_barrier.c Fri Mar 16 04:35:52 2012 (r233022)
@@ -42,13 +42,34 @@ int
_pthread_barrier_destroy(pthread_barrier_t *barrier)
{
pthread_barrier_t bar;
+ struct pthread *curthread;
if (barrier == NULL || *barrier == NULL)
return (EINVAL);
+ curthread = _get_curthread();
bar = *barrier;
- if (bar->b_waiters > 0)
+ THR_UMUTEX_LOCK(curthread, &bar->b_lock);
+ if (bar->b_destroying) {
+ THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
return (EBUSY);
+ }
+ bar->b_destroying = 1;
+ do {
+ if (bar->b_waiters > 0) {
+ bar->b_destroying = 0;
+ THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
+ return (EBUSY);
+ }
+ if (bar->b_refcount != 0) {
+ _thr_ucond_wait(&bar->b_cv, &bar->b_lock, NULL, 0);
+ THR_UMUTEX_LOCK(curthread, &bar->b_lock);
+ } else
+ break;
+ } while (1);
+ bar->b_destroying = 0;
+ THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
+
*barrier = NULL;
free(bar);
return (0);
@@ -74,6 +95,7 @@ _pthread_barrier_init(pthread_barrier_t
bar->b_cycle = 0;
bar->b_waiters = 0;
bar->b_count = count;
+ bar->b_refcount = 0;
*barrier = bar;
return (0);
@@ -101,11 +123,14 @@ _pthread_barrier_wait(pthread_barrier_t
ret = PTHREAD_BARRIER_SERIAL_THREAD;
} else {
cycle = bar->b_cycle;
+ bar->b_refcount++;
do {
_thr_ucond_wait(&bar->b_cv, &bar->b_lock, NULL, 0);
THR_UMUTEX_LOCK(curthread, &bar->b_lock);
/* test cycle to avoid bogus wakeup */
} while (cycle == bar->b_cycle);
+ if (--bar->b_refcount == 0 && bar->b_destroying)
+ _thr_ucond_broadcast(&bar->b_cv);
THR_UMUTEX_UNLOCK(curthread, &bar->b_lock);
ret = 0;
}
Modified: head/lib/libthr/thread/thr_private.h
==============================================================================
--- head/lib/libthr/thread/thr_private.h Fri Mar 16 03:22:37 2012 (r233021)
+++ head/lib/libthr/thread/thr_private.h Fri Mar 16 04:35:52 2012 (r233022)
@@ -182,9 +182,11 @@ struct pthread_cond_attr {
struct pthread_barrier {
struct umutex b_lock;
struct ucond b_cv;
- volatile int64_t b_cycle;
- volatile int b_count;
- volatile int b_waiters;
+ int64_t b_cycle;
+ int b_count;
+ int b_waiters;
+ int b_refcount;
+ int b_destroying;
};
struct pthread_barrierattr {
More information about the svn-src-all
mailing list