summaryrefslogtreecommitdiff
path: root/static/freebsd/man9/mutex.9 4.html
blob: f676d026dd1de42f76320044bfb90342fb2be186 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
<table class="head">
  <tr>
    <td class="head-ltitle">MUTEX(9)</td>
    <td class="head-vol">Kernel Developer's Manual</td>
    <td class="head-rtitle">MUTEX(9)</td>
  </tr>
</table>
<div class="manual-text">
<section class="Sh">
<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
<p class="Pp"><code class="Nm">mutex</code>, <code class="Nm">mtx_init</code>,
    <code class="Nm">mtx_destroy</code>, <code class="Nm">mtx_lock</code>,
    <code class="Nm">mtx_lock_spin</code>,
    <code class="Nm">mtx_lock_flags</code>,
    <code class="Nm">mtx_lock_spin_flags</code>,
    <code class="Nm">mtx_trylock</code>,
    <code class="Nm">mtx_trylock_flags</code>,
    <code class="Nm">mtx_trylock_spin</code>,
    <code class="Nm">mtx_trylock_spin_flags</code>,
    <code class="Nm">mtx_unlock</code>, <code class="Nm">mtx_unlock_spin</code>,
    <code class="Nm">mtx_unlock_flags</code>,
    <code class="Nm">mtx_unlock_spin_flags</code>,
    <code class="Nm">mtx_sleep</code>, <code class="Nm">mtx_initialized</code>,
    <code class="Nm">mtx_owned</code>, <code class="Nm">mtx_recursed</code>,
    <code class="Nm">mtx_assert</code>, <code class="Nm">MTX_SYSINIT</code>
    &#x2014; <span class="Nd">kernel synchronization primitives</span></p>
</section>
<section class="Sh">
<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
<p class="Pp"><code class="In">#include
    &lt;<a class="In">sys/param.h</a>&gt;</code>
  <br/>
  <code class="In">#include &lt;<a class="In">sys/lock.h</a>&gt;</code>
  <br/>
  <code class="In">#include &lt;<a class="In">sys/mutex.h</a>&gt;</code></p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">mtx_init</code>(<var class="Fa" style="white-space: nowrap;">struct
    mtx *mutex</var>, <var class="Fa" style="white-space: nowrap;">const char
    *name</var>, <var class="Fa" style="white-space: nowrap;">const char
    *type</var>, <var class="Fa" style="white-space: nowrap;">int
  opts</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">mtx_destroy</code>(<var class="Fa" style="white-space: nowrap;">struct
    mtx *mutex</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">mtx_lock</code>(<var class="Fa" style="white-space: nowrap;">struct
    mtx *mutex</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">mtx_lock_spin</code>(<var class="Fa" style="white-space: nowrap;">struct
    mtx *mutex</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">mtx_lock_flags</code>(<var class="Fa" style="white-space: nowrap;">struct
    mtx *mutex</var>, <var class="Fa" style="white-space: nowrap;">int
    flags</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">mtx_lock_spin_flags</code>(<var class="Fa" style="white-space: nowrap;">struct
    mtx *mutex</var>, <var class="Fa" style="white-space: nowrap;">int
    flags</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">mtx_trylock</code>(<var class="Fa" style="white-space: nowrap;">struct
    mtx *mutex</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">mtx_trylock_flags</code>(<var class="Fa" style="white-space: nowrap;">struct
    mtx *mutex</var>, <var class="Fa" style="white-space: nowrap;">int
    flags</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">mtx_trylock_spin</code>(<var class="Fa" style="white-space: nowrap;">struct
    mtx *mutex</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">mtx_trylock_spin_flags</code>(<var class="Fa" style="white-space: nowrap;">struct
    mtx *mutex</var>, <var class="Fa" style="white-space: nowrap;">int
    flags</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">mtx_unlock</code>(<var class="Fa" style="white-space: nowrap;">struct
    mtx *mutex</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">mtx_unlock_spin</code>(<var class="Fa" style="white-space: nowrap;">struct
    mtx *mutex</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">mtx_unlock_flags</code>(<var class="Fa" style="white-space: nowrap;">struct
    mtx *mutex</var>, <var class="Fa" style="white-space: nowrap;">int
    flags</var>);</p>
