Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Apr 2026 11:40:25 +0000
From:      Jean-=?utf-8?Q?S=C3=A9bast?==?utf-8?Q?ien P=C3=A9?=dron <dumbbell@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: eebb643bb379 - main - sx: Add `sx_has_waiters()` macro
Message-ID:  <69f33fa9.21e5b.687c9b6@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by dumbbell:

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

commit eebb643bb3799ae90dd248f0b5047ec481b26f68
Author:     Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
AuthorDate: 2026-04-12 17:20:25 +0000
Commit:     Jean-Sébastien Pédron <dumbbell@FreeBSD.org>
CommitDate: 2026-04-30 11:40:05 +0000

    sx: Add `sx_has_waiters()` macro
    
    This macro will return non-zero if there are threads waiting for this
    lock; otherwise, it will return zero.
    
    The function assumes (but does not assert) that the caller already holds
    the lock and that it is interested in other threads waiting for it to
    release the lock.
    
    The motivation to add this is the implementation of
    `rwsem_is_contended()` in linuxkpi.
    
    This Linux function indicates the same thing to the caller: if other
    threads are waiting for this semaphore.
    
    The amdgpu DRM driver started to use `rwsem_is_contended()` in Linux
    6.12.
    
    Reviewed by:    bz, olce
    Sponsored by:   The FreeBSD Foundation
    Differential Revision: https://reviews.freebsd.org/D56443
---
 share/man/man9/sx.9                              | 12 +++++++++++-
 sys/compat/linuxkpi/common/include/linux/rwsem.h |  1 +
 sys/sys/sx.h                                     |  4 ++++
 3 files changed, 16 insertions(+), 1 deletion(-)

diff --git a/share/man/man9/sx.9 b/share/man/man9/sx.9
index 473a47c27cf4..f96ee4ffccf7 100644
--- a/share/man/man9/sx.9
+++ b/share/man/man9/sx.9
@@ -24,7 +24,7 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
 .\" DAMAGE.
 .\"
-.Dd November 11, 2017
+.Dd Apri 30, 2026
 .Dt SX 9
 .Os
 .Sh NAME
@@ -46,6 +46,7 @@
 .Nm sx_sleep ,
 .Nm sx_xholder ,
 .Nm sx_xlocked ,
+.Nm sx_has_waiters ,
 .Nm sx_assert ,
 .Nm SX_SYSINIT ,
 .Nm SX_SYSINIT_FLAGS
@@ -88,6 +89,8 @@
 .Fn sx_xholder "struct sx *sx"
 .Ft int
 .Fn sx_xlocked "const struct sx *sx"
+.Ft int
+.Fn sx_has_waiters "const struct sx *sx"
 .Pp
 .Cd "options INVARIANTS"
 .Cd "options INVARIANT_SUPPORT"
@@ -268,6 +271,13 @@ is returned instead.
 will return non-zero if the current thread holds the exclusive lock;
 otherwise, it will return zero.
 .Pp
+.Fn sx_has_waiters
+will return non-zero if there are threads waiting for this lock;
+otherwise, it will return zero.
+The function assumes (but does not assert) that the caller already holds the
+lock and that it is interested in other threads waiting for it to release the
+lock.
+.Pp
 For ease of programming,
 .Fn sx_unlock
 is provided as a macro frontend to the respective functions,
diff --git a/sys/compat/linuxkpi/common/include/linux/rwsem.h b/sys/compat/linuxkpi/common/include/linux/rwsem.h
index b7a800b12e18..43688ab93796 100644
--- a/sys/compat/linuxkpi/common/include/linux/rwsem.h
+++ b/sys/compat/linuxkpi/common/include/linux/rwsem.h
@@ -51,6 +51,7 @@ struct rw_semaphore {
 #define	down_read_nested(_rw, _sc)	down_read(_rw)
 #define	init_rwsem(_rw)			linux_init_rwsem(_rw, rwsem_name("lnxrwsem"))
 #define	down_write_nest_lock(sem, _rw)	down_write(_rw)
+#define	rwsem_is_contended(_rw)		sx_has_waiters(&(_rw)->sx);
 
 #ifdef WITNESS_ALL
 /* NOTE: the maximum WITNESS name is 64 chars */
diff --git a/sys/sys/sx.h b/sys/sys/sx.h
index d28cae9d01e5..dab4fffb6f15 100644
--- a/sys/sys/sx.h
+++ b/sys/sys/sx.h
@@ -259,6 +259,10 @@ __sx_xunlock(struct sx *sx, struct thread *td, const char *file, int line)
 	(void)0; /* ensure void type for expression */			\
 })
 
+/* Return true if there are threads waiting to acquire this sx lock. */
+#define	sx_has_waiters(sx)						\
+	((SX_READ_VALUE(sx) & SX_LOCK_WAITERS) != 0)
+
 #define	sx_unlock(sx)	sx_unlock_((sx), LOCK_FILE, LOCK_LINE)
 
 #define	sx_sleep(chan, sx, pri, wmesg, timo)				\


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69f33fa9.21e5b.687c9b6>