xref: /freebsd/share/man/man9/rmlock.9 (revision d576deedb549253edd7dab4f594a77d52a98dc5f)
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*d576deedSPawel Jakub Dawidek.Dd November 16, 2011
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
44c6d7cf7bSChristian Brueffer.Nd kernel reader/writer lock optimized for mostly read 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
66*d576deedSPawel 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
70f53d15feSStephan UphoffMostly reader 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
79989cbe40SHiten PandyaRead 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.
82989cbe40SHiten PandyaAcquiring an exclusive lock after the lock had been locked for shared access
83989cbe40SHiten Pandyais an expensive operation.
84f53d15feSStephan Uphoff.Pp
85f53d15feSStephan UphoffAlthough reader/writer locks look very similar to
86f53d15feSStephan Uphoff.Xr sx 9
87f53d15feSStephan Uphofflocks, their usage pattern is different.
88f53d15feSStephan UphoffReader/writer locks can be treated as mutexes (see
89f53d15feSStephan Uphoff.Xr mutex 9 )
9036058c09SMax Laierwith shared/exclusive semantics unless initialized with
9136058c09SMax Laier.Dv RM_SLEEPABLE .
92f53d15feSStephan UphoffUnlike
93f53d15feSStephan Uphoff.Xr sx 9 ,
94f53d15feSStephan Uphoffan
95f53d15feSStephan Uphoff.Nm
96f53d15feSStephan Uphoffcan be locked while holding a non-spin mutex, and an
97f53d15feSStephan Uphoff.Nm
9836058c09SMax Laiercannot be held while sleeping, again unless initialized with
9936058c09SMax Laier.Dv RM_SLEEPABLE .
100f53d15feSStephan UphoffThe
101f53d15feSStephan Uphoff.Nm
102c6d7cf7bSChristian Bruefferlocks have full priority propagation like mutexes.
103c6d7cf7bSChristian BruefferThe
104989cbe40SHiten Pandya.Va rm_priotracker
105989cbe40SHiten Pandyastructure argument supplied in
106989cbe40SHiten Pandya.Fn rm_rlock
107989cbe40SHiten Pandyaand
108989cbe40SHiten Pandya.Fn rm_runlock
109989cbe40SHiten Pandyais used to keep track of the read owner(s).
110f53d15feSStephan UphoffAnother important property is that shared holders of
111f53d15feSStephan Uphoff.Nm
112989cbe40SHiten Pandyacan recurse if the lock has been initialized with the
113989cbe40SHiten Pandya.Dv LO_RECURSABLE
114989cbe40SHiten Pandyaoption, however exclusive locks are not allowed to recurse.
115f53d15feSStephan Uphoff.Ss Macros and Functions
116f53d15feSStephan Uphoff.Bl -tag -width indent
1171a109c1cSRobert Watson.It Fn rm_init "struct rmlock *rm" "const char *name"
118f53d15feSStephan UphoffInitialize structure located at
119f53d15feSStephan Uphoff.Fa rm
120989cbe40SHiten Pandyaas mostly reader lock, described by
121f53d15feSStephan Uphoff.Fa name .
122f53d15feSStephan UphoffThe name description is used solely for debugging purposes.
123f53d15feSStephan UphoffThis function must be called before any other operations
124f53d15feSStephan Uphoffon the lock.
1251a109c1cSRobert Watson.It Fn rm_init_flags "struct rmlock *rm" "const char *name" "int opts"
1261a109c1cSRobert WatsonInitialize the rm lock just like the
1271a109c1cSRobert Watson.Fn rm_init
1281a109c1cSRobert Watsonfunction, but specifying a set of optional flags to alter the
1291a109c1cSRobert Watsonbehaviour of
1301a109c1cSRobert Watson.Fa rm ,
1311a109c1cSRobert Watsonthrough the
1321a109c1cSRobert Watson.Fa opts
1331a109c1cSRobert Watsonargument.
1341a109c1cSRobert WatsonIt contains one or more of the following flags:
1351a109c1cSRobert Watson.Bl -tag -width ".Dv RM_NOWITNESS"
1361a109c1cSRobert Watson.It Dv RM_NOWITNESS
1371a109c1cSRobert WatsonInstruct
1381a109c1cSRobert Watson.Xr witness 4
1391a109c1cSRobert Watsonto ignore this lock.
1401a109c1cSRobert Watson.It Dv RM_RECURSE
1411a109c1cSRobert WatsonAllow threads to recursively acquire exclusive locks for
1421a109c1cSRobert Watson.Fa rm .
14336058c09SMax Laier.It Dv RM_SLEEPABLE
14436058c09SMax LaierAllow writers to sleep while holding the lock.
14536058c09SMax LaierReaders must not sleep while holding the lock and can avoid to sleep on
14636058c09SMax Laiertaking the lock by using
14736058c09SMax Laier.Fn rm_try_rlock
14836058c09SMax Laierinstead of
14936058c09SMax Laier.Fn rm_rlock .
1501a109c1cSRobert Watson.El
151f53d15feSStephan Uphoff.It Fn rm_rlock "struct rmlock *rm" "struct rm_priotracker* tracker"
152f53d15feSStephan UphoffLock
153f53d15feSStephan Uphoff.Fa rm
154c6d7cf7bSChristian Bruefferas a reader.
155c6d7cf7bSChristian BruefferUsing
156f53d15feSStephan Uphoff.Fa tracker
157f53d15feSStephan Uphoffto track read owners of a lock for priority propagation.
158989cbe40SHiten PandyaThis data structure is only used internally by
159989cbe40SHiten Pandya.Nm
160c6d7cf7bSChristian Bruefferand must persist until
161c6d7cf7bSChristian Brueffer.Fn rm_runlock
162c6d7cf7bSChristian Bruefferhas been called.
163989cbe40SHiten PandyaThis data structure can be allocated on the stack since
164f53d15feSStephan Uphoffrmlocks cannot be held while sleeping.
165f53d15feSStephan UphoffIf any thread holds this lock exclusively, the current thread blocks,
166f53d15feSStephan Uphoffand its priority is propagated to the exclusive holder.
167989cbe40SHiten PandyaIf the lock was initialized with the
168989cbe40SHiten Pandya.Dv LO_RECURSABLE
169989cbe40SHiten Pandyaoption the
170f53d15feSStephan Uphoff.Fn rm_rlock
171f53d15feSStephan Uphofffunction can be called when the thread has already acquired reader
172f53d15feSStephan Uphoffaccess on
173f53d15feSStephan Uphoff.Fa rm .
174f53d15feSStephan UphoffThis is called
175f53d15feSStephan Uphoff.Dq "recursing on a lock" .
17636058c09SMax Laier.It Fn rm_try_rlock "struct rmlock *rm" "struct rm_priotracker* tracker"
17736058c09SMax LaierTry to lock
17836058c09SMax Laier.Fa rm
17936058c09SMax Laieras a reader.
18036058c09SMax Laier.Fn rm_try_rlock
18136058c09SMax Laierwill return 0 if the lock cannot be acquired immediately;
18236058c09SMax Laierotherwise the lock will be acquired and a non-zero value will be returned.
18336058c09SMax LaierNote that
18436058c09SMax Laier.Fn rm_try_rlock
18536058c09SMax Laiermay fail even while the lock is not currently held by a writer.
186f53d15feSStephan Uphoff.It Fn rm_wlock "struct rmlock *rm"
187f53d15feSStephan UphoffLock
188f53d15feSStephan Uphoff.Fa rm
189f53d15feSStephan Uphoffas a writer.
190f53d15feSStephan UphoffIf there are any shared owners of the lock, the current thread blocks.
191f53d15feSStephan UphoffThe
192f53d15feSStephan Uphoff.Fn rm_wlock
193f53d15feSStephan Uphofffunction cannot be called recursively.
194f53d15feSStephan Uphoff.It Fn rm_runlock "struct rmlock *rm" "struct rm_priotracker* tracker"
195f53d15feSStephan UphoffThis function releases a shared lock previously acquired by
196f53d15feSStephan Uphoff.Fn rm_rlock .
197f53d15feSStephan UphoffThe
198f53d15feSStephan Uphoff.Fa tracker
199f53d15feSStephan Uphoffargument must match the
200f53d15feSStephan Uphoff.Fa tracker
201f53d15feSStephan Uphoffargument used for acquiring the shared lock
202f53d15feSStephan Uphoff.It Fn rm_wunlock "struct rmlock *rm"
203f53d15feSStephan UphoffThis function releases an exclusive lock previously acquired by
204f53d15feSStephan Uphoff.Fn rm_wlock .
205f53d15feSStephan Uphoff.It Fn rm_destroy "struct rmlock *rm"
206f53d15feSStephan UphoffThis functions destroys a lock previously initialized with
207f53d15feSStephan Uphoff.Fn rm_init .
208f53d15feSStephan UphoffThe
209f53d15feSStephan Uphoff.Fa rm
210f53d15feSStephan Uphofflock must be unlocked.
211*d576deedSPawel Jakub Dawidek.It Fn rm_wowned "const struct rmlock *rm"
212433ea89aSRobert WatsonThis function returns a non-zero value if the current thread owns an
213433ea89aSRobert Watsonexclusive lock on
214433ea89aSRobert Watson.Fa rm .
215f53d15feSStephan Uphoff.El
216f53d15feSStephan Uphoff.Sh SEE ALSO
217f53d15feSStephan Uphoff.Xr locking 9 ,
218f53d15feSStephan Uphoff.Xr mutex 9 ,
219f53d15feSStephan Uphoff.Xr panic 9 ,
220f53d15feSStephan Uphoff.Xr rwlock 9 ,
221f53d15feSStephan Uphoff.Xr sema 9 ,
222f53d15feSStephan Uphoff.Xr sx 9
223f53d15feSStephan Uphoff.Sh HISTORY
224f53d15feSStephan UphoffThese
225f53d15feSStephan Uphofffunctions appeared in
226f53d15feSStephan Uphoff.Fx 7.0 .
227f53d15feSStephan Uphoff.Sh AUTHORS
228f53d15feSStephan Uphoff.An -nosplit
229f53d15feSStephan UphoffThe
230f53d15feSStephan Uphoff.Nm
231f53d15feSStephan Uphofffacility was written by
232f53d15feSStephan Uphoff.An "Stephan Uphoff" .
233f53d15feSStephan UphoffThis manual page was written by
234f53d15feSStephan Uphoff.An "Gleb Smirnoff"
235989cbe40SHiten Pandyafor rwlock and modified to reflect rmlock by
236f53d15feSStephan Uphoff.An "Stephan Uphoff" .
237f53d15feSStephan Uphoff.Sh BUGS
238989cbe40SHiten PandyaThe
239989cbe40SHiten Pandya.Nm
240989cbe40SHiten Pandyaimplementation is currently not optimized for single processor systems.
241989cbe40SHiten Pandya.Pp
24236058c09SMax Laier.Fn rm_try_rlock
24336058c09SMax Laiercan fail transiently even when there is no writer, while another reader
24436058c09SMax Laierupdates the state on the local CPU.
24536058c09SMax Laier.Pp
246989cbe40SHiten PandyaThe
247989cbe40SHiten Pandya.Nm
248c6d7cf7bSChristian Bruefferimplementation uses a single per CPU list shared by all
249989cbe40SHiten Pandyarmlocks in the system.
250c6d7cf7bSChristian BruefferIf rmlocks become popular, hashing to multiple per CPU queues may
251989cbe40SHiten Pandyabe needed to speed up the writer lock process.
252989cbe40SHiten Pandya.Pp
253989cbe40SHiten PandyaThe
254989cbe40SHiten Pandya.Nm
255989cbe40SHiten Pandyacan currently not be used as a lock argument for condition variable
256989cbe40SHiten Pandyawait functions.
257