xref: /freebsd/share/man/man9/locking.9 (revision 815e47727edf9d819ab670fdf6a0a18e797ba909)
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.\"
27815e4772SEdward Tomasz Napierala.Dd January 29, 2010
280929bf8eSJulian Elischer.Dt LOCKING 9
290929bf8eSJulian Elischer.Os
300929bf8eSJulian Elischer.Sh NAME
3146d98f57SXin LI.Nm locking
320929bf8eSJulian Elischer.Nd kernel synchronization primitives
330929bf8eSJulian Elischer.Sh DESCRIPTION
340929bf8eSJulian ElischerThe
350929bf8eSJulian Elischer.Em FreeBSD
360929bf8eSJulian Elischerkernel is written to run across multiple CPUs and as such requires
374ff78a9cSJulian Elischerseveral different synchronization primitives to allow the developers
380929bf8eSJulian Elischerto safely access and manipulate the many data types required.
390929bf8eSJulian Elischer.Pp
400929bf8eSJulian ElischerThese include:
410929bf8eSJulian Elischer.Bl -enum
420929bf8eSJulian Elischer.It
43815e4772SEdward Tomasz NapieralaMutexes
440929bf8eSJulian Elischer.It
45815e4772SEdward Tomasz NapieralaSpin mutexes
460929bf8eSJulian Elischer.It
47815e4772SEdward Tomasz NapieralaPool mutexes
480929bf8eSJulian Elischer.It
49815e4772SEdward Tomasz NapieralaShared/exclusive locks
500929bf8eSJulian Elischer.It
51815e4772SEdward Tomasz NapieralaReader/writer locks
520929bf8eSJulian Elischer.It
53815e4772SEdward Tomasz NapieralaRead-mostly locks
54f53d15feSStephan Uphoff.It
55815e4772SEdward Tomasz NapieralaCounting semaphores
560929bf8eSJulian Elischer.It
570929bf8eSJulian ElischerCondition variables
580929bf8eSJulian Elischer.It
590929bf8eSJulian ElischerSleep/wakeup
600929bf8eSJulian Elischer.It
610929bf8eSJulian ElischerGiant
620929bf8eSJulian Elischer.It
630929bf8eSJulian ElischerLockmanager locks
640929bf8eSJulian Elischer.El
650929bf8eSJulian Elischer.Pp
6653882c7cSJulian ElischerThe primitives interact and have a number of rules regarding how
6720f16ca0SJulian Elischerthey can and can not be combined.
68815e4772SEdward Tomasz NapieralaMany of these rules are checked using the
690929bf8eSJulian Elischer.Xr witness 4
700929bf8eSJulian Elischercode.
710929bf8eSJulian Elischer.Pp
7220f16ca0SJulian Elischer.Ss Mutexes
73815e4772SEdward Tomasz NapieralaMutexes are the most commonly used synchronization primitive in the kernel.
74815e4772SEdward Tomasz NapieralaThread acquires (locks) a mutex before accessing data shared with other
75815e4772SEdward Tomasz Napieralathreads (including interrupt threads), and releases (unlocks) it afterwards.
76815e4772SEdward Tomasz NapieralaIf the mutex cannot be acquired, the thread requesting it will block.
77815e4772SEdward Tomasz Napierala.Pp
78815e4772SEdward Tomasz NapieralaSleeping while holding mutex is generally prohibited.
7920f16ca0SJulian ElischerYou may only call the
800929bf8eSJulian Elischer.Xr sleep 9
8120f16ca0SJulian Elischercall via
820929bf8eSJulian Elischer.Fn msleep
830929bf8eSJulian Elischeror the new
840929bf8eSJulian Elischer.Fn mtx_sleep
8520f16ca0SJulian Elischervariant.
8620f16ca0SJulian ElischerThese will atomically drop the mutex and reacquire it
870929bf8eSJulian Elischeras part of waking up.
8820f16ca0SJulian ElischerThis is often however a
8920f16ca0SJulian Elischer.Em BAD
9020f16ca0SJulian Elischeridea because it generally relies on you having
9120f16ca0SJulian Elischersuch a good knowledge of all the call graph above you
9220f16ca0SJulian Elischerand what assumptions it is making that there are a lot
9320f16ca0SJulian Elischerof ways to make hard-to-find mistakes.
9420f16ca0SJulian ElischerFor example you MUST re-test all the assumptions you made before,
9520f16ca0SJulian Elischerall the way up the call graph to where you got the lock.
9620f16ca0SJulian ElischerYou can not just assume that mtx_sleep can be inserted anywhere.
9720f16ca0SJulian ElischerIf any caller above you has any mutex or
9820f16ca0SJulian Elischerrwlock, your sleep, will cause a panic.
9920f16ca0SJulian ElischerIf the sleep only happens rarely it may be years before the
10020f16ca0SJulian Elischerbad code path is found.
101815e4772SEdward Tomasz Napierala.Pp
102815e4772SEdward Tomasz NapieralaSee the
103815e4772SEdward Tomasz Napierala.Xr mutex 9
104815e4772SEdward Tomasz Napieralapage for more information.
105815e4772SEdward Tomasz Napierala.Ss Spin mutexes
106815e4772SEdward Tomasz NapieralaSpin mutexes are variation of basic mutexes; the main difference between
107815e4772SEdward Tomasz Napieralathe two is that spin mutexes never block - instead, they spin, waiting
108815e4772SEdward Tomasz Napieralafor the thread holding the lock, which runs on another CPU, to release it.
109815e4772SEdward Tomasz NapieralaDifferently from ordinary mutex, spin mutexes disable interrupts when acquired.
110815e4772SEdward Tomasz NapieralaSince disabling interrupts is expensive, they are also generally slower.
111815e4772SEdward Tomasz NapieralaSpin mutexes should only be used to protect data shared with primary
112815e4772SEdward Tomasz Napierala(INTR_FILTER) interrupt code.
113815e4772SEdward Tomasz NapieralaYou
114815e4772SEdward Tomasz Napierala.Em must not
115815e4772SEdward Tomasz Napieralado anything that deschedules the thread while you
116815e4772SEdward Tomasz Napieralaare holding a spin mutex.
117815e4772SEdward Tomasz Napierala.Ss Pool mutexes
118815e4772SEdward Tomasz NapieralaWith most synchronisaton primitives, such as mutexes, programmer must
119815e4772SEdward Tomasz Napieralaprovide a piece of allocated memory to hold the primitive.
120815e4772SEdward Tomasz NapieralaFor example, a mutex may be embedded inside the structure it protects.
121815e4772SEdward Tomasz NapieralaPool mutex is a variant of mutex without this requirement - to lock or unlock
122815e4772SEdward Tomasz Napieralaa pool mutex, one uses address of the structure being protected with it,
123815e4772SEdward Tomasz Napieralanot the mutex itself.
124815e4772SEdward Tomasz NapieralaPool mutexes are seldom used.
125815e4772SEdward Tomasz Napierala.Pp
126815e4772SEdward Tomasz NapieralaSee the
127815e4772SEdward Tomasz Napierala.Xr mtx_pool 9
128815e4772SEdward Tomasz Napieralapage for more information.
129815e4772SEdward Tomasz Napierala.Ss Reader/writer locks
1300929bf8eSJulian ElischerReader/writer locks allow shared access to protected data by multiple threads,
1310929bf8eSJulian Elischeror exclusive access by a single thread.
1320929bf8eSJulian ElischerThe threads with shared access are known as
1330929bf8eSJulian Elischer.Em readers
13420f16ca0SJulian Elischersince they should only read the protected data.
1350929bf8eSJulian ElischerA thread with exclusive access is known as a
1360929bf8eSJulian Elischer.Em writer
13720f16ca0SJulian Elischersince it may modify protected data.
1380929bf8eSJulian Elischer.Pp
1390929bf8eSJulian ElischerAlthough reader/writer locks look very similar to
1400929bf8eSJulian Elischer.Xr sx 9
14120f16ca0SJulian Elischer(see below) locks, their usage pattern is different.
14220f16ca0SJulian ElischerReader/writer locks can be treated as mutexes (see above and
1430929bf8eSJulian Elischer.Xr mutex 9 )
1440929bf8eSJulian Elischerwith shared/exclusive semantics.
14520f16ca0SJulian ElischerMore specifically, regular mutexes can be
14620f16ca0SJulian Elischerconsidered to be equivalent to a write-lock on an
14720f16ca0SJulian Elischer.Em rw_lock.
14820f16ca0SJulian ElischerIn the future this may in fact
14920f16ca0SJulian Elischerbecome literally the fact.
15020f16ca0SJulian ElischerAn
1510929bf8eSJulian Elischer.Em rw_lock
15220f16ca0SJulian Elischercan be locked while holding a regular mutex, but
15320f16ca0SJulian Elischercan
15420f16ca0SJulian Elischer.Em not
15520f16ca0SJulian Elischerbe held while sleeping.
1560929bf8eSJulian ElischerThe
1570929bf8eSJulian Elischer.Em rw_lock
1580929bf8eSJulian Elischerlocks have priority propagation like mutexes, but priority
1590929bf8eSJulian Elischercan be propagated only to an exclusive holder.
1600929bf8eSJulian ElischerThis limitation comes from the fact that shared owners
1610929bf8eSJulian Elischerare anonymous.
1620929bf8eSJulian ElischerAnother important property is that shared holders of
1630929bf8eSJulian Elischer.Em rw_lock
16420f16ca0SJulian Elischercan recurse, but exclusive locks are not allowed to recurse.
16520f16ca0SJulian ElischerThis ability should not be used lightly and
16620f16ca0SJulian Elischer.Em may go away.
16720f16ca0SJulian ElischerUsers of recursion in any locks should be prepared to
16820f16ca0SJulian Elischerdefend their decision against vigorous criticism.
169815e4772SEdward Tomasz Napierala.Pp
170815e4772SEdward Tomasz NapieralaSee the
171815e4772SEdward Tomasz Napierala.Xr rwlock 9
172815e4772SEdward Tomasz Napieralapage for more information.
173815e4772SEdward Tomasz Napierala.Ss Read-mostly locks
174f53d15feSStephan UphoffMostly reader locks are similar to
175f53d15feSStephan Uphoff.Em Reader/write
176f53d15feSStephan Uphofflocks but optimized for very infrequent
177f53d15feSStephan Uphoff.Em writer
178f53d15feSStephan Uphofflocking.
179f53d15feSStephan Uphoff.Em rm_lock
180f53d15feSStephan Uphofflocks implement full priority propagation by tracking shared owners
181f53d15feSStephan Uphoffusing a lock user supplied
182f53d15feSStephan Uphoff.Em tracker
183f53d15feSStephan Uphoffdata structure.
184815e4772SEdward Tomasz Napierala.Pp
185815e4772SEdward Tomasz NapieralaSee the
186815e4772SEdward Tomasz Napierala.Xr rmlock 9
187815e4772SEdward Tomasz Napieralapage for more information.
188815e4772SEdward Tomasz Napierala.Ss Shared/exclusive locks
18920f16ca0SJulian ElischerShared/exclusive locks are used to protect data that are read far more often
19020f16ca0SJulian Elischerthan they are written.
19120f16ca0SJulian ElischerMutexes are inherently more efficient than shared/exclusive locks, so
19220f16ca0SJulian Elischershared/exclusive locks should be used prudently.
19320f16ca0SJulian ElischerThe main reason for using an
19420f16ca0SJulian Elischer.Em sx_lock
19520f16ca0SJulian Elischeris that a thread may hold a shared or exclusive lock on an
19620f16ca0SJulian Elischer.Em sx_lock
19720f16ca0SJulian Elischerlock while sleeping.
19820f16ca0SJulian ElischerAs a consequence of this however, an
19920f16ca0SJulian Elischer.Em sx_lock
20020f16ca0SJulian Elischerlock may not be acquired while holding a mutex.
20120f16ca0SJulian ElischerThe reason for this is that, if one thread slept while holding an
20220f16ca0SJulian Elischer.Em sx_lock
20320f16ca0SJulian Elischerlock while another thread blocked on the same
20420f16ca0SJulian Elischer.Em sx_lock
20520f16ca0SJulian Elischerlock after acquiring a mutex, then the second thread would effectively
20620f16ca0SJulian Elischerend up sleeping while holding a mutex, which is not allowed.
20720f16ca0SJulian ElischerThe
20820f16ca0SJulian Elischer.Em sx_lock
20920f16ca0SJulian Elischershould be considered to be closely related to
21020f16ca0SJulian Elischer.Xr sleep 9 .
21120f16ca0SJulian ElischerIn fact it could in some cases be
21220f16ca0SJulian Elischerconsidered a conditional sleep.
213815e4772SEdward Tomasz Napierala.Pp
214815e4772SEdward Tomasz NapieralaSee the
215815e4772SEdward Tomasz Napierala.Xr sx 9
216815e4772SEdward Tomasz Napieralapage for more information.
217815e4772SEdward Tomasz Napierala.Ss Counting semaphores
218815e4772SEdward Tomasz NapieralaCounting semaphores provide a mechanism for synchronizing access
219815e4772SEdward Tomasz Napieralato a pool of resources.
220815e4772SEdward Tomasz NapieralaUnlike mutexes, semaphores do not have the concept of an owner,
221815e4772SEdward Tomasz Napieralaso they can be useful in situations where one thread needs
222815e4772SEdward Tomasz Napieralato acquire a resource, and another thread needs to release it.
223815e4772SEdward Tomasz NapieralaThey are largely deprecated.
224815e4772SEdward Tomasz Napierala.Pp
225815e4772SEdward Tomasz NapieralaSee the
226815e4772SEdward Tomasz Napierala.Xr sema 9
227815e4772SEdward Tomasz Napieralapage for more information.
2280929bf8eSJulian Elischer.Ss Condition variables
2294ff78a9cSJulian ElischerCondition variables are used in conjunction with mutexes to wait for
2304ff78a9cSJulian Elischerconditions to occur.
2310929bf8eSJulian ElischerA thread must hold the mutex before calling the
2320929bf8eSJulian Elischer.Fn cv_wait* ,
2330929bf8eSJulian Elischerfunctions.
2340929bf8eSJulian ElischerWhen a thread waits on a condition, the mutex
2350929bf8eSJulian Elischeris atomically released before the thread is blocked, then reacquired
2360929bf8eSJulian Elischerbefore the function call returns.
237815e4772SEdward Tomasz Napierala.Pp
238815e4772SEdward Tomasz NapieralaSee the
239815e4772SEdward Tomasz Napierala.Xr condvar 9
240815e4772SEdward Tomasz Napieralapage for more information.
2410929bf8eSJulian Elischer.Ss Giant
2420929bf8eSJulian ElischerGiant is a special instance of a sleep lock.
243fbe508ffSWarner LoshIt has several special characteristics.
244fbe508ffSWarner Losh.Bl -enum
245fbe508ffSWarner Losh.It
246fbe508ffSWarner LoshIt is recursive.
247fbe508ffSWarner Losh.It
248fbe508ffSWarner LoshDrivers can request that Giant be locked around them, but this is
249fbe508ffSWarner Loshgoing away.
250fbe508ffSWarner Losh.It
251fbe508ffSWarner LoshYou can sleep while it has recursed, but other recursive locks cannot.
252fbe508ffSWarner Losh.It
25320f16ca0SJulian ElischerGiant must be locked first before other locks.
254fbe508ffSWarner Losh.It
255fbe508ffSWarner LoshThere are places in the kernel that drop Giant and pick it back up
256fbe508ffSWarner Loshagain.
257fbe508ffSWarner LoshSleep locks will do this before sleeping.
258fbe508ffSWarner LoshParts of the Network or VM code may do this as well, depending on the
259fbe508ffSWarner Loshsetting of a sysctl.
260fbe508ffSWarner LoshThis means that you cannot count on Giant keeping other code from
261fbe508ffSWarner Loshrunning if your code sleeps, even if you want it to.
262fbe508ffSWarner Losh.El
2630929bf8eSJulian Elischer.Ss Sleep/wakeup
2640929bf8eSJulian ElischerThe functions
2650929bf8eSJulian Elischer.Fn tsleep ,
2660929bf8eSJulian Elischer.Fn msleep ,
2670929bf8eSJulian Elischer.Fn msleep_spin ,
2680929bf8eSJulian Elischer.Fn pause ,
2690929bf8eSJulian Elischer.Fn wakeup ,
2700929bf8eSJulian Elischerand
2710929bf8eSJulian Elischer.Fn wakeup_one
2720929bf8eSJulian Elischerhandle event-based thread blocking.
2734ff78a9cSJulian ElischerIf a thread must wait for an external event, it is put to sleep by
2740929bf8eSJulian Elischer.Fn tsleep ,
2750929bf8eSJulian Elischer.Fn msleep ,
2760929bf8eSJulian Elischer.Fn msleep_spin ,
2770929bf8eSJulian Elischeror
2780929bf8eSJulian Elischer.Fn pause .
2790929bf8eSJulian ElischerThreads may also wait using one of the locking primitive sleep routines
2800929bf8eSJulian Elischer.Xr mtx_sleep 9 ,
2810929bf8eSJulian Elischer.Xr rw_sleep 9 ,
2820929bf8eSJulian Elischeror
2830929bf8eSJulian Elischer.Xr sx_sleep 9 .
2840929bf8eSJulian Elischer.Pp
2850929bf8eSJulian ElischerThe parameter
2860929bf8eSJulian Elischer.Fa chan
2870929bf8eSJulian Elischeris an arbitrary address that uniquely identifies the event on which
2880929bf8eSJulian Elischerthe thread is being put to sleep.
2890929bf8eSJulian ElischerAll threads sleeping on a single
2900929bf8eSJulian Elischer.Fa chan
2910929bf8eSJulian Elischerare woken up later by
2920929bf8eSJulian Elischer.Fn wakeup ,
2930929bf8eSJulian Elischeroften called from inside an interrupt routine, to indicate that the
2940929bf8eSJulian Elischerresource the thread was blocking on is available now.
2950929bf8eSJulian Elischer.Pp
2960929bf8eSJulian ElischerSeveral of the sleep functions including
2970929bf8eSJulian Elischer.Fn msleep ,
2980929bf8eSJulian Elischer.Fn msleep_spin ,
2990929bf8eSJulian Elischerand the locking primitive sleep routines specify an additional lock
3000929bf8eSJulian Elischerparameter.
3010929bf8eSJulian ElischerThe lock will be released before sleeping and reacquired
3020929bf8eSJulian Elischerbefore the sleep routine returns.
3030929bf8eSJulian ElischerIf
3040929bf8eSJulian Elischer.Fa priority
3050929bf8eSJulian Elischerincludes the
3060929bf8eSJulian Elischer.Dv PDROP
3074ff78a9cSJulian Elischerflag, then the lock will not be reacquired before returning.
3080929bf8eSJulian ElischerThe lock is used to ensure that a condition can be checked atomically,
3090929bf8eSJulian Elischerand that the current thread can be suspended without missing a
3100929bf8eSJulian Elischerchange to the condition, or an associated wakeup.
3110929bf8eSJulian ElischerIn addition, all of the sleep routines will fully drop the
3120929bf8eSJulian Elischer.Va Giant
3130929bf8eSJulian Elischermutex
3140929bf8eSJulian Elischer(even if recursed)
3150929bf8eSJulian Elischerwhile the thread is suspended and will reacquire the
3160929bf8eSJulian Elischer.Va Giant
3170929bf8eSJulian Elischermutex before the function returns.
3180929bf8eSJulian Elischer.Pp
319815e4772SEdward Tomasz NapieralaSee the
320815e4772SEdward Tomasz Napierala.Xr sleep 9
321815e4772SEdward Tomasz Napieralapage for more information.
322815e4772SEdward Tomasz Napierala.Pp
323815e4772SEdward Tomasz Napierala.Ss Lockmanager locks
324815e4772SEdward Tomasz NapieralaShared/exclusive sleep locks, used mostly in
325815e4772SEdward Tomasz Napierala.Xr VFS 9 ,
326815e4772SEdward Tomasz Napieralain particular as a
327815e4772SEdward Tomasz Napierala.Xr vnode 9
328815e4772SEdward Tomasz Napieralalock.
329815e4772SEdward Tomasz NapieralaThey have features other lock types don't have, such as sleep timeout,
330815e4772SEdward Tomasz Napieralawriter starvation avoidance, draining, and interlock mutex, but this makes them
331815e4772SEdward Tomasz Napieralacomplicated to implement; for this reason, they are deprecated.
332815e4772SEdward Tomasz Napierala.Pp
33320f16ca0SJulian ElischerSee the
3340929bf8eSJulian Elischer.Xr lock 9
3350929bf8eSJulian Elischerpage for more information.
336815e4772SEdward Tomasz Napierala.Sh INTERACTIONS
337c2c54c3dSJulian Elischer.Ss Interaction table.
3380929bf8eSJulian ElischerThe following table shows what you can and can not do if you hold
339f9d63aecSXin LIone of the synchronization primitives discussed here:
3400929bf8eSJulian Elischer(someone who knows what they are talking about should write this table)
3410929bf8eSJulian Elischer.Bl -column ".Ic xxxxxxxxxxxxxxxxxxxx" ".Xr XXXXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXX" -offset indent
3420929bf8eSJulian Elischer.It Xo
343f53d15feSStephan Uphoff.Em "You have: You want:" Ta Spin_mtx Ta Slp_mtx Ta sx_lock Ta rw_lock Ta rm_lock Ta sleep
3440929bf8eSJulian Elischer.Xc
345f53d15feSStephan Uphoff.It Ic SPIN mutex  Ta \&ok-1 Ta \&no Ta \&no Ta \&no Ta \&no Ta \&no-3
346f53d15feSStephan Uphoff.It Ic Sleep mutex Ta \&ok Ta \&ok-1 Ta \&no Ta \&ok Ta \&ok Ta \&no-3
347f53d15feSStephan Uphoff.It Ic sx_lock     Ta \&ok Ta \&ok Ta \&ok-2 Ta \&ok Ta \&ok Ta \&ok-4
348f53d15feSStephan Uphoff.It Ic rw_lock     Ta \&ok Ta \&ok Ta \&no Ta \&ok-2 Ta \&ok Ta \&no-3
349f53d15feSStephan Uphoff.It Ic rm_lock     Ta \&ok Ta \&ok Ta \&no Ta \&ok Ta \&ok-2 Ta \&no
3500929bf8eSJulian Elischer.El
3510929bf8eSJulian Elischer.Pp
3520929bf8eSJulian Elischer.Em *1
35320f16ca0SJulian ElischerRecursion is defined per lock.
35420f16ca0SJulian ElischerLock order is important.
3550929bf8eSJulian Elischer.Pp
3560929bf8eSJulian Elischer.Em *2
35720f16ca0SJulian Elischerreaders can recurse though writers can not.
35820f16ca0SJulian ElischerLock order is important.
3590929bf8eSJulian Elischer.Pp
3600929bf8eSJulian Elischer.Em *3
3614ff78a9cSJulian ElischerThere are calls atomically release this primitive when going to sleep
3620929bf8eSJulian Elischerand reacquire it on wakeup (e.g.
3630929bf8eSJulian Elischer.Fn mtx_sleep ,
36434e1b9e5SJulian Elischer.Fn rw_sleep
3650929bf8eSJulian Elischerand
366f9d63aecSXin LI.Fn msleep_spin
367f9d63aecSXin LI).
3680929bf8eSJulian Elischer.Pp
3690929bf8eSJulian Elischer.Em *4
37034e1b9e5SJulian ElischerThough one can sleep holding an sx lock, one can also use
3710929bf8eSJulian Elischer.Fn sx_sleep
3724ff78a9cSJulian Elischerwhich atomically release this primitive when going to sleep and
3734ff78a9cSJulian Elischerreacquire it on wakeup.
374c2c54c3dSJulian Elischer.Ss Context mode table.
3754ff78a9cSJulian ElischerThe next table shows what can be used in different contexts.
3764ff78a9cSJulian ElischerAt this time this is a rather easy to remember table.
377c2c54c3dSJulian Elischer.Bl -column ".Ic Xxxxxxxxxxxxxxxxxxxx" ".Xr XXXXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXXXX" ".Xr XXXXX" -offset indent
378c2c54c3dSJulian Elischer.It Xo
379f53d15feSStephan Uphoff.Em "Context:" Ta Spin_mtx Ta Slp_mtx Ta sx_lock Ta rw_lock Ta rm_lock Ta sleep
380c2c54c3dSJulian Elischer.Xc
381f53d15feSStephan Uphoff.It interrupt:  Ta \&ok Ta \&no Ta \&no Ta \&no Ta \&no Ta \&no
382f53d15feSStephan Uphoff.It idle:  Ta \&ok Ta \&no Ta \&no Ta \&no Ta \&no Ta \&no
383c2c54c3dSJulian Elischer.El
3840929bf8eSJulian Elischer.Sh SEE ALSO
3850929bf8eSJulian Elischer.Xr condvar 9 ,
3863111fc98SChristian Brueffer.Xr lock 9 ,
3870929bf8eSJulian Elischer.Xr mtx_pool 9 ,
38820f16ca0SJulian Elischer.Xr mutex 9 ,
389f53d15feSStephan Uphoff.Xr rmlock 9 ,
3900929bf8eSJulian Elischer.Xr rwlock 9 ,
3910929bf8eSJulian Elischer.Xr sema 9 ,
3920929bf8eSJulian Elischer.Xr sleep 9 ,
3933111fc98SChristian Brueffer.Xr sx 9 ,
394815e4772SEdward Tomasz Napierala.Xr witness 9 ,
395815e4772SEdward Tomasz Napierala.Xr LOCK_PROFILING 9
3960929bf8eSJulian Elischer.Sh HISTORY
3970929bf8eSJulian ElischerThese
3980929bf8eSJulian Elischerfunctions appeared in
3990929bf8eSJulian Elischer.Bsx 4.1
4000929bf8eSJulian Elischerthrough
4010929bf8eSJulian Elischer.Fx 7.0
402815e4772SEdward Tomasz Napierala.Sh BUGS
403815e4772SEdward Tomasz NapieralaThere are too many locking primitives to choose from.
404