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
.Vt 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 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.
When compiled with
.Cd "options INVARIANTS" and
.Cd "options INVARIANT_SUPPORT" , the sx_assert function tests sx for the assertions specified in what, and panics if they are not met. The following assertions are supported: