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