Date: Mon, 27 Jul 2026 16:17:52 +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: d738f66fab92 - main - umtx_op(2): add the CVWAIT_UMTX_TIME flag for the UMTX_OP_CV_WAIT_UC request Message-ID: <6a6784b0.1be71.61251996@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=d738f66fab9208ee3bccea5fed293d8ce3ee5ca3 commit d738f66fab9208ee3bccea5fed293d8ce3ee5ca3 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2026-07-25 22:30:37 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2026-07-27 16:17:28 +0000 umtx_op(2): add the CVWAIT_UMTX_TIME flag for the UMTX_OP_CV_WAIT_UC request Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D58463 --- sys/kern/kern_umtx.c | 90 ++++++++++++++++++++++++++++++++-------------------- sys/sys/umtx.h | 1 + 2 files changed, 56 insertions(+), 35 deletions(-) diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c index d9798fb2adb6..ab6e578ab380 100644 --- a/sys/kern/kern_umtx.c +++ b/sys/kern/kern_umtx.c @@ -2934,11 +2934,10 @@ do_unlock_umutex(struct thread *td, struct umutex *m, bool rb) static int do_cv_wait(struct thread *td, struct ucond *cv, struct umutex *m, - struct timespec *timeout, u_long wflags) + struct umtx_abs_timeout *timo, u_long wflags) { - struct umtx_abs_timeout timo; struct umtx_q *uq; - uint32_t flags, clockid, hasw; + uint32_t flags, hasw; int error; uq = td->td_umtxq; @@ -2949,23 +2948,6 @@ do_cv_wait(struct thread *td, struct ucond *cv, struct umutex *m, if (error != 0) return (error); - if ((wflags & CVWAIT_CLOCKID) != 0) { - error = fueword32(&cv->c_clockid, &clockid); - if (error == -1) { - umtx_key_release(&uq->uq_key); - return (EFAULT); - } - if ((clockid < CLOCK_REALTIME || - clockid >= CLOCK_THREAD_CPUTIME_ID) && - clockid != CLOCK_TAI) { - /* hmm, only HW clock id will work. */ - umtx_key_release(&uq->uq_key); - return (EINVAL); - } - } else { - clockid = CLOCK_REALTIME; - } - umtxq_lock(&uq->uq_key); umtxq_busy(&uq->uq_key); umtxq_insert(uq); @@ -2990,15 +2972,9 @@ do_cv_wait(struct thread *td, struct ucond *cv, struct umutex *m, error = do_unlock_umutex(td, m, false); - if (timeout != NULL) - umtx_abs_timeout_init(&timo, clockid, - (wflags & CVWAIT_ABSTIME) != 0, timeout); - umtxq_lock(&uq->uq_key); - if (error == 0) { - error = umtxq_sleep(uq, "ucond", timeout == NULL ? - NULL : &timo); - } + if (error == 0) + error = umtxq_sleep(uq, "ucond", timo); if ((uq->uq_flags & UQF_UMTXQ) == 0) error = 0; @@ -4138,19 +4114,63 @@ static int __umtx_op_cv_wait(struct thread *td, struct _umtx_op_args *uap, const struct umtx_copyops *ops) { + struct umtx_abs_timeout *timop, timo; struct timespec *ts, timeout; + struct _umtx_time umtime; + struct ucond *cv; + u_long wflags; + uint32_t clockid; int error; - /* Allow a null timespec (wait forever). */ - if (uap->uaddr2 == NULL) - ts = NULL; - else { - error = ops->copyin_timeout(uap->uaddr2, &timeout); + cv = uap->obj; + wflags = uap->val; + if ((wflags & ~(CVWAIT_CHECK_UNPARKING | CVWAIT_ABSTIME | + CVWAIT_CLOCKID | CVWAIT_UMTX_TIME)) != 0 || + ((wflags & (CVWAIT_ABSTIME | CVWAIT_CLOCKID)) != 0 && + (wflags & CVWAIT_UMTX_TIME) != 0)) + return (EINVAL); + + if ((wflags & CVWAIT_UMTX_TIME) == 0) { + /* Allow a null timespec (wait forever). */ + if (uap->uaddr2 == NULL) { + ts = NULL; + } else { + error = ops->copyin_timeout(uap->uaddr2, &timeout); + if (error != 0) + return (error); + ts = &timeout; + } + if ((wflags & CVWAIT_CLOCKID) != 0) { + error = fueword32(&cv->c_clockid, &clockid); + if (error == -1) + return (EFAULT); + } else { + clockid = CLOCK_REALTIME; + } + if (ts != NULL) { + umtx_abs_timeout_init(&timo, clockid, + (wflags & CVWAIT_ABSTIME) != 0, ts); + timop = &timo; + } else { + timop = NULL; + } + } else { + if (uap->uaddr2 == NULL) + return (EINVAL); + error = ops->copyin_umtx_time(uap->uaddr2, ops->umtx_time_sz, + &umtime); if (error != 0) return (error); - ts = &timeout; + timop = &timo; + umtx_abs_timeout_init2(timop, &umtime); } - return (do_cv_wait(td, uap->obj, uap->uaddr1, ts, uap->val)); + /* only HW clock id will work. */ + if (timop != NULL && (timop->clockid < CLOCK_REALTIME || + timop->clockid >= CLOCK_THREAD_CPUTIME_ID) && + timop->clockid != CLOCK_TAI) + return (EINVAL); + + return (do_cv_wait(td, cv, uap->uaddr1, timop, wflags)); } static int diff --git a/sys/sys/umtx.h b/sys/sys/umtx.h index f7a69ae772c3..1cd9e2070977 100644 --- a/sys/sys/umtx.h +++ b/sys/sys/umtx.h @@ -115,6 +115,7 @@ #define CVWAIT_CHECK_UNPARKING 0x01 #define CVWAIT_ABSTIME 0x02 #define CVWAIT_CLOCKID 0x04 +#define CVWAIT_UMTX_TIME 0x08 #define UMTX_ABSTIME 0x01home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a6784b0.1be71.61251996>