<p class="Pp"><var class="Ft">void</var>
  <br/>
  <code class="Fn">mtx_unlock_spin_flags</code>(<var class="Fa" style="white-space: nowrap;">struct
    mtx *mutex</var>, <var class="Fa" style="white-space: nowrap;">int
    flags</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">mtx_sleep</code>(<var class="Fa" style="white-space: nowrap;">void
    *chan</var>, <var class="Fa" style="white-space: nowrap;">struct mtx
    *mtx</var>, <var class="Fa" style="white-space: nowrap;">int priority</var>,
    <var class="Fa" style="white-space: nowrap;">const char *wmesg</var>,
    <var class="Fa" style="white-space: nowrap;">int timo</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">mtx_initialized</code>(<var class="Fa" style="white-space: nowrap;">const
    struct mtx *mutex</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">mtx_owned</code>(<var class="Fa" style="white-space: nowrap;">const
    struct mtx *mutex</var>);</p>
<p class="Pp"><var class="Ft">int</var>
  <br/>
  <code class="Fn">mtx_recursed</code>(<var class="Fa" style="white-space: nowrap;">const
    struct mtx *mutex</var>);</p>
<p class="Pp">
  <br/>
  <code class="Cd">options INVARIANTS</code>
  <br/>
  <code class="Cd">options INVARIANT_SUPPORT</code>
  <br/>
  <var class="Ft">void</var>
  <br/>
  <code class="Fn">mtx_assert</code>(<var class="Fa" style="white-space: nowrap;">const
    struct mtx *mutex</var>, <var class="Fa" style="white-space: nowrap;">int
    what</var>);</p>
<p class="Pp"><code class="In">#include
    &lt;<a class="In">sys/kernel.h</a>&gt;</code></p>
<p class="Pp"><code class="Fn">MTX_SYSINIT</code>(<var class="Fa" style="white-space: nowrap;">name</var>,
    <var class="Fa" style="white-space: nowrap;">struct mtx *mtx</var>,
    <var class="Fa" style="white-space: nowrap;">const char *description</var>,
    <var class="Fa" style="white-space: nowrap;">int opts</var>);</p>
</section>
<section class="Sh">
<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
<p class="Pp">Mutexes are the most basic and primary method of thread
    synchronization. The major design considerations for mutexes are:</p>
<ol class="Bl-enum">
  <li>Acquiring and releasing uncontested mutexes should be as cheap as
      possible.</li>
  <li>They must have the information and storage space to support priority
      propagation.</li>
  <li>A thread must be able to recursively acquire a mutex, provided that the
      mutex is initialized to support recursion.</li>
</ol>
<p class="Pp">There are currently two flavors of mutexes, those that context
    switch when they block and those that do not.</p>
<p class="Pp">By default, <code class="Dv">MTX_DEF</code> mutexes will context
    switch when they are already held. As an optimization, they may spin for
    some amount of time before context switching. It is important to remember
    that since a thread may be preempted at any time, the possible context
    switch introduced by acquiring a mutex is guaranteed to not break anything
    that is not already broken.</p>
<p class="Pp">Mutexes which do not context switch are
    <code class="Dv">MTX_SPIN</code> mutexes. These should only be used to
    protect data shared with primary interrupt code. This includes interrupt
    filters and low level scheduling code. In all architectures both acquiring
    and releasing of a uncontested spin mutex is more expensive than the same
    operation on a non-spin mutex. In order to protect an interrupt service
    routine from blocking against itself all interrupts are either blocked or
    deferred on a processor while holding a spin lock. It is permissible to hold
    multiple spin mutexes.</p>
