10929bf8eSJulian Elischer.\" Copyright (c) 2007 Julian Elischer (julian - freebsd org ) 20929bf8eSJulian Elischer.\" All rights reserved. 30929bf8eSJulian Elischer.\" 40929bf8eSJulian Elischer.\" Redistribution and use in source and binary forms, with or without 50929bf8eSJulian Elischer.\" modification, are permitted provided that the following conditions 60929bf8eSJulian Elischer.\" are met: 70929bf8eSJulian Elischer.\" 1. Redistributions of source code must retain the above copyright 80929bf8eSJulian Elischer.\" notice, this list of conditions and the following disclaimer. 90929bf8eSJulian Elischer.\" 2. Redistributions in binary form must reproduce the above copyright 100929bf8eSJulian Elischer.\" notice, this list of conditions and the following disclaimer in the 110929bf8eSJulian Elischer.\" documentation and/or other materials provided with the distribution. 120929bf8eSJulian Elischer.\" 130929bf8eSJulian Elischer.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 140929bf8eSJulian Elischer.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 150929bf8eSJulian Elischer.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 160929bf8eSJulian Elischer.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 170929bf8eSJulian Elischer.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 180929bf8eSJulian Elischer.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 190929bf8eSJulian Elischer.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 200929bf8eSJulian Elischer.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 210929bf8eSJulian Elischer.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 220929bf8eSJulian Elischer.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 230929bf8eSJulian Elischer.\" SUCH DAMAGE. 240929bf8eSJulian Elischer.\" 250929bf8eSJulian Elischer.\" $FreeBSD$ 260929bf8eSJulian Elischer.\" 270929bf8eSJulian Elischer.Dd March 14, 2007 280929bf8eSJulian Elischer.Dt LOCKING 9 290929bf8eSJulian Elischer.Os 300929bf8eSJulian Elischer.Sh NAME 310929bf8eSJulian Elischer.Nm locking , 320929bf8eSJulian Elischer.Nd kernel synchronization primitives 330929bf8eSJulian Elischer.Sh SYNOPSIS 340929bf8eSJulian ElischerAll sorts of stuff to go here. 350929bf8eSJulian Elischer.Pp 360929bf8eSJulian Elischer.Sh DESCRIPTION 370929bf8eSJulian ElischerThe 380929bf8eSJulian Elischer.Em FreeBSD 390929bf8eSJulian Elischerkernel is written to run across multiple CPUs and as such requires 404ff78a9cSJulian Elischerseveral different synchronization primitives to allow the developers 410929bf8eSJulian Elischerto safely access and manipulate the many data types required. 420929bf8eSJulian Elischer.Pp 430929bf8eSJulian ElischerThese include: 440929bf8eSJulian Elischer.Bl -enum 450929bf8eSJulian Elischer.It 460929bf8eSJulian ElischerSpin Mutexes 470929bf8eSJulian Elischer.It 480929bf8eSJulian ElischerSleep Mutexes 490929bf8eSJulian Elischer.It 500929bf8eSJulian Elischerpool Mutexes 510929bf8eSJulian Elischer.It 520929bf8eSJulian ElischerShared-Exclusive locks 530929bf8eSJulian Elischer.It 540929bf8eSJulian ElischerReader-Writer locks 550929bf8eSJulian Elischer.It 564ff78a9cSJulian ElischerTurnstiles 570929bf8eSJulian Elischer.It 580929bf8eSJulian ElischerSemaphores 590929bf8eSJulian Elischer.It 600929bf8eSJulian ElischerCondition variables 610929bf8eSJulian Elischer.It 620929bf8eSJulian ElischerSleep/wakeup 630929bf8eSJulian Elischer.It 640929bf8eSJulian ElischerGiant 650929bf8eSJulian Elischer.It 660929bf8eSJulian ElischerLockmanager locks 670929bf8eSJulian Elischer.El 680929bf8eSJulian Elischer.Pp 6953882c7cSJulian ElischerThe primitives interact and have a number of rules regarding how 704ff78a9cSJulian Elischerthey can and can not be combined. There are too many for the average 714ff78a9cSJulian Elischerhuman mind and they keep changing. 724ff78a9cSJulian Elischer(if you disagree, please write replacement text) :-) 730929bf8eSJulian Elischer.Pp 744ff78a9cSJulian ElischerSome of these primitives may be used at the low (interrupt) level and 754ff78a9cSJulian Elischersome may not. 760929bf8eSJulian Elischer.Pp 770929bf8eSJulian ElischerThere are strict ordering requirements and for some of the types this 780929bf8eSJulian Elischeris checked using the 790929bf8eSJulian Elischer.Xr witness 4 800929bf8eSJulian Elischercode. 810929bf8eSJulian Elischer.Pp 820929bf8eSJulian Elischer.Ss SPIN Mutexes 8353882c7cSJulian ElischerMutexes are the basic primitive. 840929bf8eSJulian ElischerYou either hold it or you don't. 854ff78a9cSJulian ElischerIf you don't own it then you just spin, waiting for the holder (on 864ff78a9cSJulian Elischeranother CPU) to release it. 874ff78a9cSJulian ElischerHopefully they are doing something fast. 884ff78a9cSJulian ElischerYou can not do anything that deschedules the thread while you 894ff78a9cSJulian Elischerare holding a SPIN mutex. 900929bf8eSJulian Elischer.Ss Sleep Mutexes 914ff78a9cSJulian ElischerBasically sleep (regular) mutexes will deschedule the thread if the 924ff78a9cSJulian Elischermutex can not be acquired. 934ff78a9cSJulian ElischerAs in spin mutexes, you either get it or you don't. 940929bf8eSJulian ElischerYou may call the 950929bf8eSJulian Elischer.Xr sleep 9 960929bf8eSJulian Elischercall 970929bf8eSJulian Elischer.Fn msleep 980929bf8eSJulian Elischeror the new 990929bf8eSJulian Elischer.Fn mtx_sleep 1000929bf8eSJulian Elischervariant. These will atomically drop the mutex and reacquire it 1010929bf8eSJulian Elischeras part of waking up. 1020929bf8eSJulian Elischer.Ss Pool Mutexes 1034ff78a9cSJulian ElischerA variant of SLEEP mutexes where the allocation of the mutex is handled 1044ff78a9cSJulian Elischermore by the system. 1050929bf8eSJulian Elischer.Ss Sx_locks 1060929bf8eSJulian ElischerShared/exclusive locks are used to protect data that are read far more often 1070929bf8eSJulian Elischerthan they are written. 1080929bf8eSJulian ElischerMutexes are inherently more efficient than shared/exclusive locks, so 1090929bf8eSJulian Elischershared/exclusive locks should be used prudently. 1100929bf8eSJulian ElischerA thread may hold a shared or exclusive lock on an 1110929bf8eSJulian Elischer.Em sx_lock 1120929bf8eSJulian Elischerlock while sleeping. 1130929bf8eSJulian ElischerAs a result, an 11453882c7cSJulian Elischer.Em sx_lock 1150929bf8eSJulian Elischerlock may not be acquired while holding a mutex. 1160929bf8eSJulian ElischerOtherwise, if one thread slept while holding an 11753882c7cSJulian Elischer.Em sx_lock 1180929bf8eSJulian Elischerlock while another thread blocked on the same 11953882c7cSJulian Elischer.Em sx_lock 1200929bf8eSJulian Elischerlock after acquiring a mutex, then the second thread would effectively 1210929bf8eSJulian Elischerend up sleeping while holding a mutex, which is not allowed. 1220929bf8eSJulian Elischer.Ss Rw_locks 1230929bf8eSJulian ElischerReader/writer locks allow shared access to protected data by multiple threads, 1240929bf8eSJulian Elischeror exclusive access by a single thread. 1250929bf8eSJulian ElischerThe threads with shared access are known as 1260929bf8eSJulian Elischer.Em readers 1270929bf8eSJulian Elischersince they only read the protected data. 1280929bf8eSJulian ElischerA thread with exclusive access is known as a 1290929bf8eSJulian Elischer.Em writer 1300929bf8eSJulian Elischersince it can modify protected data. 1310929bf8eSJulian Elischer.Pp 1320929bf8eSJulian ElischerAlthough reader/writer locks look very similar to 1330929bf8eSJulian Elischer.Xr sx 9 1340929bf8eSJulian Elischerlocks, their usage pattern is different. 1350929bf8eSJulian ElischerReader/writer locks can be treated as mutexes (see 1360929bf8eSJulian Elischer.Xr mutex 9 ) 1370929bf8eSJulian Elischerwith shared/exclusive semantics. 1380929bf8eSJulian ElischerUnlike 1390929bf8eSJulian Elischer.Xr sx 9 , 1400929bf8eSJulian Elischeran 1410929bf8eSJulian Elischer.Em rw_lock 1420929bf8eSJulian Elischercan be locked while holding a non-spin mutex, and an 1430929bf8eSJulian Elischer.Em rw_lock 1440929bf8eSJulian Elischercannot be held while sleeping. 1450929bf8eSJulian ElischerThe 1460929bf8eSJulian Elischer.Em rw_lock 1470929bf8eSJulian Elischerlocks have priority propagation like mutexes, but priority 1480929bf8eSJulian Elischercan be propagated only to an exclusive holder. 1490929bf8eSJulian ElischerThis limitation comes from the fact that shared owners 1500929bf8eSJulian Elischerare anonymous. 1510929bf8eSJulian ElischerAnother important property is that shared holders of 1520929bf8eSJulian Elischer.Em rw_lock 1530929bf8eSJulian Elischercan recurse, 1540929bf8eSJulian Elischerbut exclusive locks are not allowed to recurse. 15553882c7cSJulian Elischer.Ss Turnstiles 1560929bf8eSJulian ElischerTurnstiles are used to hold a queue of threads blocked on 1574ff78a9cSJulian Elischernon-sleepable locks. 1584ff78a9cSJulian ElischerSleepable locks use condition variables to implement their queues. 1594ff78a9cSJulian ElischerTurnstiles differ from a sleep queue in that turnstile queue's 1604ff78a9cSJulian Elischerare assigned to a lock held by an owning thread. 1614ff78a9cSJulian ElischerThus, when one thread is enqueued onto a turnstile, it can lend its 1624ff78a9cSJulian Elischerpriority to the owning thread. 1630929bf8eSJulian Elischer.Ss Semaphores 1640929bf8eSJulian Elischer.Ss Condition variables 1654ff78a9cSJulian ElischerCondition variables are used in conjunction with mutexes to wait for 1664ff78a9cSJulian Elischerconditions to occur. 1670929bf8eSJulian ElischerA thread must hold the mutex before calling the 1680929bf8eSJulian Elischer.Fn cv_wait* , 1690929bf8eSJulian Elischerfunctions. 1700929bf8eSJulian ElischerWhen a thread waits on a condition, the mutex 1710929bf8eSJulian Elischeris atomically released before the thread is blocked, then reacquired 1720929bf8eSJulian Elischerbefore the function call returns. 1730929bf8eSJulian Elischer.Ss Giant 1740929bf8eSJulian ElischerGiant is a special instance of a sleep lock. 1750929bf8eSJulian Elischerit has several special characteristics. 1760929bf8eSJulian Elischer.Ss Sleep/wakeup 1770929bf8eSJulian ElischerThe functions 1780929bf8eSJulian Elischer.Fn tsleep , 1790929bf8eSJulian Elischer.Fn msleep , 1800929bf8eSJulian Elischer.Fn msleep_spin , 1810929bf8eSJulian Elischer.Fn pause , 1820929bf8eSJulian Elischer.Fn wakeup , 1830929bf8eSJulian Elischerand 1840929bf8eSJulian Elischer.Fn wakeup_one 1850929bf8eSJulian Elischerhandle event-based thread blocking. 1864ff78a9cSJulian ElischerIf a thread must wait for an external event, it is put to sleep by 1870929bf8eSJulian Elischer.Fn tsleep , 1880929bf8eSJulian Elischer.Fn msleep , 1890929bf8eSJulian Elischer.Fn msleep_spin , 1900929bf8eSJulian Elischeror 1910929bf8eSJulian Elischer.Fn pause . 1920929bf8eSJulian ElischerThreads may also wait using one of the locking primitive sleep routines 1930929bf8eSJulian Elischer.Xr mtx_sleep 9 , 1940929bf8eSJulian Elischer.Xr rw_sleep 9 , 1950929bf8eSJulian Elischeror 1960929bf8eSJulian Elischer.Xr sx_sleep 9 . 1970929bf8eSJulian Elischer.Pp 1980929bf8eSJulian ElischerThe parameter 1990929bf8eSJulian Elischer.Fa chan 2000929bf8eSJulian Elischeris an arbitrary address that uniquely identifies the event on which 2010929bf8eSJulian Elischerthe thread is being put to sleep. 2020929bf8eSJulian ElischerAll threads sleeping on a single 2030929bf8eSJulian Elischer.Fa chan 2040929bf8eSJulian Elischerare woken up later by 2050929bf8eSJulian Elischer.Fn wakeup , 2060929bf8eSJulian Elischeroften called from inside an interrupt routine, to indicate that the 2070929bf8eSJulian Elischerresource the thread was blocking on is available now. 2080929bf8eSJulian Elischer.Pp 2090929bf8eSJulian ElischerSeveral of the sleep functions including 2100929bf8eSJulian Elischer.Fn msleep , 2110929bf8eSJulian Elischer.Fn msleep_spin , 2120929bf8eSJulian Elischerand the locking primitive sleep routines specify an additional lock 2130929bf8eSJulian Elischerparameter. 2140929bf8eSJulian ElischerThe lock will be released before sleeping and reacquired 2150929bf8eSJulian Elischerbefore the sleep routine returns. 2160929bf8eSJulian ElischerIf 2170929bf8eSJulian Elischer.Fa priority 2180929bf8eSJulian Elischerincludes the 2190929bf8eSJulian Elischer.Dv PDROP 2204ff78a9cSJulian Elischerflag, then the lock will not be reacquired before returning. 2210929bf8eSJulian ElischerThe lock is used to ensure that a condition can be checked atomically, 2220929bf8eSJulian Elischerand that the current thread can be suspended without missing a 2230929bf8eSJulian Elischerchange to the condition, or an associated wakeup. 2240929bf8eSJulian ElischerIn addition, all of the sleep routines will fully drop the 2250929bf8eSJulian Elischer.Va Giant 2260929bf8eSJulian Elischermutex 2270929bf8eSJulian Elischer(even if recursed) 2280929bf8eSJulian Elischerwhile the thread is suspended and will reacquire the 2290929bf8eSJulian Elischer.Va Giant 2300929bf8eSJulian Elischermutex before the function returns. 2310929bf8eSJulian Elischer.Pp 2320929bf8eSJulian Elischer.Ss lockmanager locks 2330929bf8eSJulian ElischerLargly deprecated. See the 2340929bf8eSJulian Elischer.Xr lock 9 2350929bf8eSJulian Elischerpage for more information. 2360929bf8eSJulian ElischerI don't know what the downsides are but I'm sure someone will fill in this part. 237c2c54c3dSJulian Elischer.Sh Usage tables. 238c2c54c3dSJulian Elischer.Ss Interaction table. 2390929bf8eSJulian ElischerThe following table shows what you can and can not do if you hold 2404ff78a9cSJulian Elischerone of the synchronisation primitives discussed here: 2410929bf8eSJulian Elischer(someone who knows what they are talking about should write this table) 2420929bf8eSJulian Elischer.Bl -column ".Ic xxxxxxxxxxxxxxxxxxxx" ".Xr XXXXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXX" -offset indent 2430929bf8eSJulian Elischer.It Xo 2440929bf8eSJulian Elischer.Em "You have: You want:" Ta Spin_mtx Ta Slp_mtx Ta sx_lock Ta rw_lock Ta sleep 2450929bf8eSJulian Elischer.Xc 2460929bf8eSJulian Elischer.It Ic SPIN mutex Ta \&ok Ta \&no Ta \&no Ta \&no Ta \&no-3 2470929bf8eSJulian Elischer.It Ic Sleep mutex Ta \&ok Ta \&ok-1 Ta \&no Ta \&ok Ta \&no-3 24834e1b9e5SJulian Elischer.It Ic sx_lock Ta \&ok Ta \&no Ta \&ok-2 Ta \&no Ta \&ok-4 24934e1b9e5SJulian Elischer.It Ic rw_lock Ta \&ok Ta \&ok Ta \&no Ta \&ok-2 Ta \&no-3 2500929bf8eSJulian Elischer.El 2510929bf8eSJulian Elischer.Pp 2520929bf8eSJulian Elischer.Em *1 2534ff78a9cSJulian ElischerRecursion is defined per lock. Lock order is important. 2540929bf8eSJulian Elischer.Pp 2550929bf8eSJulian Elischer.Em *2 2564ff78a9cSJulian Elischerreaders can recurse though writers can not. Lock order is important. 2570929bf8eSJulian Elischer.Pp 2580929bf8eSJulian Elischer.Em *3 2594ff78a9cSJulian ElischerThere are calls atomically release this primitive when going to sleep 2600929bf8eSJulian Elischerand reacquire it on wakeup (e.g. 2610929bf8eSJulian Elischer.Fn mtx_sleep , 26234e1b9e5SJulian Elischer.Fn rw_sleep 2630929bf8eSJulian Elischerand 2640929bf8eSJulian Elischer.Fn msleep_spin ). 2650929bf8eSJulian Elischer.Pp 2660929bf8eSJulian Elischer.Em *4 26734e1b9e5SJulian ElischerThough one can sleep holding an sx lock, one can also use 2680929bf8eSJulian Elischer.Fn sx_sleep 2694ff78a9cSJulian Elischerwhich atomically release this primitive when going to sleep and 2704ff78a9cSJulian Elischerreacquire it on wakeup. 271c2c54c3dSJulian Elischer.Ss Context mode table. 2724ff78a9cSJulian ElischerThe next table shows what can be used in different contexts. 2734ff78a9cSJulian ElischerAt this time this is a rather easy to remember table. 274c2c54c3dSJulian Elischer.Bl -column ".Ic Xxxxxxxxxxxxxxxxxxxx" ".Xr XXXXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXX" -offset indent 275c2c54c3dSJulian Elischer.It Xo 276c2c54c3dSJulian Elischer.Em "Context:" Ta Spin_mtx Ta Slp_mtx Ta sx_lock Ta rw_lock Ta sleep 277c2c54c3dSJulian Elischer.Xc 278c2c54c3dSJulian Elischer.It interrupt: Ta \&ok Ta \&no Ta \&no Ta \&no Ta \&no 279c2c54c3dSJulian Elischer.It idle: Ta \&ok Ta \&no Ta \&no Ta \&no Ta \&no 280c2c54c3dSJulian Elischer.El 281c2c54c3dSJulian Elischer.Xc 2820929bf8eSJulian Elischer.Sh SEE ALSO 2830929bf8eSJulian Elischer.Xr condvar 9 , 2840929bf8eSJulian Elischer.Xr lock 9 2850929bf8eSJulian Elischer.Xr mtx_pool 9 , 2860929bf8eSJulian Elischer.Xr rwlock 9 , 2870929bf8eSJulian Elischer.Xr sema 9 , 2880929bf8eSJulian Elischer.Xr sleep 9 , 2890929bf8eSJulian Elischer.Xr sx 9 2900929bf8eSJulian Elischer.Xr LOCK_PROFILING 9 , 2910929bf8eSJulian Elischer.Xr WITNESS 9 , 2920929bf8eSJulian Elischer.Sh HISTORY 2930929bf8eSJulian ElischerThese 2940929bf8eSJulian Elischerfunctions appeared in 2950929bf8eSJulian Elischer.Bsx 4.1 2960929bf8eSJulian Elischerthrough 2970929bf8eSJulian Elischer.Fx 7.0 298