rwlock(9)
- NetBSD Manual Pages
RWLOCK(9) NetBSD Kernel Developer's Manual RWLOCK(9)
NAME
rw, rw_init, rw_destroy, rw_enter, rw_exit, rw_tryenter, rw_tryupgrade,
rw_downgrade, rw_read_held, rw_write_held, rw_lock_held, rw_lock_op --
reader / writer lock primitives
SYNOPSIS
#include <sys/rwlock.h>
void
rw_init(krwlock_t *rw);
void
rw_destroy(krwlock_t *rw);
void
rw_enter(krwlock_t *rw, const krw_t op);
void
rw_exit(krwlock_t *rw);
int
rw_tryenter(krwlock_t *rw, const krw_t op);
int
rw_tryupgrade(krwlock_t *rw);
void
rw_downgrade(krwlock_t *rw);
int
rw_read_held(krwlock_t *rw);
int
rw_write_held(krwlock_t *rw);
int
rw_lock_held(krwlock_t *rw);
krw_t
rw_lock_op(krwlock_t *rw);
options DIAGNOSTIC
options LOCKDEBUG
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.
In addition to the capabilities provided by mutexes, RW locks distinguish
between read (shared) and write (exclusive) access.
RW locks are in one of three distinct states at any given time:
Unlocked The lock is not held.
Read locked The lock holders intend to read the protected object. Mul-
tiple callers may hold a RW lock with ``read intent''
simultaneously.
Write locked The lock holder intends to update the protected object.
Only one caller may hold a RW lock with ``write intent''.
The krwlock_t type provides storage for the RW lock object. This should
be treated as an opaque object and not examined directly by consumers.
Note that these interfaces must not be used from a hardware interrupt
handler.
OPTIONS AND MACROS
options DIAGNOSTIC
Kernels compiled with the DIAGNOSTIC option perform basic sanity
checks on RW lock operations.
options LOCKDEBUG
Kernels compiled with the LOCKDEBUG option perform potentially CPU
intensive sanity checks on RW lock operations.
FUNCTIONS
rw_init(rw)
Initialize a lock for use. No other operations can be performed on
the lock until it has been initialized.
rw_destroy(rw)
Release resources used by a lock. The lock may not be used after
it has been destroyed.
rw_enter(rw, op)
If RW_READER is specified as the argument to 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.
If 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.
RW locks and other types of locks must always be acquired in a con-
sistent order with respect to each other. Otherwise, the potential
for system deadlock exists.
rw_exit(rw)
Release a lock. The lock must have been previously acquired by the
caller.
rw_tryenter(rw, op)
Try to acquire a lock, but do not block if the lock is already
held. If the lock is acquired successfully, return non-zero. Oth-
erwise, return zero.
Valid arguments to op are RW_READER or RW_WRITER.
rw_tryupgrade(rw)
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.
rw_downgrade(rw)
Downgrade a lock from a write hold to a read hold.
rw_write_held(rw)
Return non-zero if write lock is held by current lwp. Otherwise,
return zero.
rw_read_held(rw)
Returns non-zero if read lock is held by any lwp. Otherwise,
return zero.
rw_lock_held(rw)
Returns non-zero if either read or write lock is held by any lwp.
Otherwise, return zero.
rw_write_held(), rw_read_held(), and rw_lock_held() should not gen-
erally be used to make locking decisions at run time: they are pro-
vided for diagnostic purposes, for example making assertions.
Negative assertions (lock not held) should not be made due to atom-
icity issues, excepting rw_write_held(), which can safely be used
to assert that a write lock is NOT held by the current LWP.
rw_lock_op(rw)
For a lock that is known to be held by the calling LWP, return
either RW_READER or 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.
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 fol-
lowing three conditions are met:
· The data object(s) protected by the RW lock are read much more fre-
quently than written.
· The read-side hold time for the RW lock is long (in the order of
thousands of processor clock cycles).
· Strong synchronization semantics are required: there is no scope for
lockless, lazy or optimistic synchronization.
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.
CODE REFERENCES
The core of the RW lock implementation is in sys/kern/kern_rwlock.c.
The header file sys/sys/rwlock.h describes the public interface, and
interfaces that machine-dependent code must provide to support RW locks.
SEE ALSO
membar_ops(3), lockstat(8), condvar(9), mutex(9)
Jim Mauro and Richard McDougall, Solaris Internals: Core Kernel
Architecture, Prentice Hall, 2001, ISBN 0-13-022496-0.
HISTORY
The RW lock primitives first appeared in NetBSD 5.0.
NetBSD 10.99 February 22, 2020 NetBSD 10.99
Powered by man-cgi (2021-06-01).
Maintained for NetBSD
by Kimmo Suominen.
Based on man-cgi by Panagiotis Christias.