<p class="Pp">Once a spin mutex has been acquired it is not permissible to
    acquire a blocking mutex.</p>
<p class="Pp">The storage needed to implement a mutex is provided by a
    <var class="Vt">struct mtx</var>. In general this should be treated as an
    opaque object and referenced only with the mutex primitives.</p>
<p class="Pp" id="mtx_init">The
    <a class="permalink" href="#mtx_init"><code class="Fn">mtx_init</code></a>()
    function must be used to initialize a mutex before it can be passed to any
    of the other mutex functions. The <var class="Fa">name</var> option is used
    to identify the lock in debugging output etc. The <var class="Fa">type</var>
    option is used by the witness code to classify a mutex when doing checks of
    lock ordering. If <var class="Fa">type</var> is
    <code class="Dv">NULL</code>, <var class="Fa">name</var> is used in its
    place. The pointer passed in as <var class="Fa">name</var> and
    <var class="Fa">type</var> is saved rather than the data it points to. The
    data pointed to must remain stable until the mutex is destroyed. The
    <var class="Fa">opts</var> argument is used to set the type of mutex. It may
    contain either <code class="Dv">MTX_DEF</code> or
    <code class="Dv">MTX_SPIN</code> but not both. If the kernel has been
    compiled with <code class="Cd">option INVARIANTS</code>,
    <code class="Fn">mtx_init</code>() will assert that the
    <var class="Fa">mutex</var> has not been initialized multiple times without
    intervening calls to <code class="Fn">mtx_destroy</code>() unless the
    <code class="Dv">MTX_NEW</code> option is specified. See below for
    additional initialization options.</p>
<p class="Pp" id="mtx_lock">The
    <a class="permalink" href="#mtx_lock"><code class="Fn">mtx_lock</code></a>()
    function acquires a <code class="Dv">MTX_DEF</code> mutual exclusion lock on
    behalf of the currently running kernel thread. If another kernel thread is
    holding the mutex, the caller will be disconnected from the CPU until the
    mutex is available (i.e., it will block).</p>
<p class="Pp" id="mtx_lock_spin">The
    <a class="permalink" href="#mtx_lock_spin"><code class="Fn">mtx_lock_spin</code></a>()
    function acquires a <code class="Dv">MTX_SPIN</code> mutual exclusion lock
    on behalf of the currently running kernel thread. If another kernel thread
    is holding the mutex, the caller will spin until the mutex becomes
    available. Interrupts are disabled during the spin and remain disabled
    following the acquiring of the lock.</p>
<p class="Pp" id="mtx_init~2">It is possible for the same thread to recursively
    acquire a mutex with no ill effects, provided that the
    <code class="Dv">MTX_RECURSE</code> bit was passed to
    <a class="permalink" href="#mtx_init~2"><code class="Fn">mtx_init</code></a>()
    during the initialization of the mutex.</p>
<p class="Pp" id="mtx_lock_flags">The
    <a class="permalink" href="#mtx_lock_flags"><code class="Fn">mtx_lock_flags</code></a>()
    and
    <a class="permalink" href="#mtx_lock_spin_flags"><code class="Fn" id="mtx_lock_spin_flags">mtx_lock_spin_flags</code></a>()
    functions acquire a <code class="Dv">MTX_DEF</code> or
    <code class="Dv">MTX_SPIN</code> lock, respectively, and also accept a
    <var class="Fa">flags</var> argument. In both cases, the only flags
    presently available for lock acquires are <code class="Dv">MTX_QUIET</code>
    and <code class="Dv">MTX_RECURSE</code>. If the
    <code class="Dv">MTX_QUIET</code> bit is turned on in the
    <var class="Fa">flags</var> argument, then if
    <code class="Dv">KTR_LOCK</code> tracing is being done, it will be silenced
    during the lock acquire. If the <code class="Dv">MTX_RECURSE</code> bit is
    turned on in the <var class="Fa">flags</var> argument, then the mutex can be
    acquired recursively.</p>
