xref: /freebsd/share/man/man9/rwlock.9 (revision 10f0bcab61ef441cb5af32fb706688d8cbd55dc0)
1.\" Copyright (c) 2006 Gleb Smirnoff <glebius@FreeBSD.org>
2.\" All rights reserved.
3.\"
4.\" Redistribution and use in source and binary forms, with or without
5.\" modification, are permitted provided that the following conditions
6.\" are met:
7.\" 1. Redistributions of source code must retain the above copyright
8.\"    notice, this list of conditions and the following disclaimer.
9.\" 2. Redistributions in binary form must reproduce the above copyright
10.\"    notice, this list of conditions and the following disclaimer in the
11.\"    documentation and/or other materials provided with the distribution.
12.\"
13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23.\" SUCH DAMAGE.
24.\"
25.\" $FreeBSD$
26.\"
27.Dd March 16, 2008
28.Dt RWLOCK 9
29.Os
30.Sh NAME
31.Nm rwlock ,
32.Nm rw_init ,
33.Nm rw_init_flags,
34.Nm rw_destroy ,
35.Nm rw_rlock ,
36.Nm rw_wlock ,
37.Nm rw_runlock ,
38.Nm rw_wunlock ,
39.Nm rw_unlock ,
40.Nm rw_try_upgrade ,
41.Nm rw_downgrade ,
42.Nm rw_sleep ,
43.Nm rw_initialized ,
44.Nm rw_wowned ,
45.Nm rw_assert ,
46.Nm RW_SYSINIT
47.Nd kernel reader/writer lock
48.Sh SYNOPSIS
49.In sys/param.h
50.In sys/lock.h
51.In sys/rwlock.h
52.Ft void
53.Fn rw_init "struct rwlock *rw" "const char *name"
54.Ft void
55.Fn rw_init_flags "struct rwlock *rw" "const char *name" "int opts"
56.Ft void
57.Fn rw_destroy "struct rwlock *rw"
58.Ft void
59.Fn rw_rlock "struct rwlock *rw"
60.Ft void
61.Fn rw_wlock "struct rwlock *rw"
62.Ft void
63.Fn rw_runlock "struct rwlock *rw"
64.Ft void
65.Fn rw_wunlock "struct rwlock *rw"
66.Ft void
67.Fn rw_unlock "struct rwlock *rw"
68.Ft int
69.Fn rw_try_upgrade "struct rwlock *rw"
70.Ft void
71.Fn rw_downgrade "struct rwlock *rw"
72.Ft int
73.Fn rw_sleep "void *chan" "struct rwlock *rw" "int priority" "const char *wmesg" "int timo"
74.Ft int
75.Fn rw_initialized "struct rwlock *rw"
76.Ft int
77.Fn rw_wowned "struct rwlock *rw"
78.Pp
79.Cd "options INVARIANTS"
80.Cd "options INVARIANT_SUPPORT"
81.Ft void
82.Fn rw_assert "struct rwlock *rw" "int what"
83.In sys/kernel.h
84.Fn RW_SYSINIT "name" "struct rwlock *rw" "const char *desc"
85.Sh DESCRIPTION
86Reader/writer locks allow shared access to protected data by multiple threads,
87or exclusive access by a single thread.
88The threads with shared access are known as
89.Em readers
90since they only read the protected data.
91A thread with exclusive access is known as a
92.Em writer
93since it can modify protected data.
94.Pp
95Although reader/writer locks look very similar to
96.Xr sx 9
97locks, their usage pattern is different.
98Reader/writer locks can be treated as mutexes (see
99.Xr mutex 9 )
100with shared/exclusive semantics.
101Unlike
102.Xr sx 9 ,
103an
104.Nm
105can be locked while holding a non-spin mutex, and an
106.Nm
107cannot be held while sleeping.
108The
109.Nm
110locks have priority propagation like mutexes, but priority
111can be propagated only to an exclusive holder.
112This limitation comes from the fact that shared owners
113are anonymous.
114Another important property is that shared holders of
115.Nm
116can recurse,
117and exclusive locks can be made recursive selectively.
118.Ss Macros and Functions
119.Bl -tag -width indent
120.It Fn rw_init "struct rwlock *rw" "const char *name"
121Initialize structure located at
122.Fa rw
123as reader/writer lock, described by name
124.Fa name .
125The description is used solely for debugging purposes.
126This function must be called before any other operations
127on the lock.
128.It Fn rw_init_flags "struct rwlock *rw" "const char *name" "int opts"
129Initialize the rw lock just like the
130.Fn rw_init
131function, but specifying a set of optional flags to alter the
132behaviour of
133.Fa rw ,
134through the
135.Fa opts
136argument.
137It contains one or more of the following flags:
138.Bl -tag -width ".Dv RW_NOPROFILE"
139.It Dv RW_DUPOK
140Witness should not log messages about duplicate locks being acquired.
141.It Dv RW_NOPROFILE
142Do not profile this lock.
143.It Dv RW_NOWITNESS
144Instruct
145.Xr witness 4
146to ignore this lock.
147.It Dv RW_QUIET
148Do not log any operations for this lock via
149.Xr ktr 4 .
150.It Dv RW_RECURSE
151Allow threads to recursively acquire exclusive locks for
152.Fa rw .
153.El
154.It Fn rw_rlock "struct rwlock *rw"
155Lock
156.Fa rw
157as a reader.
158If any thread holds this lock exclusively, the current thread blocks,
159and its priority is propagated to the exclusive holder.
160The
161.Fn rw_rlock
162function can be called when the thread has already acquired reader
163access on
164.Fa rw .
165This is called
166.Dq "recursing on a lock" .
167.It Fn rw_wlock "struct rwlock *rw"
168Lock
169.Fa rw
170as a writer.
171If there are any shared owners of the lock, the current thread blocks.
172The
173.Fn rw_wlock
174function can be called recursively only if
175.Fa rw
176has been initialized with the
177.Dv RW_RECURSE
178option enabled.
179.It Fn rw_runlock "struct rwlock *rw"
180This function releases a shared lock previously acquired by
181.Fn rw_rlock .
182.It Fn rw_wunlock "struct rwlock *rw"
183This function releases an exclusive lock previously acquired by
184.Fn rw_wlock .
185.It Fn rw_unlock "struct rwlock *rw"
186This function releases a shared lock previously acquired by
187.Fn rw_rlock
188or an exclusive lock previously acquired by
189.Fn rw_wlock .
190.It Fn rw_try_upgrade "struct rwlock *rw"
191Attempt to upgrade a single shared lock to an exclusive lock.
192The current thread must hold a shared lock of
193.Fa rw .
194This will only succeed if the current thread holds the only shared lock on
195.Fa rw ,
196and it only holds a single shared lock.
197If the attempt succeeds
198.Fn rw_try_upgrade
199will return a non-zero value,
200and the current thread will hold an exclusive lock.
201If the attempt fails
202.Fn rw_try_upgrade
203will return zero,
204and the current thread will still hold a shared lock.
205.It Fn rw_downgrade "struct rwlock *rw"
206Convert an exclusive lock into a single shared lock.
207The current thread must hold an exclusive lock of
208.Fa rw .
209.It Fn rw_sleep "void *chan" "struct rwlock *rw" "int priority" "const char *wmesg" "int timo"
210Atomically release
211.Fa rw
212while waiting for an event.
213For more details on the parameters to this function,
214see
215.Xr sleep 9 .
216.It Fn rw_initialized "struct rwlock *rw"
217This function returns non-zero if
218.Fa rw
219has been initialized, and zero otherwise.
220.It Fn rw_destroy "struct rwlock *rw"
221This functions destroys a lock previously initialized with
222.Fn rw_init .
223The
224.Fa rw
225lock must be unlocked.
226.It Fn rw_wowned "struct rwlock *rw"
227This function returns a non-zero value if the current thread owns an
228exclusive lock on
229.Fa rw .
230.It Fn rw_assert "struct rwlock *rw" "int what"
231This function allows assertions specified in
232.Fa what
233to be made about
234.Fa rw .
235If the assertions are not true and the kernel is compiled
236with
237.Cd "options INVARIANTS"
238and
239.Cd "options INVARIANT_SUPPORT" ,
240the kernel will panic.
241Currently the following assertions are supported:
242.Bl -tag -width ".Dv RA_UNLOCKED"
243.It Dv RA_LOCKED
244Assert that current thread holds either a shared or exclusive lock
245of
246.Fa rw .
247.It Dv RA_RLOCKED
248Assert that current thread holds a shared lock of
249.Fa rw .
250.It Dv RA_WLOCKED
251Assert that current thread holds an exclusive lock of
252.Fa rw .
253.It Dv RA_UNLOCKED
254Assert that current thread holds neither a shared nor exclusive lock of
255.Fa rw .
256.El
257.El
258.Sh SEE ALSO
259.Xr locking 9 ,
260.Xr mutex 9 ,
261.Xr panic 9 ,
262.Xr sema 9 ,
263.Xr sx 9
264.Sh HISTORY
265These
266functions appeared in
267.Fx 7.0 .
268.Sh AUTHORS
269.An -nosplit
270The
271.Nm
272facility was written by
273.An "John Baldwin" .
274This manual page was written by
275.An "Gleb Smirnoff" .
276.Sh BUGS
277If
278.Dv WITNESS
279is not included in the kernel,
280then it is impossible to assert that the current thread does or does not
281hold a read lock.
282In the
283.Pf non- Dv WITNESS
284case, the
285.Dv RA_LOCKED
286and
287.Dv RA_RLOCKED
288assertions merely check that some thread holds a read lock.
289.Pp
290Reader/writer is a bit of an awkward name.
291An
292.Nm
293can also be called a
294.Dq Robert Watson
295lock if desired.
296