xref: /freebsd/share/man/man9/rwlock.9 (revision b12455f34ee94a6386b658e8108277ca298e10fa)
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