aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJean-Sébastien Pédron <dumbbell@FreeBSD.org>2026-04-12 17:20:25 +0000
committerJean-Sébastien Pédron <dumbbell@FreeBSD.org>2026-04-30 11:40:05 +0000
commiteebb643bb3799ae90dd248f0b5047ec481b26f68 (patch)
tree815469571fd48c901f5e0533cafea084286ac88c
parent65dc0e9071a5ea206d6fbf070c974ebcfdea3680 (diff)
-rw-r--r--share/man/man9/sx.912
-rw-r--r--sys/compat/linuxkpi/common/include/linux/rwsem.h1
-rw-r--r--sys/sys/sx.h4
3 files changed, 16 insertions, 1 deletions
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) \