Skip site navigation (1)Skip section navigation (2)
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		0x01
 


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a6784b0.1be71.61251996>