Date: Mon, 27 Jul 2026 16:17:56 +0000 From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: e1136fbcab18 - main - libthr: implement pthread_cond_clockwait(3) Message-ID: <6a6784b4.1e302.52074cf8@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=e1136fbcab184b8fb87456ca0d115d502bab6643 commit e1136fbcab184b8fb87456ca0d115d502bab6643 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2026-07-25 23:45:11 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2026-07-27 16:17:28 +0000 libthr: implement pthread_cond_clockwait(3) Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D58463 --- include/pthread.h | 5 ++++ lib/libthr/pthread.map | 1 + lib/libthr/thread/thr_barrier.c | 6 ++-- lib/libthr/thread/thr_cond.c | 64 ++++++++++++++++++++++++++++++----------- lib/libthr/thread/thr_umtx.c | 30 ++++++++++++++----- lib/libthr/thread/thr_umtx.h | 3 +- 6 files changed, 83 insertions(+), 26 deletions(-) diff --git a/include/pthread.h b/include/pthread.h index 311211cb48f1..1686b54314ef 100644 --- a/include/pthread.h +++ b/include/pthread.h @@ -199,6 +199,11 @@ int pthread_condattr_init(pthread_condattr_t *); int pthread_condattr_setclock(pthread_condattr_t *, clockid_t); int pthread_condattr_setpshared(pthread_condattr_t *, int); int pthread_cond_broadcast(pthread_cond_t *); +#if __POSIX_VISIBLE >= 202405 +int pthread_cond_clockwait(pthread_cond_t * __restrict, + pthread_mutex_t * __restrict, clockid_t, + const struct timespec * __restrict); +#endif int pthread_cond_destroy(pthread_cond_t *); int pthread_cond_init(pthread_cond_t * __restrict, const pthread_condattr_t * __restrict); diff --git a/lib/libthr/pthread.map b/lib/libthr/pthread.map index ad0c28de98c1..4fe5f2c28331 100644 --- a/lib/libthr/pthread.map +++ b/lib/libthr/pthread.map @@ -344,5 +344,6 @@ FBSD_1.8 { }; FBSD_1.9 { + pthread_cond_clockwait; pthread_tryjoin_np; }; diff --git a/lib/libthr/thread/thr_barrier.c b/lib/libthr/thread/thr_barrier.c index 13dec864e2f6..e15b1627ee5d 100644 --- a/lib/libthr/thread/thr_barrier.c +++ b/lib/libthr/thread/thr_barrier.c @@ -76,7 +76,8 @@ _pthread_barrier_destroy(pthread_barrier_t *barrier) return (EBUSY); } if (bar->b_refcount != 0) { - _thr_ucond_wait(&bar->b_cv, &bar->b_lock, NULL, 0); + _thr_ucond_wait(&bar->b_cv, &bar->b_lock, NULL, + NULL, 0); THR_UMUTEX_LOCK(curthread, &bar->b_lock); } else break; @@ -158,7 +159,8 @@ _pthread_barrier_wait(pthread_barrier_t *barrier) cycle = bar->b_cycle; bar->b_refcount++; do { - _thr_ucond_wait(&bar->b_cv, &bar->b_lock, NULL, 0); + _thr_ucond_wait(&bar->b_cv, &bar->b_lock, NULL, + NULL, 0); THR_UMUTEX_LOCK(curthread, &bar->b_lock); /* test cycle to avoid bogus wakeup */ } while (cycle == bar->b_cycle); diff --git a/lib/libthr/thread/thr_cond.c b/lib/libthr/thread/thr_cond.c index f8c9118968bb..cce2ba7b6c3c 100644 --- a/lib/libthr/thread/thr_cond.c +++ b/lib/libthr/thread/thr_cond.c @@ -46,11 +46,14 @@ _Static_assert(sizeof(struct pthread_cond) <= THR_PAGE_SIZE_MIN, /* * Prototypes */ +int __pthread_cond_clockwait(pthread_cond_t *cond, pthread_mutex_t *mutex, + clockid_t clockid, const struct timespec *abstime); int __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec * abstime); 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, - const struct timespec *abstime, bool cancel); + clockid_t clockid, const struct timespec *abstime, bool cancel, + bool clockwait); static int cond_signal_common(pthread_cond_t *cond); static int cond_broadcast_common(pthread_cond_t *cond); @@ -64,6 +67,7 @@ __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(_thr_cond_timedwait, _pthread_cond_timedwait); +__weak_reference(__pthread_cond_clockwait, pthread_cond_clockwait); __weak_reference(_thr_cond_init, pthread_cond_init); __weak_reference(_thr_cond_init, _pthread_cond_init); __weak_reference(_thr_cond_destroy, pthread_cond_destroy); @@ -202,9 +206,11 @@ _thr_cond_destroy(pthread_cond_t *cond) */ static int cond_wait_kernel(struct pthread_cond *cvp, struct pthread_mutex *mp, - const struct timespec *abstime, bool cancel) + clockid_t clockid, const struct timespec *abstime, bool cancel, + bool clockwait) { struct pthread *curthread; + struct _umtx_time utime; int error, error2, recurse, robust; curthread = _get_curthread(); @@ -219,8 +225,16 @@ cond_wait_kernel(struct pthread_cond *cvp, struct pthread_mutex *mp, if (cancel) _thr_cancel_enter2(curthread, 0); - error = _thr_ucond_wait(&cvp->kcond, &mp->m_lock, abstime, - CVWAIT_ABSTIME | CVWAIT_CLOCKID); + if (clockwait) { + utime._timeout = *abstime; + utime._flags = UMTX_ABSTIME; + utime._clockid = clockid; + error = _thr_ucond_wait(&cvp->kcond, &mp->m_lock, NULL, + &utime, CVWAIT_UMTX_TIME); + } else { + error = _thr_ucond_wait(&cvp->kcond, &mp->m_lock, abstime, + NULL, CVWAIT_ABSTIME | CVWAIT_CLOCKID); + } if (cancel) _thr_cancel_leave(curthread, 0); @@ -274,7 +288,7 @@ cond_wait_kernel(struct pthread_cond *cvp, struct pthread_mutex *mp, static int cond_wait_user(struct pthread_cond *cvp, struct pthread_mutex *mp, - const struct timespec *abstime, bool cancel) + clockid_t clockid, const struct timespec *abstime, bool cancel) { struct pthread *curthread; struct sleepqueue *sq; @@ -315,7 +329,7 @@ cond_wait_user(struct pthread_cond *cvp, struct pthread_mutex *mp, if (cancel) _thr_cancel_enter2(curthread, 0); - error = _thr_sleep(curthread, cvp->kcond.c_clockid, abstime); + error = _thr_sleep(curthread, clockid, abstime); if (cancel) _thr_cancel_leave(curthread, 0); @@ -350,7 +364,8 @@ cond_wait_user(struct pthread_cond *cvp, struct pthread_mutex *mp, static int cond_wait_common(pthread_cond_t *cond, pthread_mutex_t *mutex, - const struct timespec *abstime, bool cancel) + clockid_t clockid, const struct timespec *abstime, bool cancel, + bool clockwait) { struct pthread *curthread = _get_curthread(); struct pthread_cond *cvp; @@ -359,6 +374,9 @@ cond_wait_common(pthread_cond_t *cond, pthread_mutex_t *mutex, CHECK_AND_INIT_COND + if (!clockwait) + clockid = cvp->kcond.c_clockid; + if (*mutex == THR_PSHARED_PTR) { mp = __thr_pshared_offpage(mutex, 0); if (mp == NULL) @@ -372,23 +390,25 @@ cond_wait_common(pthread_cond_t *cond, pthread_mutex_t *mutex, if (curthread->attr.sched_policy != SCHED_OTHER || (mp->m_lock.m_flags & (UMUTEX_PRIO_PROTECT | UMUTEX_PRIO_INHERIT | - USYNC_PROCESS_SHARED)) != 0 || CV_PSHARED(cvp)) - return (cond_wait_kernel(cvp, mp, abstime, cancel)); - else - return (cond_wait_user(cvp, mp, abstime, cancel)); + USYNC_PROCESS_SHARED)) != 0 || CV_PSHARED(cvp)) { + return (cond_wait_kernel(cvp, mp, clockid, abstime, cancel, + clockwait)); + } else { + return (cond_wait_user(cvp, mp, clockid, abstime, cancel)); + } } int _thr_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) { - return (cond_wait_common(cond, mutex, NULL, false)); + return (cond_wait_common(cond, mutex, 0, NULL, false, false)); } int __thr_cond_wait(pthread_cond_t * __restrict cond, pthread_mutex_t * __restrict mutex) { - return (cond_wait_common(cond, mutex, NULL, true)); + return (cond_wait_common(cond, mutex, 0, NULL, true, false)); } int @@ -400,18 +420,30 @@ _thr_cond_timedwait(pthread_cond_t * __restrict cond, abstime->tv_nsec >= 1000000000) return (EINVAL); - return (cond_wait_common(cond, mutex, abstime, false)); + return (cond_wait_common(cond, mutex, 0, abstime, false, false)); } int __pthread_cond_timedwait(pthread_cond_t *cond, pthread_mutex_t *mutex, - const struct timespec *abstime) + 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, 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 <assert.h> 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;home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a6784b4.1e302.52074cf8>
