From nobody Mon Jul 27 16:17:56 2026 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4h83fY5N23z6nBsq for ; Mon, 27 Jul 2026 16:17:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "YR1" (not verified)) by mx1.freebsd.org (Postfix) with ESMTPS id 4h83fY0W6Pz43Dw for ; Mon, 27 Jul 2026 16:17:57 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785169077; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=6AAZg87DhHvPMX3yB50FOnRqIY77CiuSERSuFI0/MHw=; b=pHhg4Itfgo5UjQLg9uEiEp+/SPwvg9AqE3AICWuEgAnp/ckvMHTIgpNpShcOxRMJ5HvLTC EtO1S7IxHkyms1cpJfx3J6yF3sl2TleYH8YFCuJ5Hni+ZEMXzJ51wEQw4MFNjT2LCkSBs1 u6j2EYPa+4ipkwxyzXtxLEO+QS3OAyPJmP7vFCsZewjX9EMLosHQDgB8wziFlQ76pMQl/S vpf4oD3IAnn0X4Uf9WquUylg8QMnrJD9yAlakiWD4lYDeC0RfWgt7XHQl6iBOCkXfAzFzG XltU3RvbhUj9df2PrS+aj8m5f00ARq7hJkUHF8tYx8Va0w9rNyrYGVplT1xVyw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1785169077; a=rsa-sha256; cv=none; b=TzNGTHECYt7sjk6j0ijFd78ALrfczqaIr5k41cdrY7uXM2fVBdbIiBRSx/q8jnLdQCtUVA yTLyYBqfpy44IZK9DMYNACP18k76GpIR+Lo9urPoCzYchyG0gkiOK5wYIFhpFMxofXree3 o+MtnbHggOZD5bQq2Q+12uKTVm58CqOkKJvRvjCclu3gNOnUHsP7kjvXqLYscnZAxaju+F xPkdMDimG2qkkRXGZNESWIcL4uyHC/4ijFpzYIdJKEtIi0xaPLYwYHsHyyYur27QHQv+Bs YE7YGf1/Won78B8TaN9UeOnPeaD9gi/PQYQEx0uQfVjKyHR03fVsDv/gc9K7Tg== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1785169077; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=6AAZg87DhHvPMX3yB50FOnRqIY77CiuSERSuFI0/MHw=; b=pu6jk1049JlF0zEgob37vRB4tPsQ6LROlVamHRuM0B7uf+8FX2zNYlF9HcZC+ac83GUOhk ePOxUSR0oF1CuSEVWZgbh9vJl+4SmY60KsacReolN2HoTTx57GG7JrDp1qpvfnrqk98Lcf 7/OsC9M6fpUPAC06VjagOiBQSbv+7dc8kGXDnSG8jnHitgocW4bSYlXj6sA/wdtK9zqcGR hvwSMzhWZ1mWob+1FDEAcKkrKhBht9gksQPbpnpQxH4tq6hSqBpRc3BfrixP1VkM6UzJDO Y/6LBj+3/HbcpLtFpLSrza695rJ9ygo/15OLh3Pr6tGPn3OQb3sKL0JnPG2YuQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) by mxrelay.nyi.freebsd.org (Postfix) with ESMTP id 4h83fX6BNhz1FhT for ; Mon, 27 Jul 2026 16:17:56 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from git (uid 1279) (envelope-from git@FreeBSD.org) id 1e302 by gitrepo.freebsd.org (DragonFly Mail Agent v0.13+ on gitrepo.freebsd.org); Mon, 27 Jul 2026 16:17:56 +0000 To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Konstantin Belousov Subject: git: e1136fbcab18 - main - libthr: implement pthread_cond_clockwait(3) List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-all@freebsd.org Sender: owner-dev-commits-src-all@FreeBSD.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: e1136fbcab184b8fb87456ca0d115d502bab6643 Auto-Submitted: auto-generated Date: Mon, 27 Jul 2026 16:17:56 +0000 Message-Id: <6a6784b4.1e302.52074cf8@gitrepo.freebsd.org> The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=e1136fbcab184b8fb87456ca0d115d502bab6643 commit e1136fbcab184b8fb87456ca0d115d502bab6643 Author: Konstantin Belousov AuthorDate: 2026-07-25 23:45:11 +0000 Commit: Konstantin Belousov 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 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;