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 400929bf8eSJulian Elischerseveral different sychronization primatives 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 560929bf8eSJulian ElischerTurnstyles 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 690929bf8eSJulian ElischerThe primnatives interact and have a number of rules regarding how 700929bf8eSJulian Elischerthey can and can not be combined. Ther eare too many for the average humanmind and they 710929bf8eSJulian Elischerkeep changing. (if you disagree, please write replacement text) :-) 720929bf8eSJulian Elischer.Pp 730929bf8eSJulian ElischerSome of these primatives may be used at the low (interrupt) level and some may not. 740929bf8eSJulian Elischer.Pp 750929bf8eSJulian ElischerThere are strict ordering requirements and for some of the types this 760929bf8eSJulian Elischeris checked using the 770929bf8eSJulian Elischer.Xr witness 4 780929bf8eSJulian Elischercode. 790929bf8eSJulian Elischer.Pp 800929bf8eSJulian Elischer.Ss SPIN Mutexes 810929bf8eSJulian ElischerMutexes are the basic primative. 820929bf8eSJulian ElischerYou either hold it or you don't. 830929bf8eSJulian ElischerIf you don't own it then you just spin, waiting for the holder (on another CPU) 840929bf8eSJulian Elischerto release it. Hopefully they are doing something fast. You can not do anythign that 850929bf8eSJulian Elischerdeschedules the thread while you are holding a SPIN mutex. 860929bf8eSJulian Elischer.Ss Sleep Mutexes 870929bf8eSJulian ElischerBasically sleep (regular) mutexes will deschedule the thread if 880929bf8eSJulian Elischerthe mutex can not be acquired. As in spin mutexes, you either get it or you don't. 890929bf8eSJulian ElischerYou may call the 900929bf8eSJulian Elischer.Xr sleep 9 910929bf8eSJulian Elischercall 920929bf8eSJulian Elischer.Fn msleep 930929bf8eSJulian Elischeror the new 940929bf8eSJulian Elischer.Fn mtx_sleep 950929bf8eSJulian Elischervariant. These will atomically drop the mutex and reacquire it 960929bf8eSJulian Elischeras part of waking up. 970929bf8eSJulian Elischer.Ss Pool Mutexes 980929bf8eSJulian ElischerA variant of SLEEP mutexes where the allocation of the mutex is handled more by the system. 990929bf8eSJulian Elischer.Ss Sx_locks 1000929bf8eSJulian ElischerShared/exclusive locks are used to protect data that are read far more often 1010929bf8eSJulian Elischerthan they are written. 1020929bf8eSJulian ElischerMutexes are inherently more efficient than shared/exclusive locks, so 1030929bf8eSJulian Elischershared/exclusive locks should be used prudently. 1040929bf8eSJulian ElischerA thread may hold a shared or exclusive lock on an 1050929bf8eSJulian Elischer.Em sx_lock 1060929bf8eSJulian Elischerlock while sleeping. 1070929bf8eSJulian ElischerAs a result, an 1080929bf8eSJulian Elischer.Em sx_lockm 1090929bf8eSJulian Elischerlock may not be acquired while holding a mutex. 1100929bf8eSJulian ElischerOtherwise, if one thread slept while holding an 1110929bf8eSJulian Elischer.Em sx_lockm 1120929bf8eSJulian Elischerlock while another thread blocked on the same 1130929bf8eSJulian Elischer.Em sx_lockm 1140929bf8eSJulian Elischerlock after acquiring a mutex, then the second thread would effectively 1150929bf8eSJulian Elischerend up sleeping while holding a mutex, which is not allowed. 1160929bf8eSJulian Elischer.Ss Rw_locks 1170929bf8eSJulian ElischerReader/writer locks allow shared access to protected data by multiple threads, 1180929bf8eSJulian Elischeror exclusive access by a single thread. 1190929bf8eSJulian ElischerThe threads with shared access are known as 1200929bf8eSJulian Elischer.Em readers 1210929bf8eSJulian Elischersince they only read the protected data. 1220929bf8eSJulian ElischerA thread with exclusive access is known as a 1230929bf8eSJulian Elischer.Em writer 1240929bf8eSJulian Elischersince it can modify protected data. 1250929bf8eSJulian Elischer.Pp 1260929bf8eSJulian ElischerAlthough reader/writer locks look very similar to 1270929bf8eSJulian Elischer.Xr sx 9 1280929bf8eSJulian Elischerlocks, their usage pattern is different. 1290929bf8eSJulian ElischerReader/writer locks can be treated as mutexes (see 1300929bf8eSJulian Elischer.Xr mutex 9 ) 1310929bf8eSJulian Elischerwith shared/exclusive semantics. 1320929bf8eSJulian ElischerUnlike 1330929bf8eSJulian Elischer.Xr sx 9 , 1340929bf8eSJulian Elischeran 1350929bf8eSJulian Elischer.Em rw_lock 1360929bf8eSJulian Elischercan be locked while holding a non-spin mutex, and an 1370929bf8eSJulian Elischer.Em rw_lock 1380929bf8eSJulian Elischercannot be held while sleeping. 1390929bf8eSJulian ElischerThe 1400929bf8eSJulian Elischer.Em rw_lock 1410929bf8eSJulian Elischerlocks have priority propagation like mutexes, but priority 1420929bf8eSJulian Elischercan be propagated only to an exclusive holder. 1430929bf8eSJulian ElischerThis limitation comes from the fact that shared owners 1440929bf8eSJulian Elischerare anonymous. 1450929bf8eSJulian ElischerAnother important property is that shared holders of 1460929bf8eSJulian Elischer.Em rw_lock 1470929bf8eSJulian Elischercan recurse, 1480929bf8eSJulian Elischerbut exclusive locks are not allowed to recurse. 1490929bf8eSJulian Elischer.Ss Turnstyless 1500929bf8eSJulian ElischerTurnstiles are used to hold a queue of threads blocked on 1510929bf8eSJulian Elischernon-sleepable locks. Sleepable locks use condition variables to 1520929bf8eSJulian Elischerimplement their queues. Turnstiles differ from a sleep queue in that 1530929bf8eSJulian Elischerturnstile queue's are assigned to a lock held by an owning thread. Thus, 1540929bf8eSJulian Elischerwhen one thread is enqueued onto a turnstile, it can lend its priority 1550929bf8eSJulian Elischerto the owning thread. 1560929bf8eSJulian Elischer.Ss Semaphores 1570929bf8eSJulian Elischer.Ss Condition variables 1580929bf8eSJulian ElischerCondition variables are used in conjunction with mutexes to wait for conditions 1590929bf8eSJulian Elischerto occur. 1600929bf8eSJulian ElischerA thread must hold the mutex before calling the 1610929bf8eSJulian Elischer.Fn cv_wait* , 1620929bf8eSJulian Elischerfunctions. 1630929bf8eSJulian ElischerWhen a thread waits on a condition, the mutex 1640929bf8eSJulian Elischeris atomically released before the thread is blocked, then reacquired 1650929bf8eSJulian Elischerbefore the function call returns. 1660929bf8eSJulian Elischer.Ss Giant 1670929bf8eSJulian ElischerGiant is a special instance of a sleep lock. 1680929bf8eSJulian Elischerit has several special characteristics. 1690929bf8eSJulian Elischer.Ss Sleep/wakeup 1700929bf8eSJulian ElischerThe functions 1710929bf8eSJulian Elischer.Fn tsleep , 1720929bf8eSJulian Elischer.Fn msleep , 1730929bf8eSJulian Elischer.Fn msleep_spin , 1740929bf8eSJulian Elischer.Fn pause , 1750929bf8eSJulian Elischer.Fn wakeup , 1760929bf8eSJulian Elischerand 1770929bf8eSJulian Elischer.Fn wakeup_one 1780929bf8eSJulian Elischerhandle event-based thread blocking. 1790929bf8eSJulian ElischerIf a thread must wait for an 1800929bf8eSJulian Elischerexternal event, it is put to sleep by 1810929bf8eSJulian Elischer.Fn tsleep , 1820929bf8eSJulian Elischer.Fn msleep , 1830929bf8eSJulian Elischer.Fn msleep_spin , 1840929bf8eSJulian Elischeror 1850929bf8eSJulian Elischer.Fn pause . 1860929bf8eSJulian ElischerThreads may also wait using one of the locking primitive sleep routines 1870929bf8eSJulian Elischer.Xr mtx_sleep 9 , 1880929bf8eSJulian Elischer.Xr rw_sleep 9 , 1890929bf8eSJulian Elischeror 1900929bf8eSJulian Elischer.Xr sx_sleep 9 . 1910929bf8eSJulian Elischer.Pp 1920929bf8eSJulian ElischerThe parameter 1930929bf8eSJulian Elischer.Fa chan 1940929bf8eSJulian Elischeris an arbitrary address that uniquely identifies the event on which 1950929bf8eSJulian Elischerthe thread is being put to sleep. 1960929bf8eSJulian ElischerAll threads sleeping on a single 1970929bf8eSJulian Elischer.Fa chan 1980929bf8eSJulian Elischerare woken up later by 1990929bf8eSJulian Elischer.Fn wakeup , 2000929bf8eSJulian Elischeroften called from inside an interrupt routine, to indicate that the 2010929bf8eSJulian Elischerresource the thread was blocking on is available now. 2020929bf8eSJulian Elischer.Pp 2030929bf8eSJulian ElischerSeveral of the sleep functions including 2040929bf8eSJulian Elischer.Fn msleep , 2050929bf8eSJulian Elischer.Fn msleep_spin , 2060929bf8eSJulian Elischerand the locking primitive sleep routines specify an additional lock 2070929bf8eSJulian Elischerparameter. 2080929bf8eSJulian ElischerThe lock will be released before sleeping and reacquired 2090929bf8eSJulian Elischerbefore the sleep routine returns. 2100929bf8eSJulian ElischerIf 2110929bf8eSJulian Elischer.Fa priority 2120929bf8eSJulian Elischerincludes the 2130929bf8eSJulian Elischer.Dv PDROP 2140929bf8eSJulian Elischerflag, then 2150929bf8eSJulian Elischerthe lock will not be reacquired before returning. 2160929bf8eSJulian ElischerThe lock is used to ensure that a condition can be checked atomically, 2170929bf8eSJulian Elischerand that the current thread can be suspended without missing a 2180929bf8eSJulian Elischerchange to the condition, or an associated wakeup. 2190929bf8eSJulian ElischerIn addition, all of the sleep routines will fully drop the 2200929bf8eSJulian Elischer.Va Giant 2210929bf8eSJulian Elischermutex 2220929bf8eSJulian Elischer(even if recursed) 2230929bf8eSJulian Elischerwhile the thread is suspended and will reacquire the 2240929bf8eSJulian Elischer.Va Giant 2250929bf8eSJulian Elischermutex before the function returns. 2260929bf8eSJulian Elischer.Pp 2270929bf8eSJulian Elischer.Ss lockmanager locks 2280929bf8eSJulian ElischerLargly deprecated. See the 2290929bf8eSJulian Elischer.Xr lock 9 2300929bf8eSJulian Elischerpage for more information. 2310929bf8eSJulian ElischerI don't know what the downsides are but I'm sure someone will fill in this part. 2320929bf8eSJulian Elischer.Sh Interaction tables. 2330929bf8eSJulian ElischerThe following table shows what you can and can not do if you hold 2340929bf8eSJulian Elischerone of the synchronisation primatives discussed here: 2350929bf8eSJulian Elischer(someone who knows what they are talking about should write this table) 2360929bf8eSJulian Elischer.Bl -column ".Ic xxxxxxxxxxxxxxxxxxxx" ".Xr XXXXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXX" -offset indent 2370929bf8eSJulian Elischer.It Xo 2380929bf8eSJulian Elischer.Em "You have: You want:" Ta Spin_mtx Ta Slp_mtx Ta sx_lock Ta rw_lock Ta sleep 2390929bf8eSJulian Elischer.Xc 2400929bf8eSJulian Elischer.It Ic SPIN mutex Ta \&ok Ta \&no Ta \&no Ta \&no Ta \&no-3 2410929bf8eSJulian Elischer.It Ic Sleep mutex Ta \&ok Ta \&ok-1 Ta \&no Ta \&ok Ta \&no-3 2420929bf8eSJulian Elischer.It Ic sx_lock Ta \&ok Ta \&no Ta \&?? Ta \&no Ta \&ok-4 2430929bf8eSJulian Elischer.It Ic rw_lock Ta \&ok Ta \&no Ta \&no Ta \&ok-2 Ta \&no-3 2440929bf8eSJulian Elischer.El 2450929bf8eSJulian Elischer.Pp 2460929bf8eSJulian Elischer.Em *1 2470929bf8eSJulian ElischerRecursion is defined per lock. lock order is important. 2480929bf8eSJulian Elischer.Pp 2490929bf8eSJulian Elischer.Em *2 2500929bf8eSJulian Elischerreaders can recurse tough writers can not. lock order is important. 2510929bf8eSJulian Elischer.Pp 2520929bf8eSJulian Elischer.Em *3 2530929bf8eSJulian ElischerThere are calls atomically release this primative when going to sleep 2540929bf8eSJulian Elischerand reacquire it on wakeup (e.g. 2550929bf8eSJulian Elischer.Fn mtx_sleep , 2560929bf8eSJulian Elischer.Fn rw-sleep 2570929bf8eSJulian Elischerand 2580929bf8eSJulian Elischer.Fn msleep_spin). 2590929bf8eSJulian Elischer.Pp 2600929bf8eSJulian Elischer.Em *4 2610929bf8eSJulian ElischerOne can also use 2620929bf8eSJulian Elischer.Fn sx_sleep 2630929bf8eSJulian Elischerwhich atomically release this primative when going to sleep and reacquire it on wakeup. 2640929bf8eSJulian Elischer.Pp 2650929bf8eSJulian Elischer.Sh SEE ALSO 2660929bf8eSJulian Elischer.Xr condvar 9 , 2670929bf8eSJulian Elischer.Xr lock 9 2680929bf8eSJulian Elischer.Xr mtx_pool 9 , 2690929bf8eSJulian Elischer.Xr rwlock 9 , 2700929bf8eSJulian Elischer.Xr sema 9 , 2710929bf8eSJulian Elischer.Xr sleep 9 , 2720929bf8eSJulian Elischer.Xr sx 9 2730929bf8eSJulian Elischer.Xr LOCK_PROFILING 9 , 2740929bf8eSJulian Elischer.Xr WITNESS 9 , 2750929bf8eSJulian Elischer.Sh HISTORY 2760929bf8eSJulian ElischerThese 2770929bf8eSJulian Elischerfunctions appeared in 2780929bf8eSJulian Elischer.Bsx 4.1 2790929bf8eSJulian Elischerthrough 2800929bf8eSJulian Elischer.Fx 7.0 281