sx(9)
NAME
- sx, sx_init, sx_destroy, sx_slock, sx_xlock, sx_try_slock,
- sx_try_xlock,
sx_sunlock, sx_xunlock, sx_try_upgrade, sx_downgrade, - sx_assert,
sx_unlock, 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_destroy(struct sx *sx); void sx_slock(struct sx *sx); void sx_xlock(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); int sx_try_upgrade(struct sx *sx); void sx_downgrade(struct sx *sx); void sx_assert(struct sx *sx, int what); sx utility macros sx_unlock(struct sx *sx); SX_SYSINIT(name, struct sx *sx, const char *description); Kernel options options INVARIANTS options INVARIANT_SUPPORT
DESCRIPTION
- Shared/exclusive locks are used to protect data that are
- read far more
often than they are written. Mutexes are inherently more - efficient than
shared/exclusive locks, so shared/exclusive locks should be - used prudently.
- Shared/exclusive locks are created with sx_init(), where sx
- is a pointer
to space for a struct sx, and description is a pointer to a - null-terminated character string that describes the shared/exclusive
- lock.
Shared/exclusive locks are destroyed with sx_destroy(). - Threads acquire
and release a shared lock by calling sx_slock() or - sx_try_slock() and
sx_sunlock() or sx_unlock(). Threads acquire and release an - exclusive
lock by calling sx_xlock() or sx_try_xlock() and - sx_xunlock() or
sx_unlock(). A thread can attempt to upgrade a currently - held shared
lock to an exclusive lock by calling sx_try_upgrade(). A - thread that has
an exclusive lock can downgrade it to a shared lock by call - ing
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
acquired and a non-zero value will be returned. - When compiled with options INVARIANTS and options
INVARIANT_SUPPORT
- sx_assert() function tests sx for the assertions specified
- in what, and
panics if they are not met. The following assertions are - supported:
- SX_LOCKED Assert that the current thread has either a
- shared or an
- exclusive lock on the sx lock pointed to by
- the first
argument. - SX_SLOCKED Assert that the current thread has a shared
- lock on the
- sx lock pointed to by the first argument.
- SX_XLOCKED Assert that the current thread has an ex
- clusive lock on
- the sx lock pointed to by the first argu
- ment.
- SX_UNLOCKED Assert that the current thread has no lock
- on the sx
- lock pointed to by the first argument.
- 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 specific 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 sleeping. 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 second thread would effectively end up sleeping while holding a
- mutex, which
is not allowed.
SEE ALSO
condvar(9), mtx_pool(9), mutex(9), panic(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 SX_LOCKED - and
SX_SLOCKED assertions merely check that some thread holds a - shared lock.
They do not ensure that the current thread holds a shared - lock.
- BSD January 5, 2005