Changeset View
Changeset View
Standalone View
Standalone View
head/lib/libthr/thread/thr_cond.c
Show First 20 Lines • Show All 43 Lines • ▼ Show 20 Lines | |||||
#include "thr_private.h" | #include "thr_private.h" | ||||
_Static_assert(sizeof(struct pthread_cond) <= PAGE_SIZE, | _Static_assert(sizeof(struct pthread_cond) <= PAGE_SIZE, | ||||
"pthread_cond too large"); | "pthread_cond too large"); | ||||
/* | /* | ||||
* Prototypes | * Prototypes | ||||
*/ | */ | ||||
int __pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex); | |||||
int __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, | int __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, | ||||
const struct timespec * abstime); | const struct timespec * abstime); | ||||
static int cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); | static int cond_init(pthread_cond_t *cond, const pthread_condattr_t *attr); | ||||
static int cond_wait_common(pthread_cond_t *cond, pthread_mutex_t *mutex, | static int cond_wait_common(pthread_cond_t *cond, pthread_mutex_t *mutex, | ||||
const struct timespec *abstime, int cancel); | const struct timespec *abstime, int cancel); | ||||
static int cond_signal_common(pthread_cond_t *cond); | static int cond_signal_common(pthread_cond_t *cond); | ||||
static int cond_broadcast_common(pthread_cond_t *cond); | static int cond_broadcast_common(pthread_cond_t *cond); | ||||
/* | /* | ||||
* Double underscore versions are cancellation points. Single underscore | * Double underscore versions are cancellation points. Single underscore | ||||
* versions are not and are provided for libc internal usage (which | * versions are not and are provided for libc internal usage (which | ||||
* shouldn't introduce cancellation points). | * shouldn't introduce cancellation points). | ||||
*/ | */ | ||||
__weak_reference(__pthread_cond_wait, pthread_cond_wait); | __weak_reference(__thr_cond_wait, pthread_cond_wait); | ||||
__weak_reference(__thr_cond_wait, __pthread_cond_wait); | |||||
__weak_reference(_thr_cond_wait, _pthread_cond_wait); | |||||
__weak_reference(__pthread_cond_timedwait, pthread_cond_timedwait); | __weak_reference(__pthread_cond_timedwait, pthread_cond_timedwait); | ||||
__weak_reference(_thr_cond_init, pthread_cond_init); | |||||
__weak_reference(_thr_cond_init, _pthread_cond_init); | |||||
__weak_reference(_thr_cond_destroy, pthread_cond_destroy); | |||||
__weak_reference(_thr_cond_destroy, _pthread_cond_destroy); | |||||
__weak_reference(_thr_cond_signal, pthread_cond_signal); | |||||
__weak_reference(_thr_cond_signal, _pthread_cond_signal); | |||||
__weak_reference(_thr_cond_broadcast, pthread_cond_broadcast); | |||||
__weak_reference(_thr_cond_broadcast, _pthread_cond_broadcast); | |||||
__weak_reference(_pthread_cond_init, pthread_cond_init); | |||||
__weak_reference(_pthread_cond_destroy, pthread_cond_destroy); | |||||
__weak_reference(_pthread_cond_signal, pthread_cond_signal); | |||||
__weak_reference(_pthread_cond_broadcast, pthread_cond_broadcast); | |||||
#define CV_PSHARED(cvp) (((cvp)->kcond.c_flags & USYNC_PROCESS_SHARED) != 0) | #define CV_PSHARED(cvp) (((cvp)->kcond.c_flags & USYNC_PROCESS_SHARED) != 0) | ||||
static void | static void | ||||
cond_init_body(struct pthread_cond *cvp, const struct pthread_cond_attr *cattr) | cond_init_body(struct pthread_cond *cvp, const struct pthread_cond_attr *cattr) | ||||
{ | { | ||||
if (cattr == NULL) { | if (cattr == NULL) { | ||||
cvp->kcond.c_clockid = CLOCK_REALTIME; | cvp->kcond.c_clockid = CLOCK_REALTIME; | ||||
▲ Show 20 Lines • Show All 62 Lines • ▼ Show 20 Lines | if (cvp == THR_COND_INITIALIZER) { \ | ||||
return (ret); \ | return (ret); \ | ||||
} else if (cvp == THR_COND_DESTROYED) { \ | } else if (cvp == THR_COND_DESTROYED) { \ | ||||
return (EINVAL); \ | return (EINVAL); \ | ||||
} \ | } \ | ||||
cvp = *cond; \ | cvp = *cond; \ | ||||
} | } | ||||
int | int | ||||
_pthread_cond_init(pthread_cond_t * __restrict cond, | _thr_cond_init(pthread_cond_t * __restrict cond, | ||||
const pthread_condattr_t * __restrict cond_attr) | const pthread_condattr_t * __restrict cond_attr) | ||||
{ | { | ||||
*cond = NULL; | *cond = NULL; | ||||
return (cond_init(cond, cond_attr)); | return (cond_init(cond, cond_attr)); | ||||
} | } | ||||
int | int | ||||
_pthread_cond_destroy(pthread_cond_t *cond) | _thr_cond_destroy(pthread_cond_t *cond) | ||||
{ | { | ||||
struct pthread_cond *cvp; | struct pthread_cond *cvp; | ||||
int error; | int error; | ||||
error = 0; | error = 0; | ||||
if (*cond == THR_PSHARED_PTR) { | if (*cond == THR_PSHARED_PTR) { | ||||
cvp = __thr_pshared_offpage(cond, 0); | cvp = __thr_pshared_offpage(cond, 0); | ||||
if (cvp != NULL) { | if (cvp != NULL) { | ||||
▲ Show 20 Lines • Show All 202 Lines • ▼ Show 20 Lines | if (curthread->attr.sched_policy != SCHED_OTHER || | ||||
(mp->m_lock.m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT | | (mp->m_lock.m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT | | ||||
USYNC_PROCESS_SHARED)) != 0 || CV_PSHARED(cvp)) | USYNC_PROCESS_SHARED)) != 0 || CV_PSHARED(cvp)) | ||||
return (cond_wait_kernel(cvp, mp, abstime, cancel)); | return (cond_wait_kernel(cvp, mp, abstime, cancel)); | ||||
else | else | ||||
return (cond_wait_user(cvp, mp, abstime, cancel)); | return (cond_wait_user(cvp, mp, abstime, cancel)); | ||||
} | } | ||||
int | int | ||||
_pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) | _thr_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) | ||||
{ | { | ||||
return (cond_wait_common(cond, mutex, NULL, 0)); | return (cond_wait_common(cond, mutex, NULL, 0)); | ||||
} | } | ||||
int | int | ||||
__pthread_cond_wait(pthread_cond_t * __restrict cond, | __thr_cond_wait(pthread_cond_t * __restrict cond, | ||||
pthread_mutex_t * __restrict mutex) | pthread_mutex_t * __restrict mutex) | ||||
{ | { | ||||
return (cond_wait_common(cond, mutex, NULL, 1)); | return (cond_wait_common(cond, mutex, NULL, 1)); | ||||
} | } | ||||
int | int | ||||
_pthread_cond_timedwait(pthread_cond_t * __restrict cond, | _thr_cond_timedwait(pthread_cond_t * __restrict cond, | ||||
pthread_mutex_t * __restrict mutex, | pthread_mutex_t * __restrict mutex, | ||||
const struct timespec * __restrict abstime) | const struct timespec * __restrict abstime) | ||||
{ | { | ||||
if (abstime == NULL || abstime->tv_sec < 0 || abstime->tv_nsec < 0 || | if (abstime == NULL || abstime->tv_sec < 0 || abstime->tv_nsec < 0 || | ||||
abstime->tv_nsec >= 1000000000) | abstime->tv_nsec >= 1000000000) | ||||
return (EINVAL); | return (EINVAL); | ||||
▲ Show 20 Lines • Show All 132 Lines • ▼ Show 20 Lines | cond_broadcast_common(pthread_cond_t *cond) | ||||
cvp->__has_user_waiters = 0; | cvp->__has_user_waiters = 0; | ||||
_sleepq_unlock(cvp); | _sleepq_unlock(cvp); | ||||
if (ba.count > 0) | if (ba.count > 0) | ||||
_thr_wake_all(ba.waddrs, ba.count); | _thr_wake_all(ba.waddrs, ba.count); | ||||
return (0); | return (0); | ||||
} | } | ||||
int | int | ||||
_pthread_cond_signal(pthread_cond_t * cond) | _thr_cond_signal(pthread_cond_t * cond) | ||||
{ | { | ||||
return (cond_signal_common(cond)); | return (cond_signal_common(cond)); | ||||
} | } | ||||
int | int | ||||
_pthread_cond_broadcast(pthread_cond_t * cond) | _thr_cond_broadcast(pthread_cond_t * cond) | ||||
{ | { | ||||
return (cond_broadcast_common(cond)); | return (cond_broadcast_common(cond)); | ||||
} | } |