xref: /freebsd/share/man/man9/rwlock.9 (revision a280550abf7f97914cd92e86e0e698b51c48a46c)
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.\"
270b79fedbSJohn Baldwin.Dd April 19, 2006
283182fc7bSGleb Smirnoff.Dt RWLOCK 9
293182fc7bSGleb Smirnoff.Os
303182fc7bSGleb Smirnoff.Sh NAME
310b79fedbSJohn Baldwin.Nm rwlock ,
323182fc7bSGleb Smirnoff.Nm rw_init ,
33b58aa2bdSJohn Baldwin.Nm rw_destroy ,
343182fc7bSGleb Smirnoff.Nm rw_rlock ,
353182fc7bSGleb Smirnoff.Nm rw_wlock ,
363182fc7bSGleb Smirnoff.Nm rw_runlock ,
373182fc7bSGleb Smirnoff.Nm rw_wunlock ,
387d3052bbSJohn Baldwin.Nm rw_try_upgrade ,
397d3052bbSJohn Baldwin.Nm rw_downgrade ,
40e7573e7aSJohn Baldwin.Nm rw_sleep ,
417d3052bbSJohn Baldwin.Nm rw_initialized ,
427d3052bbSJohn Baldwin.Nm rw_wowned ,
437d3052bbSJohn Baldwin.Nm rw_assert ,
44bd84dd2fSRuslan Ermilov.Nm RW_SYSINIT
450b79fedbSJohn Baldwin.Nd kernel reader/writer lock
463182fc7bSGleb Smirnoff.Sh SYNOPSIS
473182fc7bSGleb Smirnoff.In sys/param.h
483182fc7bSGleb Smirnoff.In sys/lock.h
493182fc7bSGleb Smirnoff.In sys/rwlock.h
503182fc7bSGleb Smirnoff.Ft void
510b79fedbSJohn Baldwin.Fn rw_init "struct rwlock *rw" "const char *name"
523182fc7bSGleb Smirnoff.Ft void
53b58aa2bdSJohn Baldwin.Fn rw_destroy "struct rwlock *rw"
54b58aa2bdSJohn Baldwin.Ft void
550b79fedbSJohn Baldwin.Fn rw_rlock "struct rwlock *rw"
563182fc7bSGleb Smirnoff.Ft void
570b79fedbSJohn Baldwin.Fn rw_wlock "struct rwlock *rw"
583182fc7bSGleb Smirnoff.Ft void
590b79fedbSJohn Baldwin.Fn rw_runlock "struct rwlock *rw"
603182fc7bSGleb Smirnoff.Ft void
610b79fedbSJohn Baldwin.Fn rw_wunlock "struct rwlock *rw"
623182fc7bSGleb Smirnoff.Ft int
6396cb5f99SJohn Baldwin.Fn rw_try_upgrade "struct rwlock *rw"
6496cb5f99SJohn Baldwin.Ft void
6596cb5f99SJohn Baldwin.Fn rw_downgrade "struct rwlock *rw"
66dd348217SRobert Watson.Ft int
67e7573e7aSJohn Baldwin.Fn rw_sleep "void *chan" "struct rwlock *rw" "int priority" "const char *wmesg" "int timo"
68e7573e7aSJohn Baldwin.Ft int
697d3052bbSJohn Baldwin.Fn rw_initialized "struct rwlock *rw"
707d3052bbSJohn Baldwin.Ft int
71dd348217SRobert Watson.Fn rw_wowned "struct rwlock *rw"
723182fc7bSGleb Smirnoff.Pp
733182fc7bSGleb Smirnoff.Cd "options INVARIANTS"
743182fc7bSGleb Smirnoff.Cd "options INVARIANT_SUPPORT"
753182fc7bSGleb Smirnoff.Ft void
760b79fedbSJohn Baldwin.Fn rw_assert "struct rwlock *rw" "int what"
773182fc7bSGleb Smirnoff.In sys/kernel.h
780b79fedbSJohn Baldwin.Fn RW_SYSINIT "name" "struct rwlock *rw" "const char *desc"
793182fc7bSGleb Smirnoff.Sh DESCRIPTION
800b79fedbSJohn BaldwinReader/writer locks allow shared access to protected data by multiple threads,
810b79fedbSJohn Baldwinor exclusive access by a single thread.
820b79fedbSJohn BaldwinThe threads with shared access are known as
833182fc7bSGleb Smirnoff.Em readers
840b79fedbSJohn Baldwinsince they only read the protected data.
850b79fedbSJohn BaldwinA thread with exclusive access is known as a
863182fc7bSGleb Smirnoff.Em writer
873182fc7bSGleb Smirnoffsince it can modify protected data.
883182fc7bSGleb Smirnoff.Pp
89f1acac21SFlorent ThoumieAlthough reader/writer locks look very similar to
903182fc7bSGleb Smirnoff.Xr sx 9
913182fc7bSGleb Smirnofflocks, their usage pattern is different.
920b79fedbSJohn BaldwinReader/writer locks can be treated as mutexes (see
933182fc7bSGleb Smirnoff.Xr mutex 9 )
943182fc7bSGleb Smirnoffwith shared/exclusive semantics.
953182fc7bSGleb SmirnoffUnlike
963182fc7bSGleb Smirnoff.Xr sx 9 ,
973182fc7bSGleb Smirnoffan
983182fc7bSGleb Smirnoff.Nm
990b79fedbSJohn Baldwincan be locked while holding a non-spin mutex, and an
1003182fc7bSGleb Smirnoff.Nm
1013182fc7bSGleb Smirnoffcannot be held while sleeping.
1023182fc7bSGleb SmirnoffThe
1033182fc7bSGleb Smirnoff.Nm
1043182fc7bSGleb Smirnofflocks have priority propagation like mutexes, but priority
1050b79fedbSJohn Baldwincan be propagated only to an exclusive holder.
1063182fc7bSGleb SmirnoffThis limitation comes from the fact that shared owners
1073182fc7bSGleb Smirnoffare anonymous.
1080b79fedbSJohn BaldwinAnother important property is that shared holders of
1093182fc7bSGleb Smirnoff.Nm
1100b79fedbSJohn Baldwincan recurse,
1110b79fedbSJohn Baldwinbut exclusive locks are not allowed to recurse.
1123182fc7bSGleb Smirnoff.Ss Macros and Functions
1133182fc7bSGleb Smirnoff.Bl -tag -width indent
1140b79fedbSJohn Baldwin.It Fn rw_init "struct rwlock *rw" "const char *name"
1153182fc7bSGleb SmirnoffInitialize structure located at
1160b79fedbSJohn Baldwin.Fa rw
1170b79fedbSJohn Baldwinas reader/writer lock, described by name
1183182fc7bSGleb Smirnoff.Fa name .
1193182fc7bSGleb SmirnoffThe description is used solely for debugging purposes.
1200b79fedbSJohn BaldwinThis function must be called before any other operations
1210b79fedbSJohn Baldwinon the lock.
1220b79fedbSJohn Baldwin.It Fn rw_rlock "struct rwlock *rw"
1230b79fedbSJohn BaldwinLock
1240b79fedbSJohn Baldwin.Fa rw
1250b79fedbSJohn Baldwinas a reader.
1263182fc7bSGleb SmirnoffIf any thread holds this lock exclusively, the current thread blocks,
1270b79fedbSJohn Baldwinand its priority is propagated to the exclusive holder.
1283182fc7bSGleb SmirnoffThe
1293182fc7bSGleb Smirnoff.Fn rw_rlock
1303182fc7bSGleb Smirnofffunction can be called when the thread has already acquired reader
1313182fc7bSGleb Smirnoffaccess on
1320b79fedbSJohn Baldwin.Fa rw .
1333182fc7bSGleb SmirnoffThis is called
1343182fc7bSGleb Smirnoff.Dq "recursing on a lock" .
1350b79fedbSJohn Baldwin.It Fn rw_wlock "struct rwlock *rw"
1360b79fedbSJohn BaldwinLock
1370b79fedbSJohn Baldwin.Fa rw
1380b79fedbSJohn Baldwinas a writer.
1393182fc7bSGleb SmirnoffIf there are any shared owners of the lock, the current thread blocks.
1403182fc7bSGleb SmirnoffThe
1413182fc7bSGleb Smirnoff.Fn rw_wlock
1423182fc7bSGleb Smirnofffunction cannot be called recursively.
1430b79fedbSJohn Baldwin.It Fn rw_runlock "struct rwlock *rw"
1440b79fedbSJohn BaldwinThis function releases a shared lock previously acquired by
1453182fc7bSGleb Smirnoff.Fn rw_rlock .
1460b79fedbSJohn Baldwin.It Fn rw_wunlock "struct rwlock *rw"
1470b79fedbSJohn BaldwinThis function releases an exclusive lock previously acquired by
1483182fc7bSGleb Smirnoff.Fn rw_wlock .
14996cb5f99SJohn Baldwin.It Fn rw_try_upgrade "struct rwlock *rw"
15096cb5f99SJohn BaldwinAttempt to upgrade a single shared lock to an exclusive lock.
15196cb5f99SJohn BaldwinThe current thread must hold a shared lock of
15296cb5f99SJohn Baldwin.Fa rw .
15396cb5f99SJohn BaldwinThis will only succeed if the current thread holds the only shared lock on
15496cb5f99SJohn Baldwin.Fa rw ,
15596cb5f99SJohn Baldwinand it only holds a single shared lock.
15696cb5f99SJohn BaldwinIf the attempt succeeds
15796cb5f99SJohn Baldwin.Fn rw_try_upgrade
15896cb5f99SJohn Baldwinwill return a non-zero value,
15996cb5f99SJohn Baldwinand the current thread will hold an exclusive lock.
16096cb5f99SJohn BaldwinIf the attempt fails
16196cb5f99SJohn Baldwin.Fn rw_try_upgrade
16296cb5f99SJohn Baldwinwill return zero,
16396cb5f99SJohn Baldwinand the current thread will still hold a shared lock.
16496cb5f99SJohn Baldwin.It Fn rw_downgrade "struct rwlock *rw"
16596cb5f99SJohn BaldwinConvert an exclusive lock into a single shared lock.
16696cb5f99SJohn BaldwinThe current thread must hold an exclusive lock of
16796cb5f99SJohn Baldwin.Fa rw .
168e7573e7aSJohn Baldwin.It Fn rw_sleep "void *chan" "struct rwlock *rw" "int priority" "const char *wmesg" "int timo"
169e7573e7aSJohn BaldwinAtomically release
170e7573e7aSJohn Baldwin.Fa rw
171e7573e7aSJohn Baldwinwhile waiting for an event.
172e7573e7aSJohn BaldwinFor more details on the parameters to this function,
173e7573e7aSJohn Baldwinsee
174e7573e7aSJohn Baldwin.Xr sleep 9 .
1750b79fedbSJohn Baldwin.It Fn rw_initialized "struct rwlock *rw"
1760b79fedbSJohn BaldwinThis function returns non-zero if
1770b79fedbSJohn Baldwin.Fa rw
1783182fc7bSGleb Smirnoffhas been initialized, and zero otherwise.
1790b79fedbSJohn Baldwin.It Fn rw_destroy "struct rwlock *rw"
1803182fc7bSGleb SmirnoffThis functions destroys a lock previously initialized with
1813182fc7bSGleb Smirnoff.Fn rw_init .
1823182fc7bSGleb SmirnoffThe
1830b79fedbSJohn Baldwin.Fa rw
1840b79fedbSJohn Baldwinlock must be unlocked.
185dd348217SRobert Watson.It Fn rw_wowned "struct rwlock *rw"
186dd348217SRobert WatsonThis function returns a non-zero value if the current thread owns an
187dd348217SRobert Watsonexclusive lock on
188dd348217SRobert Watson.Fa rw .
1890b79fedbSJohn Baldwin.It Fn rw_assert "struct rwlock *rw" "int what"
1903182fc7bSGleb SmirnoffThis function allows assertions specified in
1913182fc7bSGleb Smirnoff.Fa what
1923182fc7bSGleb Smirnoffto be made about
1930b79fedbSJohn Baldwin.Fa rw .
1943182fc7bSGleb SmirnoffIf the assertions are not true and the kernel is compiled
1953182fc7bSGleb Smirnoffwith
1963182fc7bSGleb Smirnoff.Cd "options INVARIANTS"
1973182fc7bSGleb Smirnoffand
1983182fc7bSGleb Smirnoff.Cd "options INVARIANT_SUPPORT" ,
1993182fc7bSGleb Smirnoffthe kernel will panic.
2003182fc7bSGleb SmirnoffCurrently the following assertions are supported:
2013182fc7bSGleb Smirnoff.Bl -tag -width ".Dv RA_UNLOCKED"
2023182fc7bSGleb Smirnoff.It Dv RA_LOCKED
2030b79fedbSJohn BaldwinAssert that current thread holds either a shared or exclusive lock
2040b79fedbSJohn Baldwinof
2050b79fedbSJohn Baldwin.Fa rw .
2063182fc7bSGleb Smirnoff.It Dv RA_RLOCKED
2070b79fedbSJohn BaldwinAssert that current thread holds a shared lock of
2080b79fedbSJohn Baldwin.Fa rw .
2093182fc7bSGleb Smirnoff.It Dv RA_WLOCKED
2100b79fedbSJohn BaldwinAssert that current thread holds an exclusive lock of
2110b79fedbSJohn Baldwin.Fa rw .
2123182fc7bSGleb Smirnoff.It Dv RA_UNLOCKED
2130b79fedbSJohn BaldwinAssert that current thread holds neither a shared nor exclusive lock of
2140b79fedbSJohn Baldwin.Fa rw .
2153182fc7bSGleb Smirnoff.El
2163182fc7bSGleb Smirnoff.El
2173182fc7bSGleb Smirnoff.Sh SEE ALSO
218a280550aSJulian Elischer.Xr locking 9 ,
2193182fc7bSGleb Smirnoff.Xr mutex 9 ,
2203182fc7bSGleb Smirnoff.Xr panic 9 ,
2213182fc7bSGleb Smirnoff.Xr sema 9 ,
2223182fc7bSGleb Smirnoff.Xr sx 9
2233182fc7bSGleb Smirnoff.Sh HISTORY
2243182fc7bSGleb SmirnoffThese
2253182fc7bSGleb Smirnofffunctions appeared in
2263182fc7bSGleb Smirnoff.Fx 7.0 .
2273182fc7bSGleb Smirnoff.Sh AUTHORS
2283182fc7bSGleb Smirnoff.An -nosplit
2293182fc7bSGleb SmirnoffThe
2303182fc7bSGleb Smirnoff.Nm
2313182fc7bSGleb Smirnofffacility was written by
2323182fc7bSGleb Smirnoff.An "John Baldwin" .
2333182fc7bSGleb SmirnoffThis manual page was written by
2343182fc7bSGleb Smirnoff.An "Gleb Smirnoff" .
2350b79fedbSJohn Baldwin.Sh BUGS
2360b79fedbSJohn BaldwinIf
2370b79fedbSJohn Baldwin.Dv WITNESS
2380b79fedbSJohn Baldwinis not included in the kernel,
2390b79fedbSJohn Baldwinthen it is impossible to assert that the current thread does or does not
2407d3052bbSJohn Baldwinhold a read lock.
2410b79fedbSJohn BaldwinIn the
242bd84dd2fSRuslan Ermilov.Pf non- Dv WITNESS
2430b79fedbSJohn Baldwincase, the
2440b79fedbSJohn Baldwin.Dv RA_LOCKED
2450b79fedbSJohn Baldwinand
2460b79fedbSJohn Baldwin.Dv RA_RLOCKED
2477d3052bbSJohn Baldwinassertions merely check that some thread holds a read lock.
2480b79fedbSJohn Baldwin.Pp
2490b79fedbSJohn BaldwinReader/writer is a bit of an awkward name.
2500b79fedbSJohn BaldwinAn
2510b79fedbSJohn Baldwin.Nm
2520b79fedbSJohn Baldwincan also be called a
2530b79fedbSJohn Baldwin.Dq Robert Watson
2540b79fedbSJohn Baldwinlock if desired.
255