<p class="Pp" id="mtx_trylock">The
    <a class="permalink" href="#mtx_trylock"><code class="Fn">mtx_trylock</code></a>()
    and
    <a class="permalink" href="#mtx_trylock_spin"><code class="Fn" id="mtx_trylock_spin">mtx_trylock_spin</code></a>()
    functions attempt to acquire a <code class="Dv">MTX_DEF</code> or
    <code class="Dv">MTX_SPIN</code> mutex, respectively, pointed to by
    <var class="Fa">mutex</var>. If the mutex cannot be immediately acquired,
    the functions will return 0, otherwise the mutex will be acquired and a
    non-zero value will be returned.</p>
<p class="Pp" id="mtx_trylock_flags">The
    <a class="permalink" href="#mtx_trylock_flags"><code class="Fn">mtx_trylock_flags</code></a>()
    and
    <a class="permalink" href="#mtx_trylock_spin_flags"><code class="Fn" id="mtx_trylock_spin_flags">mtx_trylock_spin_flags</code></a>()
    functions have the same behavior as <code class="Fn">mtx_trylock</code>()
    and <code class="Fn">mtx_trylock_spin</code>() respectively, but should be
    used when the caller desires to pass in a <var class="Fa">flags</var> value.
    Presently, the only valid value in the <code class="Fn">mtx_trylock</code>()
    and <code class="Fn">mtx_trylock_spin</code>() cases is
    <code class="Dv">MTX_QUIET</code>, and its effects are identical to those
    described for <code class="Fn">mtx_lock</code>() above.</p>
<p class="Pp" id="mtx_unlock">The
    <a class="permalink" href="#mtx_unlock"><code class="Fn">mtx_unlock</code></a>()
    function releases a <code class="Dv">MTX_DEF</code> mutual exclusion lock.
    The current thread may be preempted if a higher priority thread is waiting
    for the mutex.</p>
<p class="Pp" id="mtx_unlock_spin">The
    <a class="permalink" href="#mtx_unlock_spin"><code class="Fn">mtx_unlock_spin</code></a>()
    function releases a <code class="Dv">MTX_SPIN</code> mutual exclusion
  lock.</p>
<p class="Pp" id="mtx_unlock_flags">The
    <a class="permalink" href="#mtx_unlock_flags"><code class="Fn">mtx_unlock_flags</code></a>()
    and
    <a class="permalink" href="#mtx_unlock_spin_flags"><code class="Fn" id="mtx_unlock_spin_flags">mtx_unlock_spin_flags</code></a>()
    functions behave in exactly the same way as do the standard mutex unlock
    routines above, while also allowing a <var class="Fa">flags</var> argument
    which may specify <code class="Dv">MTX_QUIET</code>. The behavior of
    <code class="Dv">MTX_QUIET</code> is identical to its behavior in the mutex
    lock routines.</p>
<p class="Pp" id="mtx_destroy">The
    <a class="permalink" href="#mtx_destroy"><code class="Fn">mtx_destroy</code></a>()
    function is used to destroy <var class="Fa">mutex</var> so the data
    associated with it may be freed or otherwise overwritten. Any mutex which is
    destroyed must previously have been initialized with
    <code class="Fn">mtx_init</code>(). It is permissible to have a single hold
    count on a mutex when it is destroyed. It is not permissible to hold the
    mutex recursively, or have another thread blocked on the mutex when it is
    destroyed.</p>
<p class="Pp" id="mtx_sleep">The
    <a class="permalink" href="#mtx_sleep"><code class="Fn">mtx_sleep</code></a>()
    function is used to atomically release <var class="Fa">mtx</var> while
    waiting for an event. For more details on the parameters to this function,
    see <a class="Xr">sleep(9)</a>.</p>
