Add manual pages for RW locks, mutexes and condition variables. Not

enabled in the Makefile.
This commit is contained in:
ad 2006-11-13 16:22:11 +00:00
parent b1fe4841a1
commit bea3d13d1d
3 changed files with 659 additions and 0 deletions

244
share/man/man9/condvar.9 Normal file
View File

@ -0,0 +1,244 @@
.\" $NetBSD: condvar.9,v 1.1 2006/11/13 16:22:11 ad Exp $
.\"
.\" Copyright (c) 2006 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Andrew Doran.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the NetBSD
.\" Foundation, Inc. and its contributors.
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
.\" contributors may be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd November 13, 2006
.Dt CONDVAR 9
.Os
.Sh NAME
.Nm cv ,
.Nm condvar ,
.Nm cv_init ,
.Nm cv_destroy ,
.Nm cv_wait ,
.Nm cv_wait_sig ,
.Nm cv_timedwait ,
.Nm cv_timedwait_sig ,
.Nm cv_signal ,
.Nm cv_broadcast
.Nd condition variables
.Sh SYNOPSIS
.In sys/condvar.h
.Ft void
.Fn cv_init "kcondvar_t *cv" "const char *wmesg"
.Ft void
.Fn cv_destroy "kcondvar_t *cv"
.Ft void
.Fn cv_wait "kcondvar_t *cv" "kmutex_t *mtx"
.Ft int
.Fn cv_wait_sig "kcondvar_t *cv" "kmutex_t *mtx"
.Ft int
.Fn cv_timedwait "kcondvar_t *cv" "kmutex_t *mtx" "int ticks"
.Ft int
.Fn cv_timedwait_sig "kcondvar_t *cv" "kmutex_t *mtx" "int ticks"
.Ft void
.Fn cv_signal "kcondvar_t *cv"
.Ft void
.Fn cv_broadcast "kcondvar_t *cv"
.Sh DESCRIPTION
Condition variables (CVs) are used in the kernel to synchronize access
to resources that are limited (for example, memory) and to wait for
pending I/O operations to complete.
.Pp
The
.Vt kcondvar_t
type provides storage for the CV object.
This should be treated as an opaque object and not examined directly by
consumers.
.Sh FUNCTIONS
.Bl -tag -width abcd
.It Fn cv_init "cv" "wmesg"
.Pp
Initialize a CV for use.
No other operations can be performed on the CV until it has been initialized.
.Pp
The
.Fa wmesg
argument specifies a string of no more than 8 characters that describes
the resource or condition associated with the CV.
The kernel does not use this argument directly but makes it available for
utilities such as
.Xr ps 1
to display.
.It Fn cv_destroy "cv"
.Pp
Release resources used by a CV.
The CV must not be in use when it is destroyed, and must not be used afterwards.
.It Fn cv_wait "cv" "mtx"
.Pp
Cause the current LWP to wait non-interruptably for access to a resource,
or for an I/O operation to complete.
The LWP will resume execution when awoken by another thread using
.Fn cv_signal
or
.Fn cv_broadcast .
.Pp
.Fa mtx
specifies a kernel mutex to be used as an interlock, and must be held by the
calling LWP on entry to
.Fn cv_wait .
It will be released once the LWP has prepared to sleep, and will be reacquired
before
.Fn cv_wait
returns.
.Pp
A small window exists between testing for availability of a resource and
waiting for the resource with
.Fn cv_wait ,
in which the resource may become available again.
The interlock is used to guarentee that the resource will not be signalled
as available until the calling LWP has begun to wait for it.
.Pp
Non-interruptable waits have the potential to deadlock the system, and so must
be kept short (typically, under one second).
.It Fn cv_wait_sig "cv" "mtx"
.Pp
As per
.Fn cv_wait ,
but causes the current LWP to wait interruptably.
If the LWP recieves a signal, or is interrupted by another condition such
as its containing process exiting, the wait is ended early and an error
code returned.
.Pp
If
.Fn cv_wait_sig
returns as a result of a signal, the return value is ERESTART if the signal
has the SA_RESTART property.
If awoken normally, the value is zero, and EINTR under all other conditions.
.It Fn cv_timedwait "cv" "mtx" "ticks"
.Pp
As per
.Fn cv_wait ,
but will return early if a timeout specified by the
.Fa ticks
argument expires.
.Pp
.Fa ticks
is an architecture and system dependent value related to the number of
clock interrupts per second.
See
.Xr hz 9
for details.
The
.Xr mstohz 9
macro can be used to convert a timeout expressed in milliseconds to
one suitable for
.Fn cv_timedwait .
.Pp
If the timeout expires before the LWP is awoken, the return value is
EWOULDBLOCK.
If awoken normally, the return value is zero.
.It Fn cv_timedwait_sig "cv" "mtx" "ticks"
.Pp
As per
.Fn cv_wait_sig ,
but also accepts a timeout value and will return EWOULDBLOCK if the
timeout expires.
.It Fn cv_signal "cv"
.Pp
Awaken one LWP (potentially among many) that is waiting on the specified
condition variable.
.Pp
(Note that
.Fn cv_signal
is erroneously named in that it does not send a signal in the traditional
sense to LWPs waiting on a CV.)
.It Fn cv_broadcast "cv"
.Pp
Awaken all LWPs waiting on the specified condition variable.
.Sh EXAMPLES
.Bd -literal
Consuming a resource:
/*
* Lock the resource. Its mutex will also serve as the
* interlock.
*/
mutex_enter(&res->mutex);
/*
* Wait for the resource to become available, and take
* ownership of it.
*/
while (res->state == BUSY)
cv_wait(&res->condvar, &res->mutex);
res->state = BUSY;
/*
* It's now available, so consume it.
*/
consume(res);
mutex_exit(&res->mutex);
Releasing a resource for the next consumer to use:
mutex_enter(&res->mutex);
res->state = IDLE;
cv_signal(&res->condvar);
mutex_exit(&res->mutex);
.Ed
.Sh CODE REFERENCES
This section describes places within the
.Nx
source tree where actual code implementing or using the name
lookup cache can be found.
All pathnames are relative to
.Pa /usr/src .
.Pp
The core of the CV implementation is in
.Pa sys/kern/kern_condvar.c .
.Pp
The header file
.Pa sys/sys/condvar.h
describes the public interface, and interfaces that machine-dependent
code must provide to support RW locks.
.Sh SEE ALSO
.Xr condvar 9 ,
.Xr errno 9 ,
.Xr mstohz 9 ,
.Xr mutex 9 ,
.Xr sigaction 2 ,
.Xr rwlock 9 .
.Pp
Jim Mauro and Richard McDougall,
.Em Solaris Internals: Core Kernel Architecture ,
Prentice Hall, 2001.
ISBN 0-13-022496-0
.Sh HISTORY
The CV primatives first appeared in
.Nx 5.0 .
They are modelled after similar primatives implemented in
Sun Solaris, and have been extended for NetBSD.

