Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 17 Jun 2022 19:37:24 GMT
From:      Dmitry Chagin <dchagin@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org
Subject:   git: 6d6fb6026d5f - stable/13 - umtx: Add bitset conditional wakeup functionality.
Message-ID:  <202206171937.25HJbO6X013310@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch stable/13 has been updated by dchagin:

URL: https://cgit.FreeBSD.org/src/commit/?id=6d6fb6026d5f49c509531e926c328e83a8b8ae1f

commit 6d6fb6026d5f49c509531e926c328e83a8b8ae1f
Author:     Dmitry Chagin <dchagin@FreeBSD.org>
AuthorDate: 2021-07-29 09:42:49 +0000
Commit:     Dmitry Chagin <dchagin@FreeBSD.org>
CommitDate: 2022-06-17 19:33:17 +0000

    umtx: Add bitset conditional wakeup functionality.
    
    The bitset is a Linux emulation layer extension. This 32-bit mask, in which at
    least one bit must be set, is used to select which threads should be woken up.
    
    The bitset is stored in the umtx_q structure, which is used to enqueue the waiter
    into the umtx waitqueue. Put the bitset into the hole, that appeared on LP64 due
    to data alignment, to prevent the growth of the struct umtx_q.
    
    Reviewed by:            kib
    Differential Revision:  https://reviews.freebsd.org/D31234
    MFC after:              2 weeks
    
    (cherry picked from commit 7caa29115b4a2023128ed07942b71074507a44a1)
---
 sys/kern/kern_umtx.c | 26 ++++++++++++++++++++++++++
 sys/sys/umtxvar.h    |  4 ++++
 2 files changed, 30 insertions(+)

diff --git a/sys/kern/kern_umtx.c b/sys/kern/kern_umtx.c
index ebe52aa206ec..256c7e048ba5 100644
--- a/sys/kern/kern_umtx.c
+++ b/sys/kern/kern_umtx.c
@@ -558,6 +558,32 @@ umtxq_count_pi(struct umtx_key *key, struct umtx_q **first)
 	return (0);
 }
 
+/*
+ * Wake up threads waiting on an userland object by a bit mask.
+ */
+int
+umtxq_signal_mask(struct umtx_key *key, int n_wake, u_int bitset)
+{
+	struct umtxq_queue *uh;
+	struct umtx_q *uq, *uq_temp;
+	int ret;
+
+	ret = 0;
+	UMTXQ_LOCKED_ASSERT(umtxq_getchain(key));
+	uh = umtxq_queue_lookup(key, UMTX_SHARED_QUEUE);
+	if (uh == NULL)
+		return (0);
+	TAILQ_FOREACH_SAFE(uq, &uh->head, uq_link, uq_temp) {
+		if ((uq->uq_bitset & bitset) == 0)
+			continue;
+		umtxq_remove_queue(uq, UMTX_SHARED_QUEUE);
+		wakeup_one(uq);
+		if (++ret >= n_wake)
+			break;
+	}
+	return (ret);
+}
+
 /*
  * Wake up threads waiting on an userland object.
  */
diff --git a/sys/sys/umtxvar.h b/sys/sys/umtxvar.h
index 68f261fe6abf..de1b649ed8d7 100644
--- a/sys/sys/umtxvar.h
+++ b/sys/sys/umtxvar.h
@@ -120,6 +120,9 @@ struct umtx_q {
 	int			uq_flags;
 #define UQF_UMTXQ	0x0001
 
+	/* Futex bitset mask */
+	u_int			uq_bitset;
+
 	/* The thread waits on. */
 	struct thread		*uq_thread;
 
@@ -207,6 +210,7 @@ void umtxq_free(struct umtx_q *);
 struct umtxq_chain *umtxq_getchain(struct umtx_key *);
 void umtxq_insert_queue(struct umtx_q *, int);
 void umtxq_remove_queue(struct umtx_q *, int);
+int umtxq_signal_mask(struct umtx_key *, int, u_int);
 int umtxq_sleep(struct umtx_q *, const char *,
     struct umtx_abs_timeout *);
 void umtxq_unbusy(struct umtx_key *);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202206171937.25HJbO6X013310>