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

FreeBSD Manual Pages

  
 
  

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

NAME
     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 -- kernel shared/exclusive lock

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

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

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

     void
     sx_destroy(struct sx *sx);

     void
     sx_slock(struct sx	*sx);

     void
     sx_xlock(struct sx	*sx);

     int
     sx_slock_sig(struct sx *sx);

     int
     sx_xlock_sig(struct sx *sx);

     int
     sx_try_slock(struct sx *sx);

     int
     sx_try_xlock(struct sx *sx);

     void
     sx_sunlock(struct sx *sx);

     void
     sx_xunlock(struct sx *sx);

     void
     sx_unlock(struct sx *sx);

     int
     sx_try_upgrade(struct sx *sx);

     void
     sx_downgrade(struct sx *sx);

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

     struct thread *
     sx_xholder(struct sx *sx);

     int
     sx_xlocked(struct sx *sx);

     options INVARIANTS
     options INVARIANT_SUPPORT

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

     #include <sys/kernel.h>

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

DESCRIPTION
     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_NOADAPTIVE  If the kernel is not compiled with options NO_ADAPTIVE_SX,
		    then lock operations for sx	will spin instead of sleeping
		    while an exclusive lock holder is executing	on another
		    CPU.

     SX_DUPOK	    Witness should not log messages about duplicate locks be-
		    ing	acquired.

     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.

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

     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
     specified:

     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-
		  ment.

     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.

     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.

CONTEXT
     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.

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

BUGS
     Currently there is	no way to assert that a	lock is	not held.  This	is not
     possible in the non-WITNESS case for asserting that this thread does not
     hold a shared lock.  In the non-WITNESS case, the SA_LOCKED and
     SA_SLOCKED	assertions merely check	that some thread holds a shared	lock.
     They do not ensure	that the current thread	holds a	shared lock.

BSD				 May 28, 2009				   BSD

NAME | SYNOPSIS | DESCRIPTION | CONTEXT | SEE ALSO | BUGS

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=sx&sektion=9&manpath=FreeBSD+9.0-RELEASE>

home | help