xref: /freebsd/share/man/man9/rmlock.9 (revision 8403b19372043b43879b38a3273c859aaf21bdaa)
1f53d15feSStephan Uphoff.\" Copyright (c) 2007 Stephan Uphoff <ups@FreeBSD.org>
2f53d15feSStephan Uphoff.\" Copyright (c) 2006 Gleb Smirnoff <glebius@FreeBSD.org>
3f53d15feSStephan Uphoff.\" All rights reserved.
4f53d15feSStephan Uphoff.\"
5f53d15feSStephan Uphoff.\" Redistribution and use in source and binary forms, with or without
6f53d15feSStephan Uphoff.\" modification, are permitted provided that the following conditions
7f53d15feSStephan Uphoff.\" are met:
8f53d15feSStephan Uphoff.\" 1. Redistributions of source code must retain the above copyright
9f53d15feSStephan Uphoff.\"    notice, this list of conditions and the following disclaimer.
10f53d15feSStephan Uphoff.\" 2. Redistributions in binary form must reproduce the above copyright
11f53d15feSStephan Uphoff.\"    notice, this list of conditions and the following disclaimer in the
12f53d15feSStephan Uphoff.\"    documentation and/or other materials provided with the distribution.
13f53d15feSStephan Uphoff.\"
14f53d15feSStephan Uphoff.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
15f53d15feSStephan Uphoff.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
16f53d15feSStephan Uphoff.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17f53d15feSStephan Uphoff.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
18f53d15feSStephan Uphoff.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
19f53d15feSStephan Uphoff.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
20f53d15feSStephan Uphoff.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
21f53d15feSStephan Uphoff.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
22f53d15feSStephan Uphoff.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
23f53d15feSStephan Uphoff.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
24f53d15feSStephan Uphoff.\" SUCH DAMAGE.
25f53d15feSStephan Uphoff.\"
26f53d15feSStephan Uphoff.\" $FreeBSD$
27f53d15feSStephan Uphoff.\"
28f53d15feSStephan Uphoff.\" Based on rwlock.9 man page
29*8403b193SJohn Baldwin.Dd June 8, 2012
30f53d15feSStephan Uphoff.Dt RMLOCK 9
31f53d15feSStephan Uphoff.Os
32f53d15feSStephan Uphoff.Sh NAME
33f53d15feSStephan Uphoff.Nm rmlock ,
34f53d15feSStephan Uphoff.Nm rm_init ,
351a109c1cSRobert Watson.Nm rm_init_flags ,
36f53d15feSStephan Uphoff.Nm rm_destroy ,
37f53d15feSStephan Uphoff.Nm rm_rlock ,
3836058c09SMax Laier.Nm rm_try_rlock ,
39f53d15feSStephan Uphoff.Nm rm_wlock ,
40f53d15feSStephan Uphoff.Nm rm_runlock ,
41f53d15feSStephan Uphoff.Nm rm_wunlock ,
42433ea89aSRobert Watson.Nm rm_wowned ,
43f53d15feSStephan Uphoff.Nm RM_SYSINIT
44*8403b193SJohn Baldwin.Nd kernel reader/writer lock optimized for read-mostly access patterns
45f53d15feSStephan Uphoff.Sh SYNOPSIS
46f53d15feSStephan Uphoff.In sys/param.h
47f53d15feSStephan Uphoff.In sys/lock.h
48f53d15feSStephan Uphoff.In sys/rmlock.h
49f53d15feSStephan Uphoff.Ft void
501a109c1cSRobert Watson.Fn rm_init "struct rmlock *rm" "const char *name"
511a109c1cSRobert Watson.Ft void
521a109c1cSRobert Watson.Fn rm_init_flags "struct rmlock *rm" "const char *name" "int opts"
53f53d15feSStephan Uphoff.Ft void
54f53d15feSStephan Uphoff.Fn rm_destroy "struct rmlock *rm"
55f53d15feSStephan Uphoff.Ft void
56f53d15feSStephan Uphoff.Fn rm_rlock "struct rmlock *rm"  "struct rm_priotracker* tracker"
5736058c09SMax Laier.Ft int
5836058c09SMax Laier.Fn rm_try_rlock "struct rmlock *rm"  "struct rm_priotracker* tracker"
59f53d15feSStephan Uphoff.Ft void
60f53d15feSStephan Uphoff.Fn rm_wlock "struct rmlock *rm"
61f53d15feSStephan Uphoff.Ft void
62f53d15feSStephan Uphoff.Fn rm_runlock "struct rmlock *rm" "struct rm_priotracker* tracker"
63f53d15feSStephan Uphoff.Ft void
64f53d15feSStephan Uphoff.Fn rm_wunlock "struct rmlock *rm"
65433ea89aSRobert Watson.Ft int
66d576deedSPawel Jakub Dawidek.Fn rm_wowned "const struct rmlock *rm"
67f53d15feSStephan Uphoff.In sys/kernel.h
68f53d15feSStephan Uphoff.Fn RM_SYSINIT "name" "struct rmlock *rm" "const char *desc" "int opts"
69f53d15feSStephan Uphoff.Sh DESCRIPTION
70*8403b193SJohn BaldwinRead-mostly locks allow shared access to protected data by multiple threads,
71f53d15feSStephan Uphoffor exclusive access by a single thread.
72f53d15feSStephan UphoffThe threads with shared access are known as
73f53d15feSStephan Uphoff.Em readers
74f53d15feSStephan Uphoffsince they only read the protected data.
75f53d15feSStephan UphoffA thread with exclusive access is known as a
76f53d15feSStephan Uphoff.Em writer
77f53d15feSStephan Uphoffsince it can modify protected data.
78f53d15feSStephan Uphoff.Pp
79*8403b193SJohn BaldwinRead-mostly locks are designed to be efficient for locks almost exclusively
80989cbe40SHiten Pandyaused as reader locks and as such should be used for protecting data that
81989cbe40SHiten Pandyararely changes.
82*8403b193SJohn BaldwinAcquiring an exclusive lock after the lock has been locked for shared access
83989cbe40SHiten Pandyais an expensive operation.
84f53d15feSStephan Uphoff.Pp
85*8403b193SJohn BaldwinNormal read-mostly locks are similar to
86*8403b193SJohn Baldwin.Xr rwlock 9
87*8403b193SJohn Baldwinlocks and follow the same lock ordering rules as
88*8403b193SJohn Baldwin.Xr rwlock 9
89*8403b193SJohn Baldwinlocks.
90*8403b193SJohn BaldwinRead-mostly locks have full priority propagation like mutexes.
91f53d15feSStephan UphoffUnlike
92*8403b193SJohn Baldwin.Xr rwlock 9 ,
93*8403b193SJohn Baldwinread-mostly locks propagate priority to both readers and writers.
94*8403b193SJohn BaldwinThis is implemented via the
95989cbe40SHiten Pandya.Va rm_priotracker
96*8403b193SJohn Baldwinstructure argument supplied to
97989cbe40SHiten Pandya.Fn rm_rlock
98989cbe40SHiten Pandyaand
99*8403b193SJohn Baldwin.Fn rm_runlock .
100*8403b193SJohn BaldwinReaders can recurse if the lock is initialized with the
101*8403b193SJohn Baldwin.Dv RM_RECURSE
102*8403b193SJohn Baldwinoption;
103*8403b193SJohn Baldwinhowever, writers are never allowed to recurse.
104*8403b193SJohn Baldwin.Pp
105*8403b193SJohn BaldwinSleepable read-mostly locks are created by passing
106*8403b193SJohn Baldwin.Dv RM_SLEEPABLE
107*8403b193SJohn Baldwinto
108*8403b193SJohn Baldwin.Fn rm_init_flags .
109*8403b193SJohn BaldwinUnlike normal read-mostly locks,
110*8403b193SJohn Baldwinsleepable read-mostly locks follow the same lock ordering rules as
111*8403b193SJohn Baldwin.Xr sx 9
112*8403b193SJohn Baldwinlocks.
113*8403b193SJohn BaldwinSleepable read-mostly locks do not propagate priority to writers,
114*8403b193SJohn Baldwinbut they do propagate priority to readers.
115*8403b193SJohn BaldwinWriters are permitted to sleep while holding a read-mostly lock,
116*8403b193SJohn Baldwinbut readers are not.
117*8403b193SJohn BaldwinUnlike other sleepable locks such as
118*8403b193SJohn Baldwin.Xr sx 9
119*8403b193SJohn Baldwinlocks,
120*8403b193SJohn Baldwinreaders must use try operations on other sleepable locks to avoid sleeping.
121f53d15feSStephan Uphoff.Ss Macros and Functions
122f53d15feSStephan Uphoff.Bl -tag -width indent
1231a109c1cSRobert Watson.It Fn rm_init "struct rmlock *rm" "const char *name"
124*8403b193SJohn BaldwinInitialize the read-mostly lock
125*8403b193SJohn Baldwin.Fa rm .
126*8403b193SJohn BaldwinThe
127*8403b193SJohn Baldwin.Fa name
128*8403b193SJohn Baldwindescription is used solely for debugging purposes.
129f53d15feSStephan UphoffThis function must be called before any other operations
130f53d15feSStephan Uphoffon the lock.
1311a109c1cSRobert Watson.It Fn rm_init_flags "struct rmlock *rm" "const char *name" "int opts"
132*8403b193SJohn BaldwinSimilar to
133*8403b193SJohn Baldwin.Fn rm_init ,
134*8403b193SJohn Baldwininitialize the read-mostly lock
135*8403b193SJohn Baldwin.Fa rm
136*8403b193SJohn Baldwinwith a set of optional flags.
137*8403b193SJohn BaldwinThe
1381a109c1cSRobert Watson.Fa opts
139*8403b193SJohn Baldwinarguments contains one or more of the following flags:
1401a109c1cSRobert Watson.Bl -tag -width ".Dv RM_NOWITNESS"
1411a109c1cSRobert Watson.It Dv RM_NOWITNESS
1421a109c1cSRobert WatsonInstruct
1431a109c1cSRobert Watson.Xr witness 4
1441a109c1cSRobert Watsonto ignore this lock.
1451a109c1cSRobert Watson.It Dv RM_RECURSE
146*8403b193SJohn BaldwinAllow threads to recursively acquire shared locks for
1471a109c1cSRobert Watson.Fa rm .
14836058c09SMax Laier.It Dv RM_SLEEPABLE
149*8403b193SJohn BaldwinCreate a sleepable read-mostly lock.
1501a109c1cSRobert Watson.El
151f53d15feSStephan Uphoff.It Fn rm_rlock "struct rmlock *rm" "struct rm_priotracker* tracker"
152f53d15feSStephan UphoffLock
153f53d15feSStephan Uphoff.Fa rm
154*8403b193SJohn Baldwinas a reader using
155f53d15feSStephan Uphoff.Fa tracker
156f53d15feSStephan Uphoffto track read owners of a lock for priority propagation.
157989cbe40SHiten PandyaThis data structure is only used internally by
158989cbe40SHiten Pandya.Nm
159c6d7cf7bSChristian Bruefferand must persist until
160c6d7cf7bSChristian Brueffer.Fn rm_runlock
161c6d7cf7bSChristian Bruefferhas been called.
162989cbe40SHiten PandyaThis data structure can be allocated on the stack since
163*8403b193SJohn Baldwinreaders cannot sleep.
164f53d15feSStephan UphoffIf any thread holds this lock exclusively, the current thread blocks,
165f53d15feSStephan Uphoffand its priority is propagated to the exclusive holder.
166989cbe40SHiten PandyaIf the lock was initialized with the
167*8403b193SJohn Baldwin.Dv RM_RECURSE
168989cbe40SHiten Pandyaoption the
169f53d15feSStephan Uphoff.Fn rm_rlock
170*8403b193SJohn Baldwinfunction can be called when the current thread has already acquired reader
171f53d15feSStephan Uphoffaccess on
172f53d15feSStephan Uphoff.Fa rm .
17336058c09SMax Laier.It Fn rm_try_rlock "struct rmlock *rm" "struct rm_priotracker* tracker"
17436058c09SMax LaierTry to lock
17536058c09SMax Laier.Fa rm
17636058c09SMax Laieras a reader.
17736058c09SMax Laier.Fn rm_try_rlock
17836058c09SMax Laierwill return 0 if the lock cannot be acquired immediately;
179*8403b193SJohn Baldwinotherwise,
180*8403b193SJohn Baldwinthe lock will be acquired and a non-zero value will be returned.
18136058c09SMax LaierNote that
18236058c09SMax Laier.Fn rm_try_rlock
18336058c09SMax Laiermay fail even while the lock is not currently held by a writer.
184*8403b193SJohn BaldwinIf the lock was initialized with the
185*8403b193SJohn Baldwin.Dv RM_RECURSE
186*8403b193SJohn Baldwinoption,
187*8403b193SJohn Baldwin.Fn rm_try_rlock
188*8403b193SJohn Baldwinwill succeed if the current thread has already acquired reader access.
189f53d15feSStephan Uphoff.It Fn rm_wlock "struct rmlock *rm"
190f53d15feSStephan UphoffLock
191f53d15feSStephan Uphoff.Fa rm
192f53d15feSStephan Uphoffas a writer.
193f53d15feSStephan UphoffIf there are any shared owners of the lock, the current thread blocks.
194f53d15feSStephan UphoffThe
195f53d15feSStephan Uphoff.Fn rm_wlock
196f53d15feSStephan Uphofffunction cannot be called recursively.
197f53d15feSStephan Uphoff.It Fn rm_runlock "struct rmlock *rm" "struct rm_priotracker* tracker"
198f53d15feSStephan UphoffThis function releases a shared lock previously acquired by
199f53d15feSStephan Uphoff.Fn rm_rlock .
200f53d15feSStephan UphoffThe
201f53d15feSStephan Uphoff.Fa tracker
202f53d15feSStephan Uphoffargument must match the
203f53d15feSStephan Uphoff.Fa tracker
204f53d15feSStephan Uphoffargument used for acquiring the shared lock
205f53d15feSStephan Uphoff.It Fn rm_wunlock "struct rmlock *rm"
206f53d15feSStephan UphoffThis function releases an exclusive lock previously acquired by
207f53d15feSStephan Uphoff.Fn rm_wlock .
208f53d15feSStephan Uphoff.It Fn rm_destroy "struct rmlock *rm"
209f53d15feSStephan UphoffThis functions destroys a lock previously initialized with
210f53d15feSStephan Uphoff.Fn rm_init .
211f53d15feSStephan UphoffThe
212f53d15feSStephan Uphoff.Fa rm
213f53d15feSStephan Uphofflock must be unlocked.
214d576deedSPawel Jakub Dawidek.It Fn rm_wowned "const struct rmlock *rm"
215433ea89aSRobert WatsonThis function returns a non-zero value if the current thread owns an
216433ea89aSRobert Watsonexclusive lock on
217433ea89aSRobert Watson.Fa rm .
218f53d15feSStephan Uphoff.El
219f53d15feSStephan Uphoff.Sh SEE ALSO
220f53d15feSStephan Uphoff.Xr locking 9 ,
221f53d15feSStephan Uphoff.Xr mutex 9 ,
222f53d15feSStephan Uphoff.Xr panic 9 ,
223f53d15feSStephan Uphoff.Xr rwlock 9 ,
224f53d15feSStephan Uphoff.Xr sema 9 ,
225f53d15feSStephan Uphoff.Xr sx 9
226f53d15feSStephan Uphoff.Sh HISTORY
227f53d15feSStephan UphoffThese
228f53d15feSStephan Uphofffunctions appeared in
229f53d15feSStephan Uphoff.Fx 7.0 .
230f53d15feSStephan Uphoff.Sh AUTHORS
231f53d15feSStephan Uphoff.An -nosplit
232f53d15feSStephan UphoffThe
233f53d15feSStephan Uphoff.Nm
234f53d15feSStephan Uphofffacility was written by
235f53d15feSStephan Uphoff.An "Stephan Uphoff" .
236f53d15feSStephan UphoffThis manual page was written by
237f53d15feSStephan Uphoff.An "Gleb Smirnoff"
238989cbe40SHiten Pandyafor rwlock and modified to reflect rmlock by
239f53d15feSStephan Uphoff.An "Stephan Uphoff" .
240f53d15feSStephan Uphoff.Sh BUGS
241989cbe40SHiten PandyaThe
242989cbe40SHiten Pandya.Nm
243989cbe40SHiten Pandyaimplementation is currently not optimized for single processor systems.
244989cbe40SHiten Pandya.Pp
24536058c09SMax Laier.Fn rm_try_rlock
24636058c09SMax Laiercan fail transiently even when there is no writer, while another reader
24736058c09SMax Laierupdates the state on the local CPU.
24836058c09SMax Laier.Pp
249989cbe40SHiten PandyaThe
250989cbe40SHiten Pandya.Nm
251c6d7cf7bSChristian Bruefferimplementation uses a single per CPU list shared by all
252989cbe40SHiten Pandyarmlocks in the system.
253c6d7cf7bSChristian BruefferIf rmlocks become popular, hashing to multiple per CPU queues may
254989cbe40SHiten Pandyabe needed to speed up the writer lock process.
255989cbe40SHiten Pandya.Pp
256989cbe40SHiten PandyaThe
257989cbe40SHiten Pandya.Nm
258989cbe40SHiten Pandyacan currently not be used as a lock argument for condition variable
259989cbe40SHiten Pandyawait functions.
260