on(cond, mutex, abstime, true)); + return (cond_wait_common(cond, mutex, 0, abstime, true, false)); +} + +int +__pthread_cond_clockwait(pthread_cond_t *cond, pthread_mutex_t *mutex, + clockid_t clockid, const struct timespec *abstime) +{ + + if (abstime == NULL || abstime->tv_sec < 0 || abstime->tv_nsec < 0 || + abstime->tv_nsec >= 1000000000) + return (EINVAL); + + return (cond_wait_common(cond, mutex, clockid, abstime, true, true)); } static int diff --git a/lib/libthr/thread/thr_umtx.c b/lib/libthr/thread/thr_umtx.c index db63017a6a13..edd0dacdaff1 100644 --- a/lib/libthr/thread/thr_umtx.c +++ b/lib/libthr/thread/thr_umtx.c @@ -28,6 +28,7 @@ #include "thr_private.h" #include "thr_umtx.h" +#include void _thr_umutex_init(struct umutex *mtx) @@ -242,20 +243,35 @@ _thr_ucond_init(struct ucond *cv) int _thr_ucond_wait(struct ucond *cv, struct umutex *m, - const struct timespec *timeout, int flags) + const struct timespec *timeout, const struct _umtx_time *utimep, int flags) { struct pthread *curthread; - - if (timeout != NULL && (timeout->tv_sec < 0 || (timeout->tv_sec == 0 && - timeout->tv_nsec <= 0))) { + const struct timespec *ts; + void *arg2; + + assert(timeout == NULL || utimep == NULL); + if (timeout != NULL) { + ts = timeout; + arg2 = __DECONST(void *, timeout); + assert((flags & CVWAIT_UMTX_TIME) == 0); + } else if (utimep != NULL) { + ts = &utimep->_timeout; + arg2 = __DECONST(void *, utimep); + assert((flags & CVWAIT_UMTX_TIME) != 0); + } else { + ts = NULL; + arg2 = NULL; + assert((flags & CVWAIT_UMTX_TIME) == 0); + } + if (ts != NULL && (ts->tv_sec < 0 || (ts->tv_sec == 0 && + ts->tv_nsec <= 0))) { curthread = _get_curthread(); _thr_umutex_unlock(m, TID(curthread)); return (ETIMEDOUT); } - return (_umtx_op_err(cv, UMTX_OP_CV_WAIT, flags, m, - __DECONST(void *, timeout))); + return (_umtx_op_err(cv, UMTX_OP_CV_WAIT, flags, m, arg2)); } - + int _thr_ucond_signal(struct ucond *cv) { diff --git a/lib/libthr/thread/thr_umtx.h b/lib/libthr/thread/thr_umtx.h index 89f70e4ab14f..4e1c08ca64e8 100644 --- a/lib/libthr/thread/thr_umtx.h +++ b/lib/libthr/thread/thr_umtx.h @@ -59,7 +59,8 @@ int _thr_umtx_timedwait_uint(volatile u_int *mtx, u_int exp, int clockid, const struct timespec *timeout, int shared) __hidden; int _thr_umtx_wake(volatile void *mtx, int count, int shared) __hidden; int _thr_ucond_wait(struct ucond *cv, struct umutex *m, - const struct timespec *timeout, int flags) __hidden; + const struct timespec *timeout, const struct _umtx_time *utimep, + int flags) __hidden; void _thr_ucond_init(struct ucond *cv) __hidden; int _thr_ucond_signal(struct ucond *cv) __hidden; int _thr_ucond_broadcast(struct ucond *cv) __hidden;