diff options
| author | Jacob McDonnell <jacob@jacobmcdonnell.com> | 2026-04-25 19:55:43 -0400 |
|---|---|---|
| committer | Jacob McDonnell <jacob@jacobmcdonnell.com> | 2026-04-25 19:55:43 -0400 |
| commit | ac5e55f5f2af5b92794c2aded46c6bae85b5f5ed (patch) | |
| tree | 9367490586c84cba28652e443e3166d66c33b0d9 /static/freebsd/man9/mutex.9 4.html | |
| parent | 253e67c8b3a72b3a4757fdbc5845297628db0a4a (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.html | 456 |
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> + — <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 + <<a class="In">sys/param.h</a>></code> + <br/> + <code class="In">#include <<a class="In">sys/lock.h</a>></code> + <br/> + <code class="In">#include <<a class="In">sys/mutex.h</a>></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 + <<a class="In">sys/kernel.h</a>></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> |
