xref: /netbsd-src/share/man/man9/rwlock.9 (revision 284662e223eb47611371e772cac54092653c109a)
1.\"	$NetBSD: rwlock.9,v 1.20 2020/02/22 21:24:45 ad Exp $
2.\"
3.\" Copyright (c) 2006, 2007, 2009, 2020 The NetBSD Foundation, Inc.
4.\" All rights reserved.
5.\"
6.\" This code is derived from software contributed to The NetBSD Foundation
7.\" by Andrew Doran.
8.\"
9.\" Redistribution and use in source and binary forms, with or without
10.\" modification, are permitted provided that the following conditions
11.\" are met:
12.\" 1. Redistributions of source code must retain the above copyright
13.\"    notice, this list of conditions and the following disclaimer.
14.\" 2. Redistributions in binary form must reproduce the above copyright
15.\"    notice, this list of conditions and the following disclaimer in the
16.\"    documentation and/or other materials provided with the distribution.
17.\"
18.\" THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
19.\" ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
20.\" TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21.\" PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
22.\" BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23.\" CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24.\" SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25.\" INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26.\" CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28.\" POSSIBILITY OF SUCH DAMAGE.
29.\"
30.Dd February 22, 2020
31.Dt RWLOCK 9
32.Os
33.Sh NAME
34.Nm rw ,
35.Nm rw_init ,
36.Nm rw_destroy ,
37.Nm rw_enter ,
38.Nm rw_exit ,
39.Nm rw_tryenter ,
40.Nm rw_tryupgrade ,
41.Nm rw_downgrade ,
42.Nm rw_read_held ,
43.Nm rw_write_held ,
44.Nm rw_lock_held ,
45.Nm rw_lock_op
46.Nd reader / writer lock primitives
47.Sh SYNOPSIS
48.In sys/rwlock.h
49.Ft void
50.Fn rw_init "krwlock_t *rw"
51.Ft void
52.Fn rw_destroy "krwlock_t *rw"
53.Ft void
54.Fn rw_enter "krwlock_t *rw" "const krw_t op"
55.Ft void
56.Fn rw_exit "krwlock_t *rw"
57.Ft int
58.Fn rw_tryenter "krwlock_t *rw" "const krw_t op"
59.Ft int
60.Fn rw_tryupgrade "krwlock_t *rw"
61.Ft void
62.Fn rw_downgrade "krwlock_t *rw"
63.Ft int
64.Fn rw_read_held "krwlock_t *rw"
65.Ft int
66.Fn rw_write_held "krwlock_t *rw"
67.Ft int
68.Fn rw_lock_held "krwlock_t *rw"
69.Ft krw_t
70.Fn rw_lock_op "krwlock_t *rw"
71.Pp
72.Cd "options DIAGNOSTIC"
73.Cd "options LOCKDEBUG"
74.Sh DESCRIPTION
75Reader / writer locks (RW locks) are used in the kernel to synchronize access
76to an object among LWPs (lightweight processes) and soft interrupt handlers.
77.Pp
78In addition to the capabilities provided by mutexes, RW locks distinguish
79between read (shared) and write (exclusive) access.
80.Pp
81RW locks are in one of three distinct states at any given time:
82.Bl -tag -width cdosrunrundo
83.It Dv Unlocked
84The lock is not held.
85.It Dv Read locked
86The lock holders intend to read the protected object.
87Multiple callers may hold a RW lock with
88.Dq read intent
89simultaneously.
90.It Dv Write locked
91The lock holder intends to update the protected object.
92Only one caller may hold a RW lock with
93.Dq write intent .
94.El
95.Pp
96The
97.Vt krwlock_t
98type provides storage for the RW lock object.
99This should be treated as an opaque object and not examined directly by
100consumers.
101.Pp
102Note that these interfaces must not be used from a hardware
103interrupt handler.
104.Sh OPTIONS AND MACROS
105.Bl -tag -width abcd
106.It Cd "options DIAGNOSTIC"
107.Pp
108Kernels compiled with the
109.Dv DIAGNOSTIC
110option perform basic sanity checks on RW lock operations.
111.It Cd "options LOCKDEBUG"
112.Pp
113Kernels compiled with the
114.Dv LOCKDEBUG
115option perform potentially CPU intensive sanity checks
116on RW lock operations.
117.El
118.Sh FUNCTIONS
119.Bl -tag -width abcd
120.It Fn rw_init "rw"
121.Pp
122Initialize a lock for use.
123No other operations can be performed on the lock until it has been
124initialized.
125.It Fn rw_destroy "rw"
126.Pp
127Release resources used by a lock.
128The lock may not be used after it has been destroyed.
129.It Fn rw_enter "rw" "op"
130.Pp
131If
132.Dv RW_READER
133is specified as the argument to
134.Fa op ,
135acquire a read lock.
136The caller may block and will not return until the hold is acquired.
137Callers must not recursively acquire read locks.
138.Pp
139If
140.Dv RW_WRITER
141is specified, acquire a write lock.
142If the lock is already held, the caller will block and not return until the
143hold is acquired.
144.Pp
145RW locks and other types of locks must always be acquired in a
146consistent order with respect to each other.
147Otherwise, the potential for system deadlock exists.
148.It Fn rw_exit "rw"
149.Pp
150Release a lock.
151The lock must have been previously acquired by the caller.
152.It Fn rw_tryenter "rw" "op"
153.Pp
154Try to acquire a lock, but do not block if the lock is already held.
155If the lock is acquired successfully, return non-zero.
156Otherwise, return zero.
157.Pp
158Valid arguments to
159.Fa op
160are
161.Dv RW_READER
162or
163.Dv RW_WRITER .
164.It Fn rw_tryupgrade "rw"
165.Pp
166Try to upgrade a lock from one read hold to a write hold.
167If the lock is upgraded successfully, returns non-zero.
168Otherwise, returns zero.
169.It Fn rw_downgrade "rw"
170.Pp
171Downgrade a lock from a write hold to a read hold.
172.It Fn rw_write_held "rw"
173.Pp
174Return non-zero if write lock is held by current lwp.
175Otherwise, return zero.
176.It Fn rw_read_held "rw"
177.Pp
178Returns non-zero if read lock is held by any lwp.
179Otherwise, return zero.
180.It Fn rw_lock_held "rw"
181.Pp
182Returns non-zero if either read or write lock is held by any lwp.
183Otherwise, return zero.
184.Pp
185.Fn rw_write_held ,
186.Fn rw_read_held ,
187and
188.Fn rw_lock_held
189should not generally be used to make locking decisions at run time:
190they are provided for diagnostic purposes, for example making
191assertions.
192.Pp
193Negative assertions (lock not held) should not be made due to atomicity
194issues, excepting
195.Fn rw_write_held ,
196which can safely be used to assert that a write lock is NOT held by
197the current LWP.
198.It Fn rw_lock_op "rw"
199.Pp
200For a lock that is known to be held by the calling LWP, return either
201.Dv RW_READER
202or
203.Dv RW_WRITER
204to denote the type of hold.
205This is useful when dropping and later re-acquiring a lock, if the type
206of hold is not already known.
207.El
208.Sh PERFORMANCE CONSIDERATIONS
209RW locks are subject to high cache contention on multiprocessor systems,
210and scale poorly when the write:read ratio is not strongly in favour of
211readers.
212Ideally, RW locks should only be used in settings when the following three
213conditions are met:
214.Bl -bullet
215.It
216The data object(s) protected by the RW lock are read much more frequently
217than written.
218.It
219The read-side hold time for the RW lock is long (in the order of thousands
220of processor clock cycles).
221.It
222Strong synchronization semantics are required: there is no scope for
223lockless, lazy or optimistic synchronization.
224.El
225.Pp
226Generally speaking, it is better to organise code paths and/or
227data flows such that fewer and weaker synchronization points are required
228to ensure correct operation.
229.Sh CODE REFERENCES
230The core of the RW lock implementation is in
231.Pa sys/kern/kern_rwlock.c .
232.Pp
233The header file
234.Pa sys/sys/rwlock.h
235describes the public interface, and interfaces that machine-dependent
236code must provide to support RW locks.
237.Sh SEE ALSO
238.Xr membar_ops 3 ,
239.Xr lockstat 8 ,
240.Xr condvar 9 ,
241.Xr mutex 9
242.Rs
243.%A Jim Mauro
244.%A Richard McDougall
245.%T Solaris Internals: Core Kernel Architecture
246.%I Prentice Hall
247.%D 2001
248.%O ISBN 0-13-022496-0
249.Re
250.Sh HISTORY
251The RW lock primitives first appeared in
252.Nx 5.0 .
253