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.\" 27b12455f3SPawel Jakub Dawidek.Dd March 16, 2008 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 , 407d3052bbSJohn Baldwin.Nm rw_try_upgrade , 417d3052bbSJohn Baldwin.Nm rw_downgrade , 42e7573e7aSJohn Baldwin.Nm rw_sleep , 437d3052bbSJohn Baldwin.Nm rw_initialized , 447d3052bbSJohn Baldwin.Nm rw_wowned , 457d3052bbSJohn Baldwin.Nm rw_assert , 46bd84dd2fSRuslan Ermilov.Nm RW_SYSINIT 470b79fedbSJohn Baldwin.Nd kernel reader/writer lock 483182fc7bSGleb Smirnoff.Sh SYNOPSIS 493182fc7bSGleb Smirnoff.In sys/param.h 503182fc7bSGleb Smirnoff.In sys/lock.h 513182fc7bSGleb Smirnoff.In sys/rwlock.h 523182fc7bSGleb Smirnoff.Ft void 530b79fedbSJohn Baldwin.Fn rw_init "struct rwlock *rw" "const char *name" 543182fc7bSGleb Smirnoff.Ft void 556442838dSAttilio Rao.Fn rw_init_flags "struct rwlock *rw" "const char *name" "int opts" 566442838dSAttilio Rao.Ft void 57b58aa2bdSJohn Baldwin.Fn rw_destroy "struct rwlock *rw" 58b58aa2bdSJohn Baldwin.Ft void 590b79fedbSJohn Baldwin.Fn rw_rlock "struct rwlock *rw" 603182fc7bSGleb Smirnoff.Ft void 610b79fedbSJohn Baldwin.Fn rw_wlock "struct rwlock *rw" 623182fc7bSGleb Smirnoff.Ft void 630b79fedbSJohn Baldwin.Fn rw_runlock "struct rwlock *rw" 643182fc7bSGleb Smirnoff.Ft void 650b79fedbSJohn Baldwin.Fn rw_wunlock "struct rwlock *rw" 66b12455f3SPawel Jakub Dawidek.Ft void 67b12455f3SPawel Jakub Dawidek.Fn rw_unlock "struct rwlock *rw" 683182fc7bSGleb Smirnoff.Ft int 6996cb5f99SJohn Baldwin.Fn rw_try_upgrade "struct rwlock *rw" 7096cb5f99SJohn Baldwin.Ft void 7196cb5f99SJohn Baldwin.Fn rw_downgrade "struct rwlock *rw" 72dd348217SRobert Watson.Ft int 73e7573e7aSJohn Baldwin.Fn rw_sleep "void *chan" "struct rwlock *rw" "int priority" "const char *wmesg" "int timo" 74e7573e7aSJohn Baldwin.Ft int 757d3052bbSJohn Baldwin.Fn rw_initialized "struct rwlock *rw" 767d3052bbSJohn Baldwin.Ft int 77dd348217SRobert Watson.Fn rw_wowned "struct rwlock *rw" 783182fc7bSGleb Smirnoff.Pp 793182fc7bSGleb Smirnoff.Cd "options INVARIANTS" 803182fc7bSGleb Smirnoff.Cd "options INVARIANT_SUPPORT" 813182fc7bSGleb Smirnoff.Ft void 820b79fedbSJohn Baldwin.Fn rw_assert "struct rwlock *rw" "int what" 833182fc7bSGleb Smirnoff.In sys/kernel.h 840b79fedbSJohn Baldwin.Fn RW_SYSINIT "name" "struct rwlock *rw" "const char *desc" 853182fc7bSGleb Smirnoff.Sh DESCRIPTION 860b79fedbSJohn BaldwinReader/writer locks allow shared access to protected data by multiple threads, 870b79fedbSJohn Baldwinor exclusive access by a single thread. 880b79fedbSJohn BaldwinThe threads with shared access are known as 893182fc7bSGleb Smirnoff.Em readers 900b79fedbSJohn Baldwinsince they only read the protected data. 910b79fedbSJohn BaldwinA thread with exclusive access is known as a 923182fc7bSGleb Smirnoff.Em writer 933182fc7bSGleb Smirnoffsince it can modify protected data. 943182fc7bSGleb Smirnoff.Pp 95f1acac21SFlorent ThoumieAlthough reader/writer locks look very similar to 963182fc7bSGleb Smirnoff.Xr sx 9 973182fc7bSGleb Smirnofflocks, their usage pattern is different. 980b79fedbSJohn BaldwinReader/writer locks can be treated as mutexes (see 993182fc7bSGleb Smirnoff.Xr mutex 9 ) 1003182fc7bSGleb Smirnoffwith shared/exclusive semantics. 1013182fc7bSGleb SmirnoffUnlike 1023182fc7bSGleb Smirnoff.Xr sx 9 , 1033182fc7bSGleb Smirnoffan 1043182fc7bSGleb Smirnoff.Nm 1050b79fedbSJohn Baldwincan be locked while holding a non-spin mutex, and an 1063182fc7bSGleb Smirnoff.Nm 1073182fc7bSGleb Smirnoffcannot be held while sleeping. 1083182fc7bSGleb SmirnoffThe 1093182fc7bSGleb Smirnoff.Nm 1103182fc7bSGleb Smirnofflocks have priority propagation like mutexes, but priority 1110b79fedbSJohn Baldwincan be propagated only to an exclusive holder. 1123182fc7bSGleb SmirnoffThis limitation comes from the fact that shared owners 1133182fc7bSGleb Smirnoffare anonymous. 1140b79fedbSJohn BaldwinAnother important property is that shared holders of 1153182fc7bSGleb Smirnoff.Nm 1160b79fedbSJohn Baldwincan recurse, 1176442838dSAttilio Raoand exclusive locks can be made recursive selectively. 1183182fc7bSGleb Smirnoff.Ss Macros and Functions 1193182fc7bSGleb Smirnoff.Bl -tag -width indent 1200b79fedbSJohn Baldwin.It Fn rw_init "struct rwlock *rw" "const char *name" 1213182fc7bSGleb SmirnoffInitialize structure located at 1220b79fedbSJohn Baldwin.Fa rw 1230b79fedbSJohn Baldwinas reader/writer lock, described by name 1243182fc7bSGleb Smirnoff.Fa name . 1253182fc7bSGleb SmirnoffThe description is used solely for debugging purposes. 1260b79fedbSJohn BaldwinThis function must be called before any other operations 1270b79fedbSJohn Baldwinon the lock. 1286442838dSAttilio Rao.It Fn rw_init_flags "struct rwlock *rw" "const char *name" "int opts" 1294faa4b08SChristian BruefferInitialize the rw lock just like the 1306442838dSAttilio Rao.Fn rw_init 1314faa4b08SChristian Bruefferfunction, but specifying a set of optional flags to alter the 1326442838dSAttilio Raobehaviour of 1336442838dSAttilio Rao.Fa rw , 1346442838dSAttilio Raothrough the 1356442838dSAttilio Rao.Fa opts 1364faa4b08SChristian Bruefferargument. 1374faa4b08SChristian BruefferIt contains one or more of the following flags: 1386442838dSAttilio Rao.Bl -tag -width ".Dv RW_NOPROFILE" 1396442838dSAttilio Rao.It Dv RW_DUPOK 1406442838dSAttilio RaoWitness should not log messages about duplicate locks being acquired. 1416442838dSAttilio Rao.It Dv RW_NOPROFILE 1426442838dSAttilio RaoDo not profile this lock. 1436442838dSAttilio Rao.It Dv RW_NOWITNESS 1446442838dSAttilio RaoInstruct 1456442838dSAttilio Rao.Xr witness 4 1466442838dSAttilio Raoto ignore this lock. 1476442838dSAttilio Rao.It Dv RW_QUIET 1486442838dSAttilio RaoDo not log any operations for this lock via 1496442838dSAttilio Rao.Xr ktr 4 . 1506442838dSAttilio Rao.It Dv RW_RECURSE 1516442838dSAttilio RaoAllow threads to recursively acquire exclusive locks for 1526442838dSAttilio Rao.Fa rw . 15339887c5cSPawel Jakub Dawidek.El 1540b79fedbSJohn Baldwin.It Fn rw_rlock "struct rwlock *rw" 1550b79fedbSJohn BaldwinLock 1560b79fedbSJohn Baldwin.Fa rw 1570b79fedbSJohn Baldwinas a reader. 1583182fc7bSGleb SmirnoffIf any thread holds this lock exclusively, the current thread blocks, 1590b79fedbSJohn Baldwinand its priority is propagated to the exclusive holder. 1603182fc7bSGleb SmirnoffThe 1613182fc7bSGleb Smirnoff.Fn rw_rlock 1623182fc7bSGleb Smirnofffunction can be called when the thread has already acquired reader 1633182fc7bSGleb Smirnoffaccess on 1640b79fedbSJohn Baldwin.Fa rw . 1653182fc7bSGleb SmirnoffThis is called 1663182fc7bSGleb Smirnoff.Dq "recursing on a lock" . 1670b79fedbSJohn Baldwin.It Fn rw_wlock "struct rwlock *rw" 1680b79fedbSJohn BaldwinLock 1690b79fedbSJohn Baldwin.Fa rw 1700b79fedbSJohn Baldwinas a writer. 1713182fc7bSGleb SmirnoffIf there are any shared owners of the lock, the current thread blocks. 1723182fc7bSGleb SmirnoffThe 1733182fc7bSGleb Smirnoff.Fn rw_wlock 1746442838dSAttilio Raofunction can be called recursively only if 1756442838dSAttilio Rao.Fa rw 1766442838dSAttilio Raohas been initialized with the 1776442838dSAttilio Rao.Dv RW_RECURSE 1786442838dSAttilio Raooption enabled. 1790b79fedbSJohn Baldwin.It Fn rw_runlock "struct rwlock *rw" 1800b79fedbSJohn BaldwinThis function releases a shared lock previously acquired by 1813182fc7bSGleb Smirnoff.Fn rw_rlock . 1820b79fedbSJohn Baldwin.It Fn rw_wunlock "struct rwlock *rw" 1830b79fedbSJohn BaldwinThis function releases an exclusive lock previously acquired by 1843182fc7bSGleb Smirnoff.Fn rw_wlock . 185b12455f3SPawel Jakub Dawidek.It Fn rw_unlock "struct rwlock *rw" 186b12455f3SPawel Jakub DawidekThis function releases a shared lock previously acquired by 187b12455f3SPawel Jakub Dawidek.Fn rw_rlock 188b12455f3SPawel Jakub Dawidekor an exclusive lock previously acquired by 189b12455f3SPawel Jakub Dawidek.Fn rw_wlock . 19096cb5f99SJohn Baldwin.It Fn rw_try_upgrade "struct rwlock *rw" 19196cb5f99SJohn BaldwinAttempt to upgrade a single shared lock to an exclusive lock. 19296cb5f99SJohn BaldwinThe current thread must hold a shared lock of 19396cb5f99SJohn Baldwin.Fa rw . 19496cb5f99SJohn BaldwinThis will only succeed if the current thread holds the only shared lock on 19596cb5f99SJohn Baldwin.Fa rw , 19696cb5f99SJohn Baldwinand it only holds a single shared lock. 19796cb5f99SJohn BaldwinIf the attempt succeeds 19896cb5f99SJohn Baldwin.Fn rw_try_upgrade 19996cb5f99SJohn Baldwinwill return a non-zero value, 20096cb5f99SJohn Baldwinand the current thread will hold an exclusive lock. 20196cb5f99SJohn BaldwinIf the attempt fails 20296cb5f99SJohn Baldwin.Fn rw_try_upgrade 20396cb5f99SJohn Baldwinwill return zero, 20496cb5f99SJohn Baldwinand the current thread will still hold a shared lock. 20596cb5f99SJohn Baldwin.It Fn rw_downgrade "struct rwlock *rw" 20696cb5f99SJohn BaldwinConvert an exclusive lock into a single shared lock. 20796cb5f99SJohn BaldwinThe current thread must hold an exclusive lock of 20896cb5f99SJohn Baldwin.Fa rw . 209e7573e7aSJohn Baldwin.It Fn rw_sleep "void *chan" "struct rwlock *rw" "int priority" "const char *wmesg" "int timo" 210e7573e7aSJohn BaldwinAtomically release 211e7573e7aSJohn Baldwin.Fa rw 212e7573e7aSJohn Baldwinwhile waiting for an event. 213e7573e7aSJohn BaldwinFor more details on the parameters to this function, 214e7573e7aSJohn Baldwinsee 215e7573e7aSJohn Baldwin.Xr sleep 9 . 2160b79fedbSJohn Baldwin.It Fn rw_initialized "struct rwlock *rw" 2170b79fedbSJohn BaldwinThis function returns non-zero if 2180b79fedbSJohn Baldwin.Fa rw 2193182fc7bSGleb Smirnoffhas been initialized, and zero otherwise. 2200b79fedbSJohn Baldwin.It Fn rw_destroy "struct rwlock *rw" 2213182fc7bSGleb SmirnoffThis functions destroys a lock previously initialized with 2223182fc7bSGleb Smirnoff.Fn rw_init . 2233182fc7bSGleb SmirnoffThe 2240b79fedbSJohn Baldwin.Fa rw 2250b79fedbSJohn Baldwinlock must be unlocked. 226dd348217SRobert Watson.It Fn rw_wowned "struct rwlock *rw" 227dd348217SRobert WatsonThis function returns a non-zero value if the current thread owns an 228dd348217SRobert Watsonexclusive lock on 229dd348217SRobert Watson.Fa rw . 2300b79fedbSJohn Baldwin.It Fn rw_assert "struct rwlock *rw" "int what" 2313182fc7bSGleb SmirnoffThis function allows assertions specified in 2323182fc7bSGleb Smirnoff.Fa what 2333182fc7bSGleb Smirnoffto be made about 2340b79fedbSJohn Baldwin.Fa rw . 2353182fc7bSGleb SmirnoffIf the assertions are not true and the kernel is compiled 2363182fc7bSGleb Smirnoffwith 2373182fc7bSGleb Smirnoff.Cd "options INVARIANTS" 2383182fc7bSGleb Smirnoffand 2393182fc7bSGleb Smirnoff.Cd "options INVARIANT_SUPPORT" , 2403182fc7bSGleb Smirnoffthe kernel will panic. 2413182fc7bSGleb SmirnoffCurrently the following assertions are supported: 2423182fc7bSGleb Smirnoff.Bl -tag -width ".Dv RA_UNLOCKED" 2433182fc7bSGleb Smirnoff.It Dv RA_LOCKED 2440b79fedbSJohn BaldwinAssert that current thread holds either a shared or exclusive lock 2450b79fedbSJohn Baldwinof 2460b79fedbSJohn Baldwin.Fa rw . 2473182fc7bSGleb Smirnoff.It Dv RA_RLOCKED 2480b79fedbSJohn BaldwinAssert that current thread holds a shared lock of 2490b79fedbSJohn Baldwin.Fa rw . 2503182fc7bSGleb Smirnoff.It Dv RA_WLOCKED 2510b79fedbSJohn BaldwinAssert that current thread holds an exclusive lock of 2520b79fedbSJohn Baldwin.Fa rw . 2533182fc7bSGleb Smirnoff.It Dv RA_UNLOCKED 2540b79fedbSJohn BaldwinAssert that current thread holds neither a shared nor exclusive lock of 2550b79fedbSJohn Baldwin.Fa rw . 2563182fc7bSGleb Smirnoff.El 2573182fc7bSGleb Smirnoff.El 2583182fc7bSGleb Smirnoff.Sh SEE ALSO 259a280550aSJulian Elischer.Xr locking 9 , 2603182fc7bSGleb Smirnoff.Xr mutex 9 , 2613182fc7bSGleb Smirnoff.Xr panic 9 , 2623182fc7bSGleb Smirnoff.Xr sema 9 , 2633182fc7bSGleb Smirnoff.Xr sx 9 2643182fc7bSGleb Smirnoff.Sh HISTORY 2653182fc7bSGleb SmirnoffThese 2663182fc7bSGleb Smirnofffunctions appeared in 2673182fc7bSGleb Smirnoff.Fx 7.0 . 2683182fc7bSGleb Smirnoff.Sh AUTHORS 2693182fc7bSGleb Smirnoff.An -nosplit 2703182fc7bSGleb SmirnoffThe 2713182fc7bSGleb Smirnoff.Nm 2723182fc7bSGleb Smirnofffacility was written by 2733182fc7bSGleb Smirnoff.An "John Baldwin" . 2743182fc7bSGleb SmirnoffThis manual page was written by 2753182fc7bSGleb Smirnoff.An "Gleb Smirnoff" . 2760b79fedbSJohn Baldwin.Sh BUGS 2770b79fedbSJohn BaldwinIf 2780b79fedbSJohn Baldwin.Dv WITNESS 2790b79fedbSJohn Baldwinis not included in the kernel, 2800b79fedbSJohn Baldwinthen it is impossible to assert that the current thread does or does not 2817d3052bbSJohn Baldwinhold a read lock. 2820b79fedbSJohn BaldwinIn the 283bd84dd2fSRuslan Ermilov.Pf non- Dv WITNESS 2840b79fedbSJohn Baldwincase, the 2850b79fedbSJohn Baldwin.Dv RA_LOCKED 2860b79fedbSJohn Baldwinand 2870b79fedbSJohn Baldwin.Dv RA_RLOCKED 2887d3052bbSJohn Baldwinassertions merely check that some thread holds a read lock. 2890b79fedbSJohn Baldwin.Pp 2900b79fedbSJohn BaldwinReader/writer is a bit of an awkward name. 2910b79fedbSJohn BaldwinAn 2920b79fedbSJohn Baldwin.Nm 2930b79fedbSJohn Baldwincan also be called a 2940b79fedbSJohn Baldwin.Dq Robert Watson 2950b79fedbSJohn Baldwinlock if desired. 296