xref: /freebsd/share/man/man9/rwlock.9 (revision a2feb19b26f46e44dc955d832e67d05a9b0f75d0)
13182fc7bSGleb Smirnoff.\" Copyright (c) 2006 Gleb Smirnoff <glebius@FreeBSD.org>
23182fc7bSGleb Smirnoff.\" All rights reserved.
33182fc7bSGleb Smirnoff.\"
43182fc7bSGleb Smirnoff.\" Redistribution and use in source and binary forms, with or without
53182fc7bSGleb Smirnoff.\" modification, are permitted provided that the following conditions
63182fc7bSGleb Smirnoff.\" are met:
73182fc7bSGleb Smirnoff.\" 1. Redistributions of source code must retain the above copyright
83182fc7bSGleb Smirnoff.\"    notice, this list of conditions and the following disclaimer.
93182fc7bSGleb Smirnoff.\" 2. Redistributions in binary form must reproduce the above copyright
103182fc7bSGleb Smirnoff.\"    notice, this list of conditions and the following disclaimer in the
113182fc7bSGleb Smirnoff.\"    documentation and/or other materials provided with the distribution.
123182fc7bSGleb Smirnoff.\"
133182fc7bSGleb Smirnoff.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
143182fc7bSGleb Smirnoff.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
153182fc7bSGleb Smirnoff.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
163182fc7bSGleb Smirnoff.\" ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
173182fc7bSGleb Smirnoff.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
183182fc7bSGleb Smirnoff.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
193182fc7bSGleb Smirnoff.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
203182fc7bSGleb Smirnoff.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
213182fc7bSGleb Smirnoff.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
223182fc7bSGleb Smirnoff.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
233182fc7bSGleb Smirnoff.\" SUCH DAMAGE.
243182fc7bSGleb Smirnoff.\"
253182fc7bSGleb Smirnoff.\" $FreeBSD$
263182fc7bSGleb Smirnoff.\"
27*a2feb19bSJohn Baldwin.Dd June 20, 2013
283182fc7bSGleb Smirnoff.Dt RWLOCK 9
293182fc7bSGleb Smirnoff.Os
303182fc7bSGleb Smirnoff.Sh NAME
310b79fedbSJohn Baldwin.Nm rwlock ,
323182fc7bSGleb Smirnoff.Nm rw_init ,
336442838dSAttilio Rao.Nm rw_init_flags,
34b58aa2bdSJohn Baldwin.Nm rw_destroy ,
353182fc7bSGleb Smirnoff.Nm rw_rlock ,
363182fc7bSGleb Smirnoff.Nm rw_wlock ,
373182fc7bSGleb Smirnoff.Nm rw_runlock ,
383182fc7bSGleb Smirnoff.Nm rw_wunlock ,
39b12455f3SPawel Jakub Dawidek.Nm rw_unlock ,
40c709e029SAttilio Rao.Nm rw_try_rlock ,
417d3052bbSJohn Baldwin.Nm rw_try_upgrade ,
42c709e029SAttilio Rao.Nm rw_try_wlock ,
437d3052bbSJohn Baldwin.Nm rw_downgrade ,
44e7573e7aSJohn Baldwin.Nm rw_sleep ,
457d3052bbSJohn Baldwin.Nm rw_initialized ,
467d3052bbSJohn Baldwin.Nm rw_wowned ,
477d3052bbSJohn Baldwin.Nm rw_assert ,
48bd84dd2fSRuslan Ermilov.Nm RW_SYSINIT
490b79fedbSJohn Baldwin.Nd kernel reader/writer lock
503182fc7bSGleb Smirnoff.Sh SYNOPSIS
513182fc7bSGleb Smirnoff.In sys/param.h
523182fc7bSGleb Smirnoff.In sys/lock.h
533182fc7bSGleb Smirnoff.In sys/rwlock.h
543182fc7bSGleb Smirnoff.Ft void
550b79fedbSJohn Baldwin.Fn rw_init "struct rwlock *rw" "const char *name"
563182fc7bSGleb Smirnoff.Ft void
576442838dSAttilio Rao.Fn rw_init_flags "struct rwlock *rw" "const char *name" "int opts"
586442838dSAttilio Rao.Ft void
59b58aa2bdSJohn Baldwin.Fn rw_destroy "struct rwlock *rw"
60b58aa2bdSJohn Baldwin.Ft void
610b79fedbSJohn Baldwin.Fn rw_rlock "struct rwlock *rw"
623182fc7bSGleb Smirnoff.Ft void
630b79fedbSJohn Baldwin.Fn rw_wlock "struct rwlock *rw"
64c709e029SAttilio Rao.Ft int
65c709e029SAttilio Rao.Fn rw_try_rlock "struct rwlock *rw"
66c709e029SAttilio Rao.Ft int
67c709e029SAttilio Rao.Fn rw_try_wlock "struct rwlock *rw"
683182fc7bSGleb Smirnoff.Ft void
690b79fedbSJohn Baldwin.Fn rw_runlock "struct rwlock *rw"
703182fc7bSGleb Smirnoff.Ft void
710b79fedbSJohn Baldwin.Fn rw_wunlock "struct rwlock *rw"
72b12455f3SPawel Jakub Dawidek.Ft void
73b12455f3SPawel Jakub Dawidek.Fn rw_unlock "struct rwlock *rw"
743182fc7bSGleb Smirnoff.Ft int
7596cb5f99SJohn Baldwin.Fn rw_try_upgrade "struct rwlock *rw"
7696cb5f99SJohn Baldwin.Ft void
7796cb5f99SJohn Baldwin.Fn rw_downgrade "struct rwlock *rw"
78dd348217SRobert Watson.Ft int
79e7573e7aSJohn Baldwin.Fn rw_sleep "void *chan" "struct rwlock *rw" "int priority" "const char *wmesg" "int timo"
80e7573e7aSJohn Baldwin.Ft int
81d576deedSPawel Jakub Dawidek.Fn rw_initialized "const struct rwlock *rw"
827d3052bbSJohn Baldwin.Ft int
83d576deedSPawel Jakub Dawidek.Fn rw_wowned "const struct rwlock *rw"
843182fc7bSGleb Smirnoff.Pp
853182fc7bSGleb Smirnoff.Cd "options INVARIANTS"
863182fc7bSGleb Smirnoff.Cd "options INVARIANT_SUPPORT"
873182fc7bSGleb Smirnoff.Ft void
88d576deedSPawel Jakub Dawidek.Fn rw_assert "const struct rwlock *rw" "int what"
893182fc7bSGleb Smirnoff.In sys/kernel.h
900b79fedbSJohn Baldwin.Fn RW_SYSINIT "name" "struct rwlock *rw" "const char *desc"
913182fc7bSGleb Smirnoff.Sh DESCRIPTION
920b79fedbSJohn BaldwinReader/writer locks allow shared access to protected data by multiple threads,
930b79fedbSJohn Baldwinor exclusive access by a single thread.
940b79fedbSJohn BaldwinThe threads with shared access are known as
953182fc7bSGleb Smirnoff.Em readers
960b79fedbSJohn Baldwinsince they only read the protected data.
970b79fedbSJohn BaldwinA thread with exclusive access is known as a
983182fc7bSGleb Smirnoff.Em writer
993182fc7bSGleb Smirnoffsince it can modify protected data.
1003182fc7bSGleb Smirnoff.Pp
101f1acac21SFlorent ThoumieAlthough reader/writer locks look very similar to
1023182fc7bSGleb Smirnoff.Xr sx 9
1033182fc7bSGleb Smirnofflocks, their usage pattern is different.
1040b79fedbSJohn BaldwinReader/writer locks can be treated as mutexes (see
1053182fc7bSGleb Smirnoff.Xr mutex 9 )
1063182fc7bSGleb Smirnoffwith shared/exclusive semantics.
1073182fc7bSGleb SmirnoffUnlike
1083182fc7bSGleb Smirnoff.Xr sx 9 ,
1093182fc7bSGleb Smirnoffan
1103182fc7bSGleb Smirnoff.Nm
1110b79fedbSJohn Baldwincan be locked while holding a non-spin mutex, and an
1123182fc7bSGleb Smirnoff.Nm
1133182fc7bSGleb Smirnoffcannot be held while sleeping.
1143182fc7bSGleb SmirnoffThe
1153182fc7bSGleb Smirnoff.Nm
1163182fc7bSGleb Smirnofflocks have priority propagation like mutexes, but priority
1173d2a7480SJohn Baldwincan be propagated only to writers.
1183d2a7480SJohn BaldwinThis limitation comes from the fact that readers
1193182fc7bSGleb Smirnoffare anonymous.
1203d2a7480SJohn BaldwinAnother important property is that readers can always recurse,
1216442838dSAttilio Raoand exclusive locks can be made recursive selectively.
1223182fc7bSGleb Smirnoff.Ss Macros and Functions
1233182fc7bSGleb Smirnoff.Bl -tag -width indent
1240b79fedbSJohn Baldwin.It Fn rw_init "struct rwlock *rw" "const char *name"
1253182fc7bSGleb SmirnoffInitialize structure located at
1260b79fedbSJohn Baldwin.Fa rw
1270b79fedbSJohn Baldwinas reader/writer lock, described by name
1283182fc7bSGleb Smirnoff.Fa name .
1293182fc7bSGleb SmirnoffThe description is used solely for debugging purposes.
1300b79fedbSJohn BaldwinThis function must be called before any other operations
1310b79fedbSJohn Baldwinon the lock.
1326442838dSAttilio Rao.It Fn rw_init_flags "struct rwlock *rw" "const char *name" "int opts"
1334faa4b08SChristian BruefferInitialize the rw lock just like the
1346442838dSAttilio Rao.Fn rw_init
1354faa4b08SChristian Bruefferfunction, but specifying a set of optional flags to alter the
1366442838dSAttilio Raobehaviour of
1376442838dSAttilio Rao.Fa rw ,
1386442838dSAttilio Raothrough the
1396442838dSAttilio Rao.Fa opts
1404faa4b08SChristian Bruefferargument.
1414faa4b08SChristian BruefferIt contains one or more of the following flags:
1426442838dSAttilio Rao.Bl -tag -width ".Dv RW_NOPROFILE"
1436442838dSAttilio Rao.It Dv RW_DUPOK
1446442838dSAttilio RaoWitness should not log messages about duplicate locks being acquired.
1456442838dSAttilio Rao.It Dv RW_NOPROFILE
1466442838dSAttilio RaoDo not profile this lock.
1476442838dSAttilio Rao.It Dv RW_NOWITNESS
1486442838dSAttilio RaoInstruct
1496442838dSAttilio Rao.Xr witness 4
1506442838dSAttilio Raoto ignore this lock.
1516442838dSAttilio Rao.It Dv RW_QUIET
1526442838dSAttilio RaoDo not log any operations for this lock via
1536442838dSAttilio Rao.Xr ktr 4 .
1546442838dSAttilio Rao.It Dv RW_RECURSE
1556442838dSAttilio RaoAllow threads to recursively acquire exclusive locks for
1566442838dSAttilio Rao.Fa rw .
15739887c5cSPawel Jakub Dawidek.El
1580b79fedbSJohn Baldwin.It Fn rw_rlock "struct rwlock *rw"
1590b79fedbSJohn BaldwinLock
1600b79fedbSJohn Baldwin.Fa rw
1610b79fedbSJohn Baldwinas a reader.
1623182fc7bSGleb SmirnoffIf any thread holds this lock exclusively, the current thread blocks,
1630b79fedbSJohn Baldwinand its priority is propagated to the exclusive holder.
1643182fc7bSGleb SmirnoffThe
1653182fc7bSGleb Smirnoff.Fn rw_rlock
1663182fc7bSGleb Smirnofffunction can be called when the thread has already acquired reader
1673182fc7bSGleb Smirnoffaccess on
1680b79fedbSJohn Baldwin.Fa rw .
1693182fc7bSGleb SmirnoffThis is called
1703182fc7bSGleb Smirnoff.Dq "recursing on a lock" .
1710b79fedbSJohn Baldwin.It Fn rw_wlock "struct rwlock *rw"
1720b79fedbSJohn BaldwinLock
1730b79fedbSJohn Baldwin.Fa rw
1740b79fedbSJohn Baldwinas a writer.
1753182fc7bSGleb SmirnoffIf there are any shared owners of the lock, the current thread blocks.
1763182fc7bSGleb SmirnoffThe
1773182fc7bSGleb Smirnoff.Fn rw_wlock
1786442838dSAttilio Raofunction can be called recursively only if
1796442838dSAttilio Rao.Fa rw
1806442838dSAttilio Raohas been initialized with the
1816442838dSAttilio Rao.Dv RW_RECURSE
1826442838dSAttilio Raooption enabled.
183c709e029SAttilio Rao.It Fn rw_try_rlock "struct rwlock *rw"
184c709e029SAttilio RaoTry to lock
185c709e029SAttilio Rao.Fa rw
186c709e029SAttilio Raoas a reader.
187c709e029SAttilio RaoThis function will return true if the operation succeeds, otherwise 0
188c709e029SAttilio Raowill be returned.
189c709e029SAttilio Rao.It Fn rw_try_wlock "struct rwlock *rw"
190c709e029SAttilio RaoTry to lock
191c709e029SAttilio Rao.Fa rw
192c709e029SAttilio Raoas a writer.
193c709e029SAttilio RaoThis function will return true if the operation succeeds, otherwise 0
194c709e029SAttilio Raowill be returned.
1950b79fedbSJohn Baldwin.It Fn rw_runlock "struct rwlock *rw"
1960b79fedbSJohn BaldwinThis function releases a shared lock previously acquired by
1973182fc7bSGleb Smirnoff.Fn rw_rlock .
1980b79fedbSJohn Baldwin.It Fn rw_wunlock "struct rwlock *rw"
1990b79fedbSJohn BaldwinThis function releases an exclusive lock previously acquired by
2003182fc7bSGleb Smirnoff.Fn rw_wlock .
201b12455f3SPawel Jakub Dawidek.It Fn rw_unlock "struct rwlock *rw"
202b12455f3SPawel Jakub DawidekThis function releases a shared lock previously acquired by
203b12455f3SPawel Jakub Dawidek.Fn rw_rlock
204b12455f3SPawel Jakub Dawidekor an exclusive lock previously acquired by
205b12455f3SPawel Jakub Dawidek.Fn rw_wlock .
20696cb5f99SJohn Baldwin.It Fn rw_try_upgrade "struct rwlock *rw"
20796cb5f99SJohn BaldwinAttempt to upgrade a single shared lock to an exclusive lock.
20896cb5f99SJohn BaldwinThe current thread must hold a shared lock of
20996cb5f99SJohn Baldwin.Fa rw .
21096cb5f99SJohn BaldwinThis will only succeed if the current thread holds the only shared lock on
21196cb5f99SJohn Baldwin.Fa rw ,
21296cb5f99SJohn Baldwinand it only holds a single shared lock.
21396cb5f99SJohn BaldwinIf the attempt succeeds
21496cb5f99SJohn Baldwin.Fn rw_try_upgrade
21596cb5f99SJohn Baldwinwill return a non-zero value,
21696cb5f99SJohn Baldwinand the current thread will hold an exclusive lock.
21796cb5f99SJohn BaldwinIf the attempt fails
21896cb5f99SJohn Baldwin.Fn rw_try_upgrade
21996cb5f99SJohn Baldwinwill return zero,
22096cb5f99SJohn Baldwinand the current thread will still hold a shared lock.
22196cb5f99SJohn Baldwin.It Fn rw_downgrade "struct rwlock *rw"
22296cb5f99SJohn BaldwinConvert an exclusive lock into a single shared lock.
22396cb5f99SJohn BaldwinThe current thread must hold an exclusive lock of
22496cb5f99SJohn Baldwin.Fa rw .
225e7573e7aSJohn Baldwin.It Fn rw_sleep "void *chan" "struct rwlock *rw" "int priority" "const char *wmesg" "int timo"
226e7573e7aSJohn BaldwinAtomically release
227e7573e7aSJohn Baldwin.Fa rw
228e7573e7aSJohn Baldwinwhile waiting for an event.
229e7573e7aSJohn BaldwinFor more details on the parameters to this function,
230e7573e7aSJohn Baldwinsee
231e7573e7aSJohn Baldwin.Xr sleep 9 .
232d576deedSPawel Jakub Dawidek.It Fn rw_initialized "const struct rwlock *rw"
2330b79fedbSJohn BaldwinThis function returns non-zero if
2340b79fedbSJohn Baldwin.Fa rw
2353182fc7bSGleb Smirnoffhas been initialized, and zero otherwise.
2360b79fedbSJohn Baldwin.It Fn rw_destroy "struct rwlock *rw"
2373182fc7bSGleb SmirnoffThis functions destroys a lock previously initialized with
2383182fc7bSGleb Smirnoff.Fn rw_init .
2393182fc7bSGleb SmirnoffThe
2400b79fedbSJohn Baldwin.Fa rw
2410b79fedbSJohn Baldwinlock must be unlocked.
242d576deedSPawel Jakub Dawidek.It Fn rw_wowned "const struct rwlock *rw"
243dd348217SRobert WatsonThis function returns a non-zero value if the current thread owns an
244dd348217SRobert Watsonexclusive lock on
245dd348217SRobert Watson.Fa rw .
246d576deedSPawel Jakub Dawidek.It Fn rw_assert "const struct rwlock *rw" "int what"
2473182fc7bSGleb SmirnoffThis function allows assertions specified in
2483182fc7bSGleb Smirnoff.Fa what
2493182fc7bSGleb Smirnoffto be made about
2500b79fedbSJohn Baldwin.Fa rw .
2513182fc7bSGleb SmirnoffIf the assertions are not true and the kernel is compiled
2523182fc7bSGleb Smirnoffwith
2533182fc7bSGleb Smirnoff.Cd "options INVARIANTS"
2543182fc7bSGleb Smirnoffand
2553182fc7bSGleb Smirnoff.Cd "options INVARIANT_SUPPORT" ,
2563182fc7bSGleb Smirnoffthe kernel will panic.
257*a2feb19bSJohn BaldwinCurrently the following base assertions are supported:
2583182fc7bSGleb Smirnoff.Bl -tag -width ".Dv RA_UNLOCKED"
2593182fc7bSGleb Smirnoff.It Dv RA_LOCKED
2600b79fedbSJohn BaldwinAssert that current thread holds either a shared or exclusive lock
2610b79fedbSJohn Baldwinof
2620b79fedbSJohn Baldwin.Fa rw .
2633182fc7bSGleb Smirnoff.It Dv RA_RLOCKED
2640b79fedbSJohn BaldwinAssert that current thread holds a shared lock of
2650b79fedbSJohn Baldwin.Fa rw .
2663182fc7bSGleb Smirnoff.It Dv RA_WLOCKED
2670b79fedbSJohn BaldwinAssert that current thread holds an exclusive lock of
2680b79fedbSJohn Baldwin.Fa rw .
2693182fc7bSGleb Smirnoff.It Dv RA_UNLOCKED
2700b79fedbSJohn BaldwinAssert that current thread holds neither a shared nor exclusive lock of
2710b79fedbSJohn Baldwin.Fa rw .
2723182fc7bSGleb Smirnoff.El
273*a2feb19bSJohn Baldwin.Pp
274*a2feb19bSJohn BaldwinIn addition, one of the following optional flags may be specified with
275*a2feb19bSJohn Baldwin.Dv RA_LOCKED ,
276*a2feb19bSJohn Baldwin.Dv RA_RLOCKED ,
277*a2feb19bSJohn Baldwinor
278*a2feb19bSJohn Baldwin.Dv RA_WLOCKED :
279*a2feb19bSJohn Baldwin.Bl -tag -width ".Dv RA_NOTRECURSED"
280*a2feb19bSJohn Baldwin.It Dv RA_RECURSED
281*a2feb19bSJohn BaldwinAssert that the current thread holds a recursive lock of
282*a2feb19bSJohn Baldwin.Fa rw .
283*a2feb19bSJohn Baldwin.It Dv RA_NOTRECURSED
284*a2feb19bSJohn BaldwinAssert that the current thread does not hold a recursive lock of
285*a2feb19bSJohn Baldwin.Fa rw .
286*a2feb19bSJohn Baldwin.El
2873182fc7bSGleb Smirnoff.El
2883182fc7bSGleb Smirnoff.Sh SEE ALSO
289a280550aSJulian Elischer.Xr locking 9 ,
2903182fc7bSGleb Smirnoff.Xr mutex 9 ,
2913182fc7bSGleb Smirnoff.Xr panic 9 ,
2923182fc7bSGleb Smirnoff.Xr sema 9 ,
2933182fc7bSGleb Smirnoff.Xr sx 9
2943182fc7bSGleb Smirnoff.Sh HISTORY
2953182fc7bSGleb SmirnoffThese
2963182fc7bSGleb Smirnofffunctions appeared in
2973182fc7bSGleb Smirnoff.Fx 7.0 .
2983182fc7bSGleb Smirnoff.Sh AUTHORS
2993182fc7bSGleb Smirnoff.An -nosplit
3003182fc7bSGleb SmirnoffThe
3013182fc7bSGleb Smirnoff.Nm
3023182fc7bSGleb Smirnofffacility was written by
3033182fc7bSGleb Smirnoff.An "John Baldwin" .
3043182fc7bSGleb SmirnoffThis manual page was written by
3053182fc7bSGleb Smirnoff.An "Gleb Smirnoff" .
3060b79fedbSJohn Baldwin.Sh BUGS
3070b79fedbSJohn BaldwinIf
3080b79fedbSJohn Baldwin.Dv WITNESS
3090b79fedbSJohn Baldwinis not included in the kernel,
3100b79fedbSJohn Baldwinthen it is impossible to assert that the current thread does or does not
3117d3052bbSJohn Baldwinhold a read lock.
3120b79fedbSJohn BaldwinIn the
313bd84dd2fSRuslan Ermilov.Pf non- Dv WITNESS
3140b79fedbSJohn Baldwincase, the
3150b79fedbSJohn Baldwin.Dv RA_LOCKED
3160b79fedbSJohn Baldwinand
3170b79fedbSJohn Baldwin.Dv RA_RLOCKED
3187d3052bbSJohn Baldwinassertions merely check that some thread holds a read lock.
3190b79fedbSJohn Baldwin.Pp
3200b79fedbSJohn BaldwinReader/writer is a bit of an awkward name.
3210b79fedbSJohn BaldwinAn
3220b79fedbSJohn Baldwin.Nm
3230b79fedbSJohn Baldwincan also be called a
3240b79fedbSJohn Baldwin.Dq Robert Watson
3250b79fedbSJohn Baldwinlock if desired.
326