xref: /freebsd/share/man/man9/rwlock.9 (revision 1e413cf93298b5b97441a21d9a50fdcd0ee9945e)
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 November 25, 2007
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_try_upgrade ,
40.Nm rw_downgrade ,
41.Nm rw_sleep ,
42.Nm rw_initialized ,
43.Nm rw_wowned ,
44.Nm rw_assert ,
45.Nm RW_SYSINIT
46.Nd kernel reader/writer lock
47.Sh SYNOPSIS
48.In sys/param.h
49.In sys/lock.h
50.In sys/rwlock.h
51.Ft void
52.Fn rw_init "struct rwlock *rw" "const char *name"
53.Ft void
54.Fn rw_init_flags "struct rwlock *rw" "const char *name" "int opts"
55.Ft void
56.Fn rw_destroy "struct rwlock *rw"
57.Ft void
58.Fn rw_rlock "struct rwlock *rw"
59.Ft void
60.Fn rw_wlock "struct rwlock *rw"
61.Ft void
62.Fn rw_runlock "struct rwlock *rw"
63.Ft void
64.Fn rw_wunlock "struct rwlock *rw"
65.Ft int
66.Fn rw_try_upgrade "struct rwlock *rw"
67.Ft void
68.Fn rw_downgrade "struct rwlock *rw"
69.Ft int
70.Fn rw_sleep "void *chan" "struct rwlock *rw" "int priority" "const char *wmesg" "int timo"
71.Ft int
72.Fn rw_initialized "struct rwlock *rw"
73.Ft int
74.Fn rw_wowned "struct rwlock *rw"
75.Pp
76.Cd "options INVARIANTS"
77.Cd "options INVARIANT_SUPPORT"
78.Ft void
79.Fn rw_assert "struct rwlock *rw" "int what"
80.In sys/kernel.h
81.Fn RW_SYSINIT "name" "struct rwlock *rw" "const char *desc"
82.Sh DESCRIPTION
83Reader/writer locks allow shared access to protected data by multiple threads,
84or exclusive access by a single thread.
85The threads with shared access are known as
86.Em readers
87since they only read the protected data.
88A thread with exclusive access is known as a
89.Em writer
90since it can modify protected data.
91.Pp
92Although reader/writer locks look very similar to
93.Xr sx 9
94locks, their usage pattern is different.
95Reader/writer locks can be treated as mutexes (see
96.Xr mutex 9 )
97with shared/exclusive semantics.
98Unlike
99.Xr sx 9 ,
100an
101.Nm
102can be locked while holding a non-spin mutex, and an
103.Nm
104cannot be held while sleeping.
105The
106.Nm
107locks have priority propagation like mutexes, but priority
108can be propagated only to an exclusive holder.
109This limitation comes from the fact that shared owners
110are anonymous.
111Another important property is that shared holders of
112.Nm
113can recurse,
114and exclusive locks can be made recursive selectively.
115.Ss Macros and Functions
116.Bl -tag -width indent
117.It Fn rw_init "struct rwlock *rw" "const char *name"
118Initialize structure located at
119.Fa rw
120as reader/writer lock, described by name
121.Fa name .
122The description is used solely for debugging purposes.
123This function must be called before any other operations
124on the lock.
125.It Fn rw_init_flags "struct rwlock *rw" "const char *name" "int opts"
126Initialize the rw lock just like the
127.Fn rw_init
128function, but specifying a set of optional flags to alter the
129behaviour of
130.Fa rw ,
131through the
132.Fa opts
133argument.
134It contains one or more of the following flags:
135.Bl -tag -width ".Dv RW_NOPROFILE"
136.It Dv RW_DUPOK
137Witness should not log messages about duplicate locks being acquired.
138.It Dv RW_NOPROFILE
139Do not profile this lock.
140.It Dv RW_NOWITNESS
141Instruct
142.Xr witness 4
143to ignore this lock.
144.It Dv RW_QUIET
145Do not log any operations for this lock via
146.Xr ktr 4 .
147.It Dv RW_RECURSE
148Allow threads to recursively acquire exclusive locks for
149.Fa rw .
150.It Fn rw_rlock "struct rwlock *rw"
151Lock
152.Fa rw
153as a reader.
154If any thread holds this lock exclusively, the current thread blocks,
155and its priority is propagated to the exclusive holder.
156The
157.Fn rw_rlock
158function can be called when the thread has already acquired reader
159access on
160.Fa rw .
161This is called
162.Dq "recursing on a lock" .
163.It Fn rw_wlock "struct rwlock *rw"
164Lock
165.Fa rw
166as a writer.
167If there are any shared owners of the lock, the current thread blocks.
168The
169.Fn rw_wlock
170function can be called recursively only if
171.Fa rw
172has been initialized with the
173.Dv RW_RECURSE
174option enabled.
175.It Fn rw_runlock "struct rwlock *rw"
176This function releases a shared lock previously acquired by
177.Fn rw_rlock .
178.It Fn rw_wunlock "struct rwlock *rw"
179This function releases an exclusive lock previously acquired by
180.Fn rw_wlock .
181.It Fn rw_try_upgrade "struct rwlock *rw"
182Attempt to upgrade a single shared lock to an exclusive lock.
183The current thread must hold a shared lock of
184.Fa rw .
185This will only succeed if the current thread holds the only shared lock on
186.Fa rw ,
187and it only holds a single shared lock.
188If the attempt succeeds
189.Fn rw_try_upgrade
190will return a non-zero value,
191and the current thread will hold an exclusive lock.
192If the attempt fails
193.Fn rw_try_upgrade
194will return zero,
195and the current thread will still hold a shared lock.
196.It Fn rw_downgrade "struct rwlock *rw"
197Convert an exclusive lock into a single shared lock.
198The current thread must hold an exclusive lock of
199.Fa rw .
200.It Fn rw_sleep "void *chan" "struct rwlock *rw" "int priority" "const char *wmesg" "int timo"
201Atomically release
202.Fa rw
203while waiting for an event.
204For more details on the parameters to this function,
205see
206.Xr sleep 9 .
207.It Fn rw_initialized "struct rwlock *rw"
208This function returns non-zero if
209.Fa rw
210has been initialized, and zero otherwise.
211.It Fn rw_destroy "struct rwlock *rw"
212This functions destroys a lock previously initialized with
213.Fn rw_init .
214The
215.Fa rw
216lock must be unlocked.
217.It Fn rw_wowned "struct rwlock *rw"
218This function returns a non-zero value if the current thread owns an
219exclusive lock on
220.Fa rw .
221.It Fn rw_assert "struct rwlock *rw" "int what"
222This function allows assertions specified in
223.Fa what
224to be made about
225.Fa rw .
226If the assertions are not true and the kernel is compiled
227with
228.Cd "options INVARIANTS"
229and
230.Cd "options INVARIANT_SUPPORT" ,
231the kernel will panic.
232Currently the following assertions are supported:
233.Bl -tag -width ".Dv RA_UNLOCKED"
234.It Dv RA_LOCKED
235Assert that current thread holds either a shared or exclusive lock
236of
237.Fa rw .
238.It Dv RA_RLOCKED
239Assert that current thread holds a shared lock of
240.Fa rw .
241.It Dv RA_WLOCKED
242Assert that current thread holds an exclusive lock of
243.Fa rw .
244.It Dv RA_UNLOCKED
245Assert that current thread holds neither a shared nor exclusive lock of
246.Fa rw .
247.El
248.El
249.Sh SEE ALSO
250.Xr locking 9 ,
251.Xr mutex 9 ,
252.Xr panic 9 ,
253.Xr sema 9 ,
254.Xr sx 9
255.Sh HISTORY
256These
257functions appeared in
258.Fx 7.0 .
259.Sh AUTHORS
260.An -nosplit
261The
262.Nm
263facility was written by
264.An "John Baldwin" .
265This manual page was written by
266.An "Gleb Smirnoff" .
267.Sh BUGS
268If
269.Dv WITNESS
270is not included in the kernel,
271then it is impossible to assert that the current thread does or does not
272hold a read lock.
273In the
274.Pf non- Dv WITNESS
275case, the
276.Dv RA_LOCKED
277and
278.Dv RA_RLOCKED
279assertions merely check that some thread holds a read lock.
280.Pp
281Reader/writer is a bit of an awkward name.
282An
283.Nm
284can also be called a
285.Dq Robert Watson
286lock if desired.
287