<p class="Pp" id="mtx_initialized">The
    <a class="permalink" href="#mtx_initialized"><code class="Fn">mtx_initialized</code></a>()
    function returns non-zero if <var class="Fa">mutex</var> has been
    initialized and zero otherwise.</p>
<p class="Pp" id="mtx_owned">The
    <a class="permalink" href="#mtx_owned"><code class="Fn">mtx_owned</code></a>()
    function returns non-zero if the current thread holds
    <var class="Fa">mutex</var>. If the current thread does not hold
    <var class="Fa">mutex</var> zero is returned.</p>
<p class="Pp" id="mtx_recursed">The
    <a class="permalink" href="#mtx_recursed"><code class="Fn">mtx_recursed</code></a>()
    function returns non-zero if the <var class="Fa">mutex</var> is recursed.
    This check should only be made if the running thread already owns
    <var class="Fa">mutex</var>.</p>
<p class="Pp" id="mtx_assert">The
    <a class="permalink" href="#mtx_assert"><code class="Fn">mtx_assert</code></a>()
    function allows assertions specified in <var class="Fa">what</var> to be
    made about <var class="Fa">mutex</var>. If the assertions are not true and
    the kernel is compiled with <code class="Cd">options INVARIANTS</code> and
    <code class="Cd">options INVARIANT_SUPPORT</code>, the kernel will panic.
    Currently the following assertions are supported:</p>
<dl class="Bl-tag">
  <dt id="MA_OWNED"><a class="permalink" href="#MA_OWNED"><code class="Dv">MA_OWNED</code></a></dt>
  <dd>Assert that the current thread holds the mutex pointed to by the first
      argument.</dd>
  <dt id="MA_NOTOWNED"><a class="permalink" href="#MA_NOTOWNED"><code class="Dv">MA_NOTOWNED</code></a></dt>
  <dd>Assert that the current thread does not hold the mutex pointed to by the
      first argument.</dd>
  <dt id="MA_RECURSED"><a class="permalink" href="#MA_RECURSED"><code class="Dv">MA_RECURSED</code></a></dt>
  <dd>Assert that the current thread has recursed on the mutex pointed to by the
      first argument. This assertion is only valid in conjunction with
      <code class="Dv">MA_OWNED</code>.</dd>
  <dt id="MA_NOTRECURSED"><a class="permalink" href="#MA_NOTRECURSED"><code class="Dv">MA_NOTRECURSED</code></a></dt>
  <dd>Assert that the current thread has not recursed on the mutex pointed to by
      the first argument. This assertion is only valid in conjunction with
      <code class="Dv">MA_OWNED</code>.</dd>
</dl>
<p class="Pp" id="MTX_SYSINIT">The
    <a class="permalink" href="#MTX_SYSINIT"><code class="Fn">MTX_SYSINIT</code></a>()
    macro is used to generate a call to the
    <a class="permalink" href="#mtx_sysinit"><code class="Fn" id="mtx_sysinit">mtx_sysinit</code></a>()
    routine at system startup in order to initialize a given mutex lock. The
    parameters are the same as <code class="Fn">mtx_init</code>() but with an
    additional argument, <var class="Fa">name</var>, that is used in generating
    unique variable names for the related structures associated with the lock
    and the sysinit routine.</p>
<section class="Ss">
<h2 class="Ss" id="The_Default_Mutex_Type"><a class="permalink" href="#The_Default_Mutex_Type">The
  Default Mutex Type</a></h2>
<p class="Pp">Most kernel code should use the default lock type,
    <code class="Dv">MTX_DEF</code>. The default lock type will allow the thread
    to be disconnected from the CPU if the lock is already held by another
    thread. The implementation may treat the lock as a short term spin lock
    under some circumstances. However, it is always safe to use these forms of
    locks in an interrupt thread without fear of deadlock against an interrupted
    thread on the same CPU.</p>
</section>
<section class="Ss">
<h2 class="Ss" id="The_Spin_Mutex_Type"><a class="permalink" href="#The_Spin_Mutex_Type">The
  Spin Mutex Type</a></h2>
