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