204
share/man/man9/mutex.9 Normal file
View File

@ -0,0 +1,204 @@
.\" $NetBSD: mutex.9,v 1.1 2006/11/13 16:22:11 ad Exp $
.\"
.\" Copyright (c) 2006 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Andrew Doran.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the NetBSD
.\" Foundation, Inc. and its contributors.
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
.\" contributors may be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd November 13, 2006
.Dt MUTEX 9
.Os
.Sh NAME
.Nm mutex ,
.Nm mutex_init ,
.Nm mutex_destroy ,
.Nm mutex_enter ,
.Nm mutex_exit ,
.Nm mutex_tryenter
.Nm mutex_owned
.Nd mutual exclusion primitives
.Sh SYNOPSIS
.In sys/mutex.h
.Ft void
.Fn mutex_init "kmutex_t *mtx" "kmutex_type_t type" "int ipl"
.Ft void
.Fn mutex_destroy "kmutex_t *mtx"
.Ft void
.Fn mutex_enter "kmutex_t *mtx"
.Ft void
.Fn mutex_exit "kmutex_t *mtx"
.Ft int
.Fn mutex_tryenter "kmutex_t *mtx"
.Ft int
.Fn mutex_owned "kmutex_t *mtx"
.Pp
.Cd "options DIAGNOSTIC"
.Cd "options LOCKDEBUG"
.Sh DESCRIPTION
Mutexes are used in the kernel to implement mutual exclusion among LWPs
(lightweight processes) and interrupt handlers.
.Pp
Two core types of mutex are currently provided, and are manipulated using the
same interface:
.Bl -tag -width cdoscdosrunrun
.It Dv MUTEX_ADAPTIVE
Adaptive mutexes provide mutual exclusion between LWPs.
.Pp
When initializing an adaptive mutex, IPL_NONE must be specified as the
.Ar ipl
argument.
Adaptive mutexes can not be acquired from an interrupt handler.
.Pp
In general, an LWP that owns an adaptive mutex must not sleep with the mutex
held, unless acquiring another mutex or sleep lock.
.Pp
An LWP may either sleep or busy-wait when attempting to acquire
an adaptive mutex that is already held.
.It Dv MUTEX_SPIN
Spin mutexes provide mutual exclusion between LWPs, and between LWPs
and interrupt handlers.
.Pp
When initializing a spin mutex, the
.Ar ipl
argument is used to pass an system interrupt priority level (SPL)
that will block all interrupt handlers that may try to acquire the mutex.
.Pp
LWPs that own spin mutexes may not sleep, and therefore must not
try to acquire adaptive mutexes or other sleep locks.
.Pp
A processor will always busy-wait when attempting to acquire
a spin mutex that is already held.
.El
.Pp
Kernel code, in particular device drivers, should not directly request
spin or adaptive mutexes unless necessary.
The following types should be requested:
.Bl -tag -width cdoscdosrunrun
.It Dv MUTEX_DEFAULT
General mutex type.
May sleep.
.It Dv MUTEX_DRIVER
Device driver mutex.
May or may not sleep.
.El
.Pp
The
.Vt kmutex_t
type provides storage for the mutex object.
This should be treated as an opaque object and not examined directly by
consumers.
.Sh OPTIONS
.Bl -tag -width abcd
.It Cd "options DIANOSTIC"
.Pp
Kernels compiled with the
.Dv DIAGNOSTIC
option perform basic sanity checks on mutex operations.
.It Cd "options LOCKDEBUG"
.Pp
Kernels compiled with the
.Dv LOCKDEBUG
option perform potentially CPU intensive sanity checks
on mutex operations.
.El
.Sh FUNCTIONS
.Bl -tag -width abcd
.It Fn mutex_init "mtx" "type" "ipl"
.Pp
Dynamically initialize a mutex for use.
No other operations can be performed on a mutex until it has been initialized.
.It Fn mutex_destroy "mtx"
.Pp
Release resources used by a mutex.
The mutex may not be used after it has been destroyed.
.It Fn mutex_enter "mtx"
.Pp
Acquire a mutex.
If the mutex is already held, the caller will block and not return until the
mutex is acquired.
.Pp
Mutexes 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.
.It Fn mutex_exit "mtx"
.Pp
Release a mutex.
The mutex must have been previously acquired by the caller.
Mutexes may be released out of order as needed.
.It Fn mutex_tryenter "mtx"
.Pp
Try to acquire a mutex, but do not block if the mutex is already held.
Returns non-zero if the mutex was acquired, or zero if the mutex was
already held.
.It Fn mutex_owned "mtx"
.Pp
For adaptive mutexes, return non-zero if the current LWP holds the mutex.
For spin mutexes, return non-zero if the mutex is held, potentially by the
current processor.
Otherwise, return zero.
.Pp
For spin mutexes,
.Fn mutex_owned
may unconditionally return non-zero when the kernel is not built with the
.Dv DIAGNOSTIC
option, and is therefore suitable only for diagnostic checks that verify
that a lock is held.
.Fn mutex_owned
must not be used to make locking decisions at run time.
.Sh CODE REFERENCES
This section describes places within the
.Nx
source tree where actual code implementing or using the name
lookup cache can be found.
All pathnames are relative to
.Pa /usr/src .
.Pp
The core of the mutex implementation is in
.Pa sys/kern/kern_mutex.c .
.Pp
The header file
.Pa sys/sys/mutex.h
describes the public interface, and interfaces that machine-dependent
code must provide to support mutexes.
.Sh SEE ALSO
.Xr condvar 9 ,
.Xr rwlock 9 .
.Pp
Jim Mauro and Richard McDougall,
.Em Solaris Internals: Core Kernel Architecture ,
Prentice Hall, 2001.
ISBN 0-13-022496-0
.Sh HISTORY
The mutex primatives first appeared in
.Nx 5.0 .
They are modelled after the mutual exclusion primatives implemented in
Sun Solaris, and have been extended for NetBSD.

