2011-02-12 00:22:29 -05:00
|
|
|
#include "pthread_impl.h"
|
|
|
|
|
|
|
|
int pthread_cond_broadcast(pthread_cond_t *c)
|
|
|
|
{
|
2011-09-25 02:38:03 -04:00
|
|
|
pthread_mutex_t *m;
|
|
|
|
|
|
|
|
if (!c->_c_waiters) return 0;
|
|
|
|
|
2011-09-26 00:25:13 -04:00
|
|
|
a_inc(&c->_c_seq);
|
2011-09-25 02:38:03 -04:00
|
|
|
|
2011-09-26 00:25:13 -04:00
|
|
|
/* If cond var is process-shared, simply wake all waiters. */
|
|
|
|
if (c->_c_mutex == (void *)-1) {
|
|
|
|
__wake(&c->_c_seq, -1, 0);
|
2011-09-25 02:38:03 -04:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2011-09-26 00:25:13 -04:00
|
|
|
/* Block waiters from returning so we can use the mutex. */
|
|
|
|
while (a_swap(&c->_c_lock, 1))
|
|
|
|
__wait(&c->_c_lock, &c->_c_lockwait, 1, 1);
|
|
|
|
if (!c->_c_waiters)
|
|
|
|
goto out;
|
|
|
|
m = c->_c_mutex;
|
|
|
|
|
2011-09-25 02:38:03 -04:00
|
|
|
/* Move waiter count to the mutex */
|
2011-09-26 00:25:13 -04:00
|
|
|
a_fetch_add(&m->_m_waiters, c->_c_waiters);
|
|
|
|
a_store(&c->_c_waiters, 0);
|
2011-09-25 02:38:03 -04:00
|
|
|
|
2011-09-25 02:56:01 -04:00
|
|
|
/* Perform the futex requeue, waking one waiter unless we know
|
|
|
|
* that the calling thread holds the mutex. */
|
2011-09-26 00:25:13 -04:00
|
|
|
__syscall(SYS_futex, &c->_c_seq, FUTEX_REQUEUE,
|
2011-09-25 02:56:01 -04:00
|
|
|
!m->_m_type || (m->_m_lock&INT_MAX)!=pthread_self()->tid,
|
|
|
|
INT_MAX, &m->_m_lock);
|
2011-09-25 02:38:03 -04:00
|
|
|
|
2011-09-26 00:25:13 -04:00
|
|
|
out:
|
|
|
|
a_store(&c->_c_lock, 0);
|
|
|
|
if (c->_c_lockwait) __wake(&c->_c_lock, 1, 0);
|
|
|
|
|
2011-02-12 00:22:29 -05:00
|
|
|
return 0;
|
|
|
|
}
|