p .Cd "options DIAGNOSTIC" .Cd "options LOCKDEBUG" .Sh DESCRIPTION Reader / writer locks (RW locks) are used in the kernel to synchronize access to an object among LWPs (lightweight processes) and soft interrupt handlers.
p In addition to the capabilities provided by mutexes, RW locks distinguish between read (shared) and write (exclusive) access.
p RW locks are in one of three distinct states at any given time: l -tag -width cdosrunrundo t Dv Unlocked The lock is not held. t Dv Read locked The lock holders intend to read the protected object. Multiple callers may hold a RW lock with .Dq read intent simultaneously. t Dv Write locked The lock holder intends to update the protected object. Only one caller may hold a RW lock with .Dq write intent . .El
p The .Vt krwlock_t type provides storage for the RW lock object. This should be treated as an opaque object and not examined directly by consumers.
p Note that these interfaces must not be used from a hardware interrupt handler. .Sh OPTIONS AND MACROS l -tag -width abcd t Cd "options DIAGNOSTIC"
p Kernels compiled with the .Dv DIAGNOSTIC option perform basic sanity checks on RW lock operations. t Cd "options LOCKDEBUG"
p Kernels compiled with the .Dv LOCKDEBUG option perform potentially CPU intensive sanity checks on RW lock operations. .El .Sh FUNCTIONS l -tag -width abcd t Fn rw_init "rw"
p Initialize a lock for use. No other operations can be performed on the lock until it has been initialized. t Fn rw_destroy "rw"
p Release resources used by a lock. The lock may not be used after it has been destroyed. t Fn rw_enter "rw" "op"
p If .Dv RW_READER is specified as the argument to .Fa op , acquire a read lock. The caller may block and will not return until the hold is acquired. Callers must not recursively acquire read locks.
p If .Dv RW_WRITER is specified, acquire a write lock. If the lock is already held, the caller will block and not return until the hold is acquired.
p RW locks and other types of locks must always be acquired in a consistent order with respect to each other. Otherwise, the potential for system deadlock exists. t Fn rw_exit "rw"
p Release a lock. The lock must have been previously acquired by the caller. t Fn rw_tryenter "rw" "op"
p Try to acquire a lock, but do not block if the lock is already held. If the lock is acquired successfully, return non-zero. Otherwise, return zero.
p Valid arguments to .Fa op are .Dv RW_READER or .Dv RW_WRITER . t Fn rw_tryupgrade "rw"
p Try to upgrade a lock from one read hold to a write hold. If the lock is upgraded successfully, returns non-zero. Otherwise, returns zero. t Fn rw_downgrade "rw"
p Downgrade a lock from a write hold to a read hold. t Fn rw_write_held "rw"
p Return non-zero if write lock is held by current lwp. Otherwise, return zero. t Fn rw_read_held "rw"
p Returns non-zero if read lock is held by any lwp. Otherwise, return zero. t Fn rw_lock_held "rw"
p Returns non-zero if either read or write lock is held by any lwp. Otherwise, return zero.
p .Fn rw_write_held , .Fn rw_read_held , and .Fn rw_lock_held should not generally be used to make locking decisions at run time: they are provided for diagnostic purposes, for example making assertions.
p Negative assertions (lock not held) should not be made due to atomicity issues, excepting .Fn rw_write_held , which can safely be used to assert that a write lock is NOT held by the current LWP. t Fn rw_lock_op "rw"
p For a lock that is known to be held by the calling LWP, return either .Dv RW_READER or .Dv RW_WRITER to denote the type of hold. This is useful when dropping and later re-acquiring a lock, if the type of hold is not already known. .El .Sh PERFORMANCE CONSIDERATIONS RW locks are subject to high cache contention on multiprocessor systems, and scale poorly when the write:read ratio is not strongly in favour of readers. Ideally, RW locks should only be used in settings when the following three conditions are met: l -bullet t The data object(s) protected by the RW lock are read much more frequently than written. t The read-side hold time for the RW lock is long (in the order of thousands of processor clock cycles). t Strong synchronization semantics are required: there is no scope for lockless, lazy or optimistic synchronization. .El
p Generally speaking, it is better to organise code paths and/or data flows such that fewer and weaker synchronization points are required to ensure correct operation. .Sh CODE REFERENCES The core of the RW lock implementation is in
a sys/kern/kern_rwlock.c .
p The header file
a sys/sys/rwlock.h describes the public interface, and interfaces that machine-dependent code must provide to support RW locks. .Sh SEE ALSO .Xr membar_ops 3 , .Xr lockstat 8 , .Xr condvar 9 , .Xr mutex 9 .Rs .%A Jim Mauro .%A Richard McDougall .%T Solaris Internals: Core Kernel Architecture .%I Prentice Hall .%D 2001 .%O ISBN 0-13-022496-0 .Re .Sh HISTORY The RW lock primitives first appeared in .Nx 5.0 .