NAME
mutex, mtx_init,
mtx_uninit, mtx_lock_sh,
mtx_lock_sh_quick,
mtx_lock_ex,
mtx_lock_ex_quick, mtx_lock,
mtx_spinlock,
mtx_lock_ex_try,
mtx_lock_sh_try,
mtx_spinlock_try,
mtx_downgrade,
mtx_upgrade_try, mtx_unlock,
mtx_unlock_ex,
mtx_unlock_sh,
mtx_spinunlock,
mtx_islocked,
mtx_islocked_ex,
mtx_notlocked,
mtx_notlocked_ex, mtx_owned,
mtx_notowned, mtx_lockrefs
— general blocking/spinnable
mutex functions
SYNOPSIS
#include
<sys/globaldata.h>
#include <sys/mutex2.h>
void
mtx_init(mtx_t
*mtx, const char
*ident);
void
mtx_uninit(mtx_t
*mtx);
int
mtx_lock_sh(mtx_t
*mtx, int flags,
int to);
int
mtx_lock_sh_quick(mtx_t
*mtx);
int
mtx_lock_ex(mtx_t
*mtx, int flags,
int to);
int
mtx_lock_ex_quick(mtx_t
*mtx);
void
mtx_lock(mtx_t
*mtx);
void
mtx_spinlock(mtx_t
*mtx);
int
mtx_lock_ex_try(mtx_t
*mtx);
int
mtx_lock_sh_try(mtx_t
*mtx);
int
mtx_spinlock_try(mtx_t
*mtx);
void
mtx_downgrade(mtx_t
*mtx);
int
mtx_upgrade_try(mtx_t
*mtx);
void
mtx_unlock(mtx_t
*mtx);
void
mtx_unlock_ex(mtx_t
*mtx);
void
mtx_unlock_sh(mtx_t
*mtx);
void
mtx_spinunlock(mtx_t
*mtx);
int
mtx_islocked(mtx_t
*mtx);
int
mtx_islocked_ex(mtx_t
*mtx);
int
mtx_notlocked(mtx_t
*mtx);
int
mtx_notlocked_ex(mtx_t
*mtx);
int
mtx_owned(mtx_t
*mtx);
int
mtx_notowned(mtx_t
*mtx);
int
mtx_lockrefs(mtx_t
*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 incremented each time an attempt to acquire a mutex fails due to contention. kern.mtx_wakeup_count is incremented each time an exclusive lock is converted 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 ident parameter is
as in tsleep(9), it is a string describing the reason for a thread
to be blocked.
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 flags parameter
is passed to
tsleep(9) if the thread must block; the to
parameter is a timeout for the sleep. The
mtx_lock_sh_quick()
function is a version of mtx_lock_sh() without flags
or a timeout. The mtx_lock_sh() and
mtx_lock_sh_quick() functions return 0 on success,
or the
tsleep()
return code on failure. An error can only be returned if
PCATCH is specified in the flags.
The
mtx_lock_ex()
function attempts to lock a mutex exclusively and blocks the current thread
until it is able to do so. The flags parameter is as
in tsleep(9). The to parameter is a
timeout on the sleep. The
mtx_lock_ex_quick()
function is a version of mtx_lock_ex() without flags
or a timeout. The
mtx_lock()
function is a yet shorter form for exclusively locking a mutex, blocking the
current thread until acquired. It is equivalent to
mtx_lock_ex(mtx,
0, 0). The
mtx_lock_ex() and
mtx_lock_ex_quick() functions return 0 on success,
or the tsleep() return code on failure. An error can
only be returned if PCATCH is specified in the
flags.
The
mtx_spinlock()
function attempts to lock the mutex in exclusive 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_spinlock_try()
function does the same but for spin mutexes.
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 exclusive and shared
mutexes. The
mtx_unlock_ex()
and
mtx_unlock_sh()
functions are optimized unlock paths, used when it is known that a lock is
held exclusively or in shared state.
The
mtx_spinunlock()
function releases a held spin mutex.
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.
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 ALSO
crit_enter(9), locking(9), lockmgr(9), serializer(9), sleep(9), spinlock(9)
HISTORY
Mutexes first appeared in DragonFly 2.3.
AUTHORS
The mutex implementation was written by
Matthew Dillon.