Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages


home | help
SX(9)		       FreeBSD Kernel Developer's Manual		 SX(9)

     sx, sx_init, sx_init_flags, sx_destroy, sx_slock, sx_xlock, sx_slock_sig,
     sx_xlock_sig, sx_try_slock, sx_try_xlock, sx_sunlock, sx_xunlock,
     sx_unlock,	sx_try_upgrade,	sx_downgrade, sx_sleep,	sx_xholder,
     sx_xlocked, sx_assert, SX_SYSINIT,	SX_SYSINIT_FLAGS -- kernel shared/ex-
     clusive lock

     #include <sys/param.h>
     #include <sys/lock.h>
     #include <sys/sx.h>

     sx_init(struct sx *sx, const char *description);

     sx_init_flags(struct sx *sx, const	char *description, int opts);

     sx_destroy(struct sx *sx);

     sx_slock(struct sx	*sx);

     sx_xlock(struct sx	*sx);

     sx_slock_sig(struct sx *sx);

     sx_xlock_sig(struct sx *sx);

     sx_try_slock(struct sx *sx);

     sx_try_xlock(struct sx *sx);

     sx_sunlock(struct sx *sx);

     sx_xunlock(struct sx *sx);

     sx_unlock(struct sx *sx);

     sx_try_upgrade(struct sx *sx);

     sx_downgrade(struct sx *sx);

     sx_sleep(void *chan, struct sx *sx, int priority, const char *wmesg,
	 int timo);

     struct thread *
     sx_xholder(struct sx *sx);

     sx_xlocked(const struct sx	*sx);

     options INVARIANTS

     sx_assert(const struct sx *sx, int	what);

     #include <sys/kernel.h>

     SX_SYSINIT(name, struct sx	*sx, const char	*desc);

     SX_SYSINIT_FLAGS(name, struct sx *sx, const char *desc, int flags);

     Shared/exclusive locks are	used to	protect	data that are read far more
     often than	they are written.  Shared/exclusive locks do not implement
     priority propagation like mutexes and reader/writer locks to prevent pri-
     ority inversions, so shared/exclusive locks should	be used	prudently.

     Shared/exclusive locks are	created	with either sx_init() or
     sx_init_flags() where sx is a pointer to space for	a struct sx, and
     description is a pointer to a null-terminated character string that de-
     scribes the shared/exclusive lock.	 The opts argument to sx_init_flags()
     specifies a set of	optional flags to alter	the behavior of	sx.  It	con-
     tains one or more of the following	flags:

     SX_DUPOK	   Witness should not log messages about duplicate locks being

     SX_NOWITNESS  Instruct witness(4) to ignore this lock.

     SX_NOPROFILE  Do not profile this lock.

     SX_RECURSE	   Allow threads to recursively	acquire	exclusive locks	for

     SX_QUIET	   Do not log any operations for this lock via ktr(4).

     SX_NEW	   If the kernel has been compiled with	options	INVARIANTS,
		   sx_init() will assert that the sx has not been initialized
		   multiple times without intervening calls to sx_destroy()
		   unless this option is specified.

     Shared/exclusive locks are	destroyed with sx_destroy().  The lock sx must
     not be locked by any thread when it is destroyed.

     Threads acquire and release a shared lock by calling sx_slock(),
     sx_slock_sig() or sx_try_slock() and sx_sunlock() or sx_unlock().
     Threads acquire and release an exclusive lock by calling sx_xlock(),
     sx_xlock_sig() or sx_try_xlock() and sx_xunlock() or sx_unlock().	A
     thread can	attempt	to upgrade a currently held shared lock	to an exclu-
     sive lock by calling sx_try_upgrade().  A thread that has an exclusive
     lock can downgrade	it to a	shared lock by calling sx_downgrade().

     sx_try_slock() and	sx_try_xlock() will return 0 if	the shared/exclusive
     lock cannot be acquired immediately; otherwise the	shared/exclusive lock
     will be acquired and a non-zero value will	be returned.

     sx_try_upgrade() will return 0 if the shared lock cannot be upgraded to
     an	exclusive lock immediately; otherwise the exclusive lock will be ac-
     quired and	a non-zero value will be returned.

     sx_slock_sig() and	sx_xlock_sig() do the same as their normal versions
     but performing an interruptible sleep.  They return a non-zero value if
     the sleep has been	interrupted by a signal	or an interrupt, otherwise 0.

     A thread can atomically release a shared/exclusive	lock while waiting for
     an	event by calling sx_sleep().  For more details on the parameters to
     this function, see	sleep(9).

     When compiled with	options	INVARIANTS and options INVARIANT_SUPPORT, the
     sx_assert() function tests	sx for the assertions specified	in what, and
     panics if they are	not met.  One of the following assertions must be

     SA_LOCKED	  Assert that the current thread has either a shared or	an ex-
		  clusive lock on the sx lock pointed to by the	first argu-

     SA_SLOCKED	  Assert that the current thread has a shared lock on the sx
		  lock pointed to by the first argument.

     SA_XLOCKED	  Assert that the current thread has an	exclusive lock on the
		  sx lock pointed to by	the first argument.

     SA_UNLOCKED  Assert that the current thread has no	lock on	the sx lock
		  pointed to by	the first argument.

     In	addition, one of the following optional	assertions may be included
     with either an SA_LOCKED, SA_SLOCKED, or SA_XLOCKED assertion:

     SA_RECURSED     Assert that the current thread has	a recursed lock	on sx.

     SA_NOTRECURSED  Assert that the current thread does not have a recursed
		     lock on sx.

     sx_xholder() will return a	pointer	to the thread which currently holds an
     exclusive lock on sx.  If no thread holds an exclusive lock on sx,	then
     NULL is returned instead.

     sx_xlocked() will return non-zero if the current thread holds the exclu-
     sive lock;	otherwise, it will return zero.

     For ease of programming, sx_unlock() is provided as a macro frontend to
     the respective functions, sx_sunlock() and	sx_xunlock().  Algorithms that
     are aware of what state the lock is in should use either of the two spe-
     cific functions for a minor performance benefit.

     The SX_SYSINIT() macro is used to generate	a call to the sx_sysinit()
     routine at	system startup in order	to initialize a	given sx lock.	The
     parameters	are the	same as	sx_init() but with an additional argument,
     name, that	is used	in generating unique variable names for	the related
     structures	associated with	the lock and the sysinit routine.  The
     SX_SYSINIT_FLAGS()	macro can similarly be used to initialize a given sx
     lock using	sx_init_flags().

     A thread may not hold both	a shared lock and an exclusive lock on the
     same lock simultaneously; attempting to do	so will	result in deadlock.

     A thread may hold a shared	or exclusive lock on an	sx lock	while sleep-
     ing.  As a	result,	an sx lock may not be acquired while holding a mutex.
     Otherwise,	if one thread slept while holding an sx	lock while another
     thread blocked on the same	sx lock	after acquiring	a mutex, then the sec-
     ond thread	would effectively end up sleeping while	holding	a mutex, which
     is	not allowed.

     lock(9), locking(9), mutex(9), panic(9), rwlock(9), sema(9)

     A kernel without WITNESS cannot assert whether the	current	thread does or
     does not hold a shared lock.  SA_LOCKED and SA_SLOCKED can	only assert
     that any thread holds a shared lock.  They	cannot ensure that the current
     thread holds a shared lock.  Further, SA_UNLOCKED can only	assert that
     the current thread	does not hold an exclusive lock.

FreeBSD	13.0		       November	11, 2017		  FreeBSD 13.0


Want to link to this manual page? Use this URL:

home | help