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.