xref: /openbsd-src/share/man/man9/rwlock.9 (revision 380dd543fe7cbd445d86181a8d918352d3127e9e)
1.\" $OpenBSD: rwlock.9,v 1.27 2025/01/29 15:10:35 mpi Exp $
2.\"
3.\" Copyright (c) 2006 Pedro Martelletto <pedro@ambientworks.net>
4.\" All rights reserved.
5.\"
6.\" Permission to use, copy, modify, and distribute this software for any
7.\" purpose with or without fee is hereby granted, provided that the above
8.\" copyright notice and this permission notice appear in all copies.
9.\"
10.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17.\"
18.Dd $Mdocdate: January 29 2025 $
19.Dt RWLOCK 9
20.Os
21.Sh NAME
22.Nm rwlock ,
23.Nm rw_init ,
24.Nm rw_init_flags ,
25.Nm rw_enter ,
26.Nm rw_exit ,
27.Nm rw_enter_read ,
28.Nm rw_enter_write ,
29.Nm rw_exit_read ,
30.Nm rw_exit_write ,
31.Nm rw_assert_wrlock ,
32.Nm rw_assert_rdlock ,
33.Nm rw_assert_anylock ,
34.Nm rw_assert_unlocked ,
35.Nm rw_status ,
36.Nm RWLOCK_INITIALIZER ,
37.Nm rrw_init ,
38.Nm rrw_init_flags ,
39.Nm rrw_enter ,
40.Nm rrw_exit ,
41.Nm rrw_status
42.Nd interface to read/write locks
43.Sh SYNOPSIS
44.In sys/rwlock.h
45.Ft void
46.Fn rw_init "struct rwlock *rwl" "const char *name"
47.Ft void
48.Fn rw_init_flags "struct rwlock *rwl" "const char *name" "int flags"
49.Ft int
50.Fn rw_enter "struct rwlock *rwl" "int flags"
51.Ft void
52.Fn rw_exit "struct rwlock *rwl"
53.Ft void
54.Fn rw_enter_read "struct rwlock *rwl"
55.Ft void
56.Fn rw_enter_write "struct rwlock *rwl"
57.Ft void
58.Fn rw_exit_read "struct rwlock *rwl"
59.Ft void
60.Fn rw_exit_write "struct rwlock *rwl"
61.Ft void
62.Fn rw_assert_wrlock "struct rwlock *rwl"
63.Ft void
64.Fn rw_assert_rdlock "struct rwlock *rwl"
65.Ft void
66.Fn rw_assert_anylock "struct rwlock *rwl"
67.Ft void
68.Fn rw_assert_unlocked "struct rwlock *rwl"
69.Ft int
70.Fn rw_status "struct rwlock *rwl"
71.Fn RWLOCK_INITIALIZER "const char *name"
72.Ft void
73.Fn rrw_init "struct rrwlock *rrwl" "const char *name"
74.Ft void
75.Fn rrw_init_flags "struct rrwlock *rrwl" "const char *name" "int flags"
76.Ft int
77.Fn rrw_enter "struct rrwlock *rrwl" "int flags"
78.Ft void
79.Fn rrw_exit "struct rrwlock *rrwl"
80.Ft int
81.Fn rrw_status "struct rrwlock *rrwl"
82.Sh DESCRIPTION
83The
84.Nm
85set of functions provides a multiple-reader, single-writer locking mechanism to
86ensure mutual exclusion between different threads.
87.Pp
88Read locks can be acquired while the write lock is not held, and may coexist in
89distinct threads at any time.
90A write lock, however, can only be acquired when there are no read locks held,
91granting exclusive access to a single thread.
92.Pp
93The
94.Fn rw_init
95function is used to initiate the lock pointed to by
96.Fa rwl .
97The
98.Fa name
99argument specifies the name of the lock, which is used as the wait message
100if the thread needs to sleep.
101.Pp
102The
103.Fn rw_init_flags
104macro is similar to
105.Fn rw_init ,
106but it additionally accepts a bitwise OR of the following flags:
107.Bl -tag -width RWL_NOWITNESS -offset indent
108.It Dv RWL_DUPOK
109Prevents
110.Xr witness 4
111from logging when a thread acquires more than one lock of this lock type.
112.It Dv RWL_IS_VNODE
113Make
114.Xr witness 4
115ignore lock order issues between this lock type and any other lock type
116tagged with the
117.Dv RWL_IS_VNODE
118flag.
119.It Dv RWL_NOWITNESS
120Instructs
121.Xr witness 4
122to ignore this lock.
123.El
124.Pp
125The
126.Fn rw_enter
127function acquires a lock.
128The
129.Fa flags
130argument specifies what kind of lock should be obtained and also
131modifies the operation.
132The possible flags are:
133.Pp
134.Bl -tag -offset indent -width RW_DOWNGRADEXXX -compact
135.It Dv RW_READ
136Acquire a shared lock.
137.It Dv RW_WRITE
138Acquire an exclusive lock.
139.It Dv RW_DOWNGRADE
140Safely release an exclusive lock and acquire a shared lock without
141letting other exclusive locks in between.
142.It Dv RW_UPGRADE
143Upgrade a shared lock into an exclusive one.
144Must be combined with
145.Dv RW_NOSLEEP .
146.It Dv RW_INTR
147When waiting for a lock, allow signals to interrupt the sleep.
148.It Dv RW_NOSLEEP
149Do not wait for busy locks, fail with
150.Dv EBUSY
151instead.
152.It Dv RW_SLEEPFAIL
153Wait for busy locks, but do not obtain them, fail with
154.Dv EAGAIN
155instead.
156.It Dv RW_DUPOK
157Prevents
158.Xr witness 4 ,
159for just this
160.Fn rw_enter ,
161from logging when this thread already has a lock of this lock type.
162.El
163.Pp
164The
165.Fn rw_exit
166function is used to release a held lock.
167.Pp
168The
169.Fn rw_enter_read
170function acquires a read lock, sleeping if necessary.
171.Pp
172The
173.Fn rw_enter_write
174function acquires a write lock, sleeping if necessary.
175.Pp
176The
177.Fn rw_exit_read
178function releases a read lock.
179.Pp
180The
181.Fn rw_exit_write
182function releases a write lock.
183.Pp
184The
185.Fn rw_assert_wrlock ,
186.Fn rw_assert_rdlock ,
187.Fn rw_assert_anylock ,
188and
189.Fn rw_assert_unlocked
190functions check the status
191.Fa rwl ,
192panicking if it is not write-, read-, any-, or unlocked, respectively.
193.Pp
194.Nm rw_status
195returns the current state of the lock.
196.Pp
197A lock declaration may be initialised with the
198.Fn RWLOCK_INITIALIZER
199macro.
200The
201.Fa name
202argument specifies the name of the lock, which is used as the wait message
203if the thread needs to sleep.
204.Pp
205The
206.Nm rrwlock
207functions support recursive write locking by the same process.
208They otherwise behave the same as their rwlock counterparts.
209.Sh CONTEXT
210.Fn rw_init ,
211.Fn rw_init_flags ,
212.Fn rrw_init
213and
214.Fn rrw_init_flags
215can be called during autoconf, from process context, or from interrupt context.
216.Pp
217All other functions can be called during autoconf or from process context.
218.Sh RETURN VALUES
219.Nm rw_enter
220and
221.Nm rrw_enter
222return 0 on success, or an
223.Xr errno 2
224style value on failure.
225.Pp
226.Nm rw_status
227and
228.Nm rrw_status
229return the state of the lock:
230.Pp
231.Bl -tag -width "RW_WRITE_OTHER" -offset indent -compact
232.It Dv RW_WRITE
233Lock is write locked by the calling thread.
234.It Dv RW_WRITE_OTHER
235Lock is write locked by a different thread.
236.It Dv RW_READ
237Lock is read locked.
238The current thread may be one of the threads that has it locked.
239.It 0
240Lock is not locked.
241.El
242.Sh SEE ALSO
243.Xr witness 4 ,
244.Xr mutex 9 ,
245.Xr rwsleep 9 ,
246.Xr spl 9
247.Sh HISTORY
248The
249.Nm
250functions first appeared in
251.Ox 3.5 .
252.Sh AUTHORS
253The
254.Nm
255functions were written by
256.An Artur Grabowski Aq Mt art@openbsd.org .
257