<p class="Pp">A <code class="Dv">MTX_SPIN</code> mutex will not relinquish the
    CPU when it cannot immediately get the requested lock, but will loop,
    waiting for the mutex to be released by another CPU. This could result in
    deadlock if another thread interrupted the thread which held a mutex and
    then tried to acquire the mutex. For this reason spin locks disable all
    interrupts on the local CPU.</p>
<p class="Pp">Spin locks are fairly specialized locks that are intended to be
    held for very short periods of time. Their primary purpose is to protect
    portions of the code that implement other synchronization primitives such as
    default mutexes, thread scheduling, and interrupt threads.</p>
</section>
<section class="Ss">
<h2 class="Ss" id="Initialization_Options"><a class="permalink" href="#Initialization_Options">Initialization
  Options</a></h2>
<p class="Pp">The options passed in the <var class="Fa">opts</var> argument of
    <a class="permalink" href="#mtx_init~3"><code class="Fn" id="mtx_init~3">mtx_init</code></a>()
    specify the mutex type. One of the <code class="Dv">MTX_DEF</code> or
    <code class="Dv">MTX_SPIN</code> options is required and only one of those
    two options may be specified. The possibilities are:</p>
<dl class="Bl-tag">
  <dt id="MTX_DEF"><a class="permalink" href="#MTX_DEF"><code class="Dv">MTX_DEF</code></a></dt>
  <dd>Default mutexes will always allow the current thread to be suspended to
      avoid deadlock conditions against interrupt threads. The implementation of
      this lock type may spin for a while before suspending the current
    thread.</dd>
  <dt id="MTX_SPIN"><a class="permalink" href="#MTX_SPIN"><code class="Dv">MTX_SPIN</code></a></dt>
  <dd>Spin mutexes will never relinquish the CPU. All interrupts are disabled on
      the local CPU while any spin lock is held.</dd>
  <dt id="MTX_RECURSE"><a class="permalink" href="#MTX_RECURSE"><code class="Dv">MTX_RECURSE</code></a></dt>
  <dd>Specifies that the initialized mutex is allowed to recurse. This bit must
      be present if the mutex is permitted to recurse.
    <p class="Pp" id="mtx_trylock~2">Note that neither
        <a class="permalink" href="#mtx_trylock~2"><code class="Fn">mtx_trylock</code></a>()
        nor
        <a class="permalink" href="#mtx_trylock_spin~2"><code class="Fn" id="mtx_trylock_spin~2">mtx_trylock_spin</code></a>()
        support recursion; that is, attempting to acquire an already-owned mutex
        fails.</p>
  </dd>
  <dt id="MTX_QUIET"><a class="permalink" href="#MTX_QUIET"><code class="Dv">MTX_QUIET</code></a></dt>
  <dd>Do not log any mutex operations for this lock.</dd>
  <dt id="MTX_NOWITNESS"><a class="permalink" href="#MTX_NOWITNESS"><code class="Dv">MTX_NOWITNESS</code></a></dt>
  <dd>Instruct <a class="Xr">witness(4)</a> to ignore this lock.</dd>
  <dt id="MTX_DUPOK"><a class="permalink" href="#MTX_DUPOK"><code class="Dv">MTX_DUPOK</code></a></dt>
  <dd>Witness should not log messages about duplicate locks being acquired.</dd>
  <dt id="MTX_NOPROFILE"><a class="permalink" href="#MTX_NOPROFILE"><code class="Dv">MTX_NOPROFILE</code></a></dt>
  <dd>Do not profile this lock.</dd>
  <dt id="MTX_NEW"><a class="permalink" href="#MTX_NEW"><code class="Dv">MTX_NEW</code></a></dt>
  <dd>Do not check for double-init.</dd>
