MUTEX(9) BSD Kernel Developer's Manual MUTEX(9)NAME
mutex, mtx_init, mtx_uninit, mtx_lock_sh, mtx_lock_sh_quick, mtx_lock_ex,
mtx_lock_ex_quick, mtx_spinlock_ex, mtx_spinlock_sh, mtx_lock_ex_try,
mtx_lock_sh_try, mtx_downgrade, mtx_upgrade_try, mtx_unlock,
mtx_unlock_ex, mtx_unlock_sh, mtx_islocked, mtx_islocked_ex,
mtx_notlocked, mtx_notlocked_ex, mtx_owned, mtx_notowned, mtx_lockrefs,
mtx_hold, mtx_drop — general blocking/spinnable mutex functions
SYNOPSIS
#include <sys/globaldata.h>
#include <sys/mutex2.h>
void
mtx_init(struct mtx *mtx);
void
mtx_uninit(struct mtx *mtx);
void
mtx_lock_sh(struct mtx *mtx, const char *ident, int flags, int to);
void
mtx_lock_sh_quick(struct mtx *mtx, const char *ident);
void
mtx_lock_ex(struct mtx *mtx, const char *ident, int flags, int to);
void
mtx_lock_ex_quick(struct mtx *mtx, const char *ident);
void
mtx_spinlock_ex(struct mtx *mtx);
void
mtx_spinlock_sh(struct mtx *mtx);
int
mtx_lock_ex_try(struct mtx *mtx);
int
mtx_lock_sh_try(struct mtx *mtx);
void
mtx_downgrade(struct mtx *mtx);
int
mtx_upgrade_try(struct mtx *mtx);
void
mtx_unlock(struct mtx *mtx);
void
mtx_unlock_ex(struct mtx *mtx);
void
mtx_unlock_sh(struct mtx *mtx);
int
mtx_islocked(struct mtx *mtx);
int
mtx_islocked_ex(struct mtx *mtx);
int
mtx_notlocked(struct mtx *mtx);
int
mtx_notlocked_ex(struct mtx *mtx);
int
mtx_owned(struct mtx *mtx);
int
mtx_notowned(struct mtx *mtx);
int
mtx_lockrefs(struct mtx *mtx);
void
mtx_hold(struct mtx *mtx);
int
mtx_drop(struct mtx *mtx);
DESCRIPTION
Mutexes are used to implement mutual exclusion between threads. Mutexes
can be locked in shared or exclusive mode; they can also block or spin
the current thread when there is contention.
Mutexes also have an associated reference count, independent of the lock.
System-wide mutex contention statistics can be found in the
kern.mtx_contention_count, kern.mtx_collision_count, and
kern.mtx_wakeup_count variables. kern.mtx_contention_count is incre‐
mented each time an attempt to acquire a mutex fails due to contention.
kern.mtx_wakeup_count is incremented each time an exclusive lock is con‐
verted to either a shared or unlocked state an waiters for the shared
state are woken.
The mutex functions are similar to the lockmgr(9) functions.
FUNCTIONS
The mtx_init() function initializes a mutex to the unlocked state. It is
an error to use a mutex without initializing it.
The mtx_uninit() function deinitializes a mutex.
The mtx_lock_sh() function attempts to lock a mutex in shared mode and
blocks the current thread until it is able to do so. The ident parameter
is as in tsleep(9), it is a string describing the reason for a thread to
be blocked. The flags parameter is passed to tsleep(9) if the thread
must block; the to parameter is a timeout for the sleep.
mtx_lock_sh_quick() is a version without flags or a timeout.
The mtx_lock_ex() function attempts to lock a mutex exclusively and
blocks the current thread until it is able to do so. The ident parameter
and flags parameters are as in tsleep(9). The to parameter is a timeout
on the sleep. mtx_lock_ex_quick is is a version without flags or a time‐
out.
The mtx_spinlock_ex() function attempts to lock the mutex in exclusive
mode and spins until it is able to do so; the mtx_spinlock_sh() function
attempts to lock the mutex in shared mode and spins until it is able to
do so.
The mtx_lock_ex_try() and mtx_lock_sh_try() functions attempt to lock the
mutex in exclusive or shared mode, respectively. If they are not able
to, they return EAGAIN.
The mtx_downgrade() function converts an exclusively held lock to a
shared lock. The lock must be held by the calling thread. If the lock
is already shared, this call is a no-op.
The mtx_upgrade_try() function attempts to convert a shared lock to an
exclusive one. The mutex must be held by the caller in the shared state.
If the upgrade is successful, this function returns 0; otherwise, it
returns EDEADLK.
The mtx_unlock() function releases a held mutex; it works on both exclu‐
sive and shared mutexes. The mtx_unlock_ex() and mtx_unlock_sh() func‐
tions are optimized unlock paths, used when it is known that a lock is
held exclusively or in shared state.
The mtx_islocked() function returns non-zero if the mutex is locked in
either shared of exclusive state by any thread. mtx_islocked_ex()
returns non-zero if the mutex is locked exclusively by any thread. The
mtx_notlocked() function returns non-zero if the mutex is not locked.
The mtx_owned() function returns non-zero if the mutex is exclusively
locked by the calling thread. The mtx_notowned() function returns non-
zero if the mutex is not exclusively locked by the calling thread. The
mtx_lockrefs() function returns the number of shared or exclusive locks
on the mutex.
The mtx_hold() function increments the reference count associated with
each mutex. The reference count is independent of the lock field. The
mtx_drop() function decrements the reference count associated with each
mutex and returns the old value of the count. A return value of ‘1’
means that the current count is ‘0’.
FILES
The uncontended path of the mutex implementation is in /sys/sys/mutex2.h.
The data structures are in /sys/sys/mutex.h. The core of the spinlock
implementation is in /sys/kern/kern_mutex.c.
SEE ALSOcrit_enter(9), lockmgr(9), serializer(9), spinlock(9)HISTORY
Mutexes first appeared in DragonFly 2.3.
AUTHORS
The mutex implementation was written by Matthew Dillon.
BSD May 9, 2010 BSD