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_SYSINIT -- kernel shared/exclusive lock
sx_init(struct sx *sx, const char *description);
sx_destroy(struct sx *sx);
sx_slock(struct sx *sx);
sx_xlock(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_try_upgrade(struct sx *sx);
sx_downgrade(struct sx *sx);
sx_assert(struct sx *sx, int what);
SX_SYSINIT(name, struct sx *sx, const char *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(). Threads acquire and release an exclusive lock by calling
sx_xlock() or sx_try_xlock() and sx_xunlock(). A thread can attempt to
upgrade a currently owned shared lock to an exclusive lock by calling
sx_try_upgrade(). A thread that owns 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
acquired and a non-zero value will be returned.
The sx_assert() function tests specified conditions and panics if they
are not met and the kernel is compiled with INVARIANTS.
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 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 exclusive lock on the
sx lock pointed to by the first argument.
A thread may not own a shared lock and an exclusive lock simultaneously;
attempting to do so will result in deadlock.
It is allowed to own a shared lock or an exclusive lock while sleeping.
condvar(9), mtx_pool(9), mutex(9), sema(9)
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.
FreeBSD 5.2.1 August 14, 2001 FreeBSD 5.2.1 [ Back ]