</dl>
</section>
<section class="Ss">
<h2 class="Ss" id="Lock_and_Unlock_Flags"><a class="permalink" href="#Lock_and_Unlock_Flags">Lock
  and Unlock Flags</a></h2>
<p class="Pp">The flags passed to the <code class="Fn">mtx_lock_flags</code>(),
    <code class="Fn">mtx_lock_spin_flags</code>(),
    <code class="Fn">mtx_unlock_flags</code>(), and
    <code class="Fn">mtx_unlock_spin_flags</code>() functions provide some basic
    options to the caller, and are often used only under special circumstances
    to modify lock or unlock behavior. Standard locking and unlocking should be
    performed with the <code class="Fn">mtx_lock</code>(),
    <code class="Fn">mtx_lock_spin</code>(),
    <code class="Fn">mtx_unlock</code>(), and
    <code class="Fn">mtx_unlock_spin</code>() functions. Only if a flag is
    required should the corresponding flags-accepting routines be used.</p>
<p class="Pp">Options that modify mutex behavior:</p>
<dl class="Bl-tag">
  <dt id="MTX_QUIET~2"><a class="permalink" href="#MTX_QUIET~2"><code class="Dv">MTX_QUIET</code></a></dt>
  <dd>This option is used to quiet logging messages during individual mutex
      operations. This can be used to trim superfluous logging messages for
      debugging purposes.</dd>
</dl>
</section>
<section class="Ss">
<h2 class="Ss" id="Giant"><a class="permalink" href="#Giant">Giant</a></h2>
<p class="Pp">If <var class="Va">Giant</var> must be acquired, it must be
    acquired prior to acquiring other mutexes. Put another way: it is impossible
    to acquire <var class="Va">Giant</var> non-recursively while holding another
    mutex. It is possible to acquire other mutexes while holding
    <var class="Va">Giant</var>, and it is possible to acquire
    <var class="Va">Giant</var> recursively while holding other mutexes.</p>
</section>
<section class="Ss">
<h2 class="Ss" id="Sleeping"><a class="permalink" href="#Sleeping">Sleeping</a></h2>
<p class="Pp">Sleeping while holding a mutex (except for
    <var class="Va">Giant</var>) is never safe and should be avoided. There are
    numerous assertions which will fail if this is attempted.</p>
</section>
<section class="Ss">
<h2 class="Ss" id="Functions_Which_Access_Memory_in_Userspace"><a class="permalink" href="#Functions_Which_Access_Memory_in_Userspace">Functions
  Which Access Memory in Userspace</a></h2>
<p class="Pp">No mutexes should be held (except for <var class="Va">Giant</var>)
    across functions which access memory in userspace, such as
    <a class="Xr">copyin(9)</a>, <a class="Xr">copyout(9)</a>,
    <a class="Xr">uiomove(9)</a>, <a class="Xr">fuword(9)</a>, etc. No locks are
    needed when calling these functions.</p>
</section>
</section>
<section class="Sh">
<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
  ALSO</a></h1>
<p class="Pp"><a class="Xr">condvar(9)</a>, <a class="Xr">LOCK_PROFILING(9)</a>,
    <a class="Xr">locking(9)</a>, <a class="Xr">mtx_pool(9)</a>,
    <a class="Xr">panic(9)</a>, <a class="Xr">rwlock(9)</a>,
    <a class="Xr">sema(9)</a>, <a class="Xr">sleep(9)</a>,
    <a class="Xr">sx(9)</a></p>
</section>
<section class="Sh">
<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
<p class="Pp">These functions appeared in <span class="Ux">BSD/OS 4.1</span> and
    <span class="Ux">FreeBSD 5.0</span>. The
    <code class="Fn">mtx_trylock_spin</code>() function was added in
    <span class="Ux">FreeBSD 11.1</span>.</p>
</section>
</div>
<table class="foot">
  <tr>
    <td class="foot-date">February 17, 2023</td>
    <td class="foot-os">FreeBSD 15.0</td>
  </tr>
</table>