211
share/man/man9/rwlock.9 Normal file
View File

@ -0,0 +1,211 @@
.\" $NetBSD: rwlock.9,v 1.1 2006/11/13 16:22:11 ad Exp $
.\"
.\" Copyright (c) 2006 The NetBSD Foundation, Inc.
.\" All rights reserved.
.\"
.\" This code is derived from software contributed to The NetBSD Foundation
.\" by Andrew Doran.
.\"
.\" Redistribution and use in source and binary forms, with or without
.\" modification, are permitted provided that the following conditions
.\" are met:
.\" 1. Redistributions of source code must retain the above copyright
.\" notice, this list of conditions and the following disclaimer.
.\" 2. Redistributions in binary form must reproduce the above copyright
.\" notice, this list of conditions and the following disclaimer in the
.\" documentation and/or other materials provided with the distribution.
.\" 3. All advertising materials mentioning features or use of this software
.\" must display the following acknowledgement:
.\" This product includes software developed by the NetBSD
.\" Foundation, Inc. and its contributors.
.\" 4. Neither the name of The NetBSD Foundation nor the names of its
.\" contributors may be used to endorse or promote products derived
.\" from this software without specific prior written permission.
.\"
.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
.\" PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd November 13, 2006
.Dt RWLOCK 9
.Os
.Sh NAME
.Nm rw ,
.Nm rw_init ,
.Nm rw_destroy ,
.Nm rw_enter ,
.Nm rw_exit ,
.Nm rw_tryenter ,
.Nm rw_tryupgrade ,
.Nm rw_downgrade ,
.Nm rw_read_held ,
.Nm rw_write_held ,
.Nm rw_lock_held
.Nd reader / writer lock primitives
.Sh SYNOPSIS
.In sys/rwlock.h
.Ft void
.Fn rw_init "krwlock_t *rw"
.Ft void
.Fn rw_destroy "krwlock_t *rw"
.Ft void
.Fn rw_enter "krwlock_t *rw" "krwlock_op_t op"
.Ft void
.Fn rw_exit "krwlock_t *rw"
.Ft int
.Fn rw_tryenter "krwlock_t *rw" "krwlock_op_t op"
.Ft int
.Fn rw_tryupgrade "krwlock_t *rw"
.Ft void
.Fn rw_downgrade "krwlock_t *rw"
.Ft int
.Fn rw_read_held "krwlock_t *rw"
.Ft int
.Fn rw_write_held "krwlock_t *rw"
.Ft int
.Fn rw_lock_held "krwlock_t *rw"
.Pp
.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).
.Pp
In addition to the capabilities provided by mutexes, RW locks distinguish
between read (shared) and write (exclusive) access.
RW locks are intended to provide protection for kernel data
or objects that are read much more frequently than updated.
For objects that are updated as frequently as they are read, mutexes should
be used to guarantee atomic access.
.Pp
RW locks are in one of three distinct states at any given time:
.Bl -tag -width cdosrunrundo
.It Dv Unlocked
The lock is not held.
.It Dv Read locked
The lock holders intend to read the protected object.
Multiple callers may hold a RW lock with 'read intent' simultaneously.
.It Dv Write locked
The lock holder intends to update the protected object.
Only one caller may hold a RW lock with 'write intent'.
.El
.Pp
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.
.Sh OPTIONS AND MACROS
.Bl -tag -width abcd
.It Cd "options DIANOSTIC"
.Pp
Kernels compiled with the
.Dv DIAGNOSTIC
option perform basic sanity checks on RW lock operations.
.It Cd "options LOCKDEBUG"
.Pp
Kernels compiled with the
.Dv LOCKDEBUG
option perform potentially CPU intensive sanity checks
on RW lock operations.
.El
.Sh FUNCTIONS
.Bl -tag -width abcd
.It Fn rw_init "rw"
.Pp
Initialize a lock for use.
No other operations can be performed on the lock until it has been initialized.
.It Fn rw_destroy "rw"
.Pp
Release resources used by a lock.
The lock may not be used after it has been destroyed.
.It Fn rw_enter "rw" "op"
.Pp
If
.Dv RW_READER
is specified as the argument to
.Fa op ,
acquire a read lock.
If the lock is write held, the caller will block and not return until the
hold is acquired.
Callers must not recursively acquire read locks.
.Pp
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.
.Pp
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.
.It Fn rw_exit "rw"
.Pp
Release a lock.
The lock must have been previously acquired by the caller.
.It Fn rw_tryenter "rw" "op"
.Pp
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.
.Pp
Valid arguments to
.Fa op
are
.Dv RW_READ
or
.Dv RW_WRITE .
.It Fn rw_tryupgrade "rw"
.Pp
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.
.It Fn rw_downgrade "rw"
.Pp
Downgrade a lock from a write hold to a read hold.
.It Fn rw_write_held "rw"
.It Fn rw_read_held "rw"
.It Fn rw_lock_held "rw"
.Pp
Test the lock's condition and return non-zero if the lock is held
(potentially by the current LWP) and matches the specified condition.
Otherwise, return zero.
.Pp
These functions must never be used to make locking decisions at run time:
they are provided only for diagnostic purposes.
.Sh CODE REFERENCES
This section describes places within the
.Nx
source tree where actual code implementing or using the name
lookup cache can be found.
All pathnames are relative to
.Pa /usr/src .
.Pp
The core of the rwlock implementation is in
.Pa sys/kern/kern_rwlock.c .
.Pp
The header file
.Pa sys/sys/rwlock.h
describes the public interface, and interfaces that machine-dependent
code must provide to support RW locks.
.Sh SEE ALSO
.Xr condvar 9 ,
.Xr mutex 9 .
.Pp
Jim Mauro and Richard McDougall,
.Em Solaris Internals: Core Kernel Architecture ,
Prentice Hall, 2001.
ISBN 0-13-022496-0
.Sh HISTORY
The RW lock primatives first appeared in
.Nx 5.0 .
They are modelled after the reader / writer lock primatives implemented in
Sun Solaris, and have been extended for NetBSD.