mutex(9)
NAME
- mutex, mtx_init, mtx_lock, mtx_lock_spin, mtx_lock_flags, mtx_lock_spin_flags, mtx_trylock, mtx_trylock_flags,
- mtx_unlock,
mtx_unlock_spin, mtx_unlock_flags, mtx_unlock_spin_flags, - mtx_destroy,
mtx_initialized, mtx_owned, mtx_recursed, mtx_assert,
MTX_SYSINIT
nel synchronization primitives
SYNOPSIS
#include <sys/param.h> #include <sys/lock.h> #include <sys/mutex.h> void mtx_init(struct mtx *mutex, const char *name, const char *type, int opts); void mtx_lock(struct mtx *mutex); void mtx_lock_spin(struct mtx *mutex); void mtx_lock_flags(struct mtx *mutex, int flags); void mtx_lock_spin_flags(struct mtx *mutex, int flags); int mtx_trylock(struct mtx *mutex); int mtx_trylock_flags(struct mtx *mutex, int flags); void mtx_unlock(struct mtx *mutex); void mtx_unlock_spin(struct mtx *mutex); void mtx_unlock_flags(struct mtx *mutex, int flags); void mtx_unlock_spin_flags(struct mtx *mutex, int flags); void mtx_destroy(struct mtx *mutex); int mtx_initialized(struct mtx *mutex); int mtx_owned(struct mtx *mutex); int mtx_recursed(struct mtx *mutex); options INVARIANTS options INVARIANT_SUPPORT void mtx_assert(struct mtx *mutex, int what); #include <sys/kernel.h> MTX_SYSINIT(name, struct mutex *mtx, const char *description, int opts);
DESCRIPTION
- Mutexes are the most basic and primary method of thread syn
- chronization.
The major design considerations for mutexes are: - 1. Acquiring and releasing uncontested mutexes should be
- as cheap as
possible. - 2. They must have the information and storage space to
- support priority
propagation. - 3. A thread must be able to recursively acquire a mutex,
- provided that
the mutex is initialized to support recursion. - There are currently two flavors of mutexes, those that con
- text switch
when they block and those that do not. - By default, MTX_DEF 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 intro - duced by
acquiring a mutex is guaranteed to not break anything that - is not already
broken. - Mutexes which do not context switch are MTX_SPIN mutexes.
- These should
only be used to protect data shared with primary interrupt - code. This
includes INTR_FAST interrupt handlers and low level schedul - ing code. In
all architectures both acquiring and releasing of a uncon - tested 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.
- Once a spin mutex has been acquired it is not permissible to
- acquire a
blocking mutex. - The storage needed to implement a mutex is provided by a
- struct mtx. In
general this should be treated as an opaque object and ref - erenced only
with the mutex primitives. - The mtx_init() function must be used to initialize a mutex
- before it can
be passed to any of the other mutex functions. The name op - tion is used
to identify the lock in debugging output etc. The type op - tion is used by
the witness code to classify a mutex when doing checks of - lock ordering.
If type is NULL, name is used in its place. The pointer - passed in as
name and type is saved rather than the data it points to. - The data
pointed to must remain stable until the mutex is destroyed. - The opts
argument is used to set the type of mutex. It may contain - either MTX_DEF
or MTX_SPIN but not both. See below for additional initial - ization
options. It is not permissible to pass the same mutex to - mtx_init() multiple times without intervening calls to mtx_destroy().
- The mtx_lock() function acquires a MTX_DEF 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). - The mtx_lock_spin() function acquires a MTX_SPIN mutual ex
- clusion 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.
- It is possible for the same thread to recursively acquire a
- mutex with no
ill effects, provided that the MTX_RECURSE bit was passed to - mtx_init()
during the initialization of the mutex. - The mtx_lock_flags() and mtx_lock_spin_flags() functions ac
- quire a
MTX_DEF or MTX_SPIN lock, respectively, and also accept a - flags argument.
In both cases, the only flag presently available for lock - acquires is
MTX_QUIET. If the MTX_QUIET bit is turned on in the flags - argument, then
if KTR_LOCK tracing is being done, it will be silenced dur - ing the lock
acquire. - The mtx_trylock() attempts to acquire the MTX_DEF mutex
- pointed to by
mutex. If the mutex cannot be immediately acquired - mtx_trylock() will
return 0, otherwise the mutex will be acquired and a non-ze - ro value will
be returned. - The mtx_trylock_flags() function has the same behavior as
- mtx_trylock()
but should be used when the caller desires to pass in a - flags value.
Presently, the only valid value in the mtx_trylock() case is - MTX_QUIET,
and its effects are identical to those described for - mtx_lock() above.
- The mtx_unlock() function releases a MTX_DEF mutual exclu
- sion lock. The
current thread may be preempted if a higher priority thread - is waiting
for the mutex. - The mtx_unlock_spin() function releases a MTX_SPIN mutual
- exclusion lock.
- The mtx_unlock_flags() and mtx_unlock_spin_flags() functions
- behave in
exactly the same way as do the standard mutex unlock rou - tines above,
while also allowing a flags argument which may specify - MTX_QUIET. The
behavior of MTX_QUIET is identical to its behavior in the - mutex lock routines.
- The mtx_destroy() function is used to destroy mutex so the
- data associated with it may be freed or otherwise overwritten. Any mu
- tex which is
destroyed must previously have been initialized with - mtx_init(). 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. - The mtx_initialized() function returns non-zero if mutex has
- been initialized and zero otherwise.
- The mtx_owned() function returns non-zero if the current
- thread holds
mutex. If the current thread does not hold mutex zero is - returned.
- The mtx_recursed() function returns non-zero if the mutex is
- recursed.
This check should only be made if the running thread already - owns mutex.
- The mtx_assert() function allows assertions specified in
- what to be made
about mutex. If the assertions are not true and the kernel - is compiled
with options INVARIANTS and options INVARIANT_SUPPORT, the - kernel will
panic. Currently the following assertions are supported: - MA_OWNED Assert that the current thread holds the mu
- tex pointed to
by the first argument. - MA_NOTOWNED Assert that the current thread does not hold
- the mutex
pointed to by the first argument. - MA_RECURSED Assert that the current thread has recursed
- on the mutex
pointed to by the first argument. This as - sertion is only
valid in conjunction with MA_OWNED. - MA_NOTRECURSED Assert that the current thread has not re
- cursed on the
mutex pointed to by the first argument. - This assertion
is only valid in conjunction with MA_OWNED. - The MTX_SYSINIT() macro is used to generate a call to the
- mtx_sysinit()
routine at system startup in order to initialize a given mu - tex lock. The
parameters are the same as mtx_init() but with an additional - argument,
name, that is used in generating unique variable names for - the related
structures associated with the lock and the sysinit routine. - The Default Mutex Type
Most kernel code should use the default lock type, MTX_DEF. - 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.
- The Spin Mutex Type
A MTX_SPIN 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. - 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. - Initialization Options
The options passed in the opts argument of mtx_init() speci - fy the mutex
type. One of the MTX_DEF or MTX_SPIN options is required - and only one of
those two options may be specified. The possibilities are: - MTX_DEF 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.
- MTX_SPIN Spin mutexes will never relinquish the CPU.
- All inter
rupts are disabled on the local CPU while any - spin lock is
held. - MTX_RECURSE Specifies that the initialized mutex is al
- lowed to
recurse. This bit must be present if the mu - tex is permitted to recurse.
- MTX_QUIET Do not log any mutex operations for this
- lock.
- MTX_NOWITNESS Instruct witness(4) to ignore this lock.
- MTX_DUPOK Witness should not log messages about dupli
- cate locks
being acquired. - Lock and Unlock Flags
The flags passed to the mtx_lock_flags(), - mtx_lock_spin_flags(),
mtx_unlock_flags(), and mtx_unlock_spin_flags() 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 mtx_lock(), - mtx_lock_spin(),
mtx_unlock(), and mtx_unlock_spin() functions. Only if a - flag is
required should the corresponding flags-accepting routines - be used.
- Options that modify mutex behavior:
- MTX_QUIET This option is used to quiet logging messages
- during individ
ual mutex operations. This can be used to trim - superfluous
logging messages for debugging purposes. - Giant
If Giant must be acquired, it must be acquired prior to ac - quiring other
mutexes. Put another way: it is impossible to acquire Giant - non-recursively while holding another mutex. It is possible to ac
- quire other
mutexes while holding Giant, and it is possible to acquire - Giant recursively while holding other mutexes.
- Sleeping
Sleeping while holding a mutex (except for Giant) is never - safe and
should be avoided. There are numerous assertions which will - fail if this
is attempted. - Functions Which Access Memory in Userspace No mutexes should be held (except for Giant) across func
- tions which
access memory in userspace, such as copyin(9), copyout(9), - uiomove(9),
fuword(9), etc. No locks are needed when calling these - functions.
SEE ALSO
HISTORY
- These functions appeared in BSD/OS 4.1 and FreeBSD 5.0.
- BSD February 16, 2005