summaryrefslogtreecommitdiff
path: root/static/freebsd/man9/mutex.9 4.html
diff options
context:
space:
mode:
authorJacob McDonnell <jacob@jacobmcdonnell.com>2026-04-25 19:55:43 -0400
committerJacob McDonnell <jacob@jacobmcdonnell.com>2026-04-25 19:55:43 -0400
commitac5e55f5f2af5b92794c2aded46c6bae85b5f5ed (patch)
tree9367490586c84cba28652e443e3166d66c33b0d9 /static/freebsd/man9/mutex.9 4.html
parent253e67c8b3a72b3a4757fdbc5845297628db0a4a (diff)
docs: Added All FreeBSD Manuals
Diffstat (limited to 'static/freebsd/man9/mutex.9 4.html')
-rw-r--r--static/freebsd/man9/mutex.9 4.html456
1 files changed, 456 insertions, 0 deletions
diff --git a/static/freebsd/man9/mutex.9 4.html b/static/freebsd/man9/mutex.9 4.html
new file mode 100644
index 00000000..f676d026
--- /dev/null
+++ b/static/freebsd/man9/mutex.9 4.html
@@ -0,0 +1,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>