MUTEX(9) | Kernel Developer's Manual | MUTEX(9)

# NAME

`mutex`, `mtx_init`, `mtx_init_flags`, `mtx_enter`, `mtx_enter_try`, `mtx_leave`, `MUTEX_ASSERT_LOCKED`, `MUTEX_ASSERT_UNLOCKED`, `MUTEX_INITIALIZER`, `MUTEX_INITIALIZER_FLAGS` — interface to CPU mutexes

# SYNOPSIS

`#include <sys/mutex.h>`

void
`mtx_init`(struct mutex *mtxp, int wantipl);

void
`mtx_init_flags`(struct mutex *mtxp, int wantipl, const char *name, int flags);

void
`mtx_enter`(struct mutex *mtxp);

int
`mtx_enter_try`(struct mutex *mtxp);

void
`mtx_leave`(struct mutex *mtxp);

`MUTEX_ASSERT_LOCKED`(struct mutex *mtxp);

`MUTEX_ASSERT_UNLOCKED`(struct mutex *mtxp);

`MUTEX_INITIALIZER`(int wantipl);

`MUTEX_INITIALIZER_FLAGS`(int wantipl, const char *name, int flags);

# DESCRIPTION

The `mutex` set of functions provides a non-recursive, interrupt-aware spinning mechanism to ensure mutual exclusion between different CPUs.

The `mtx_init`() function is used to initiate the mutex pointed to by mtxp. When acquired, the mutex will cause the processor interrupt level to be raised to wantipl if necessary.

The `mtx_init_flags`() macro is similar to `mtx_init`(), but it additionally accepts parameters for witness(4). The pointer name differentiates a lock type. Two mutexes have the same lock type only if they have been created by the same occurrence of `mtx_init_flags`() with the same pointer name. The flags parameter is a bitwise OR of the following options:

`MTX_DUPOK`
  Prevents witness(4) from logging when a CPU acquires more than one lock of this lock type.
`MTX_NOWITNESS`
  Instructs witness(4) to ignore this lock.

The `mtx_enter`() function acquires a mutex, spinning if necessary.

The `mtx_enter_try`() function attempts to acquire a mutex.

The `mtx_leave`() function releases a mutex. In case the acquisition of the mutex caused the interrupt level to be changed, it is then restored.

The `MUTEX_ASSERT_LOCKED`() and `MUTEX_ASSERT_UNLOCKED`() macros may be used to assert that a mutex is held locked or unlocked by the current CPU.

A mutex declaration may be initialised with the `MUTEX_INITIALIZER`() macro. When acquired, the mutex will cause the processor interrupt level to be raised to wantipl if necessary.

The `MUTEX_INITIALIZER_FLAGS`() macro is similar to `MUTEX_INITIALIZER`(), but it additionally accepts parameters for witness(4). See the `mtx_init_flags`() macro for details.

# CONTEXT

`mtx_init`() and `mtx_init_flags`() can be called during autoconf, from process context, or from interrupt context.

`mtx_enter`(), `mtx_enter_try`(), and `mtx_leave`() can be called during autoconf, from process context, or from any interrupt context at or below the interrupt level mtxp was initialised with.

# RETURN VALUES

The `mtx_enter_try`() function will return non-zero if it succeeds in acquiring the mutex mtxp, otherwise it will return 0.

# SEE ALSO

witness(4), msleep(9), rwlock(9), spl(9)

# HISTORY

The `mutex` functions first appeared in OpenBSD 3.6.

# AUTHORS

The `mutex` functions were written by Artur Grabowski <art@openbsd.org>.

# CAVEATS

As these are spinning locks, don't sleep while holding one.

Multiple mutexes may be nested, but not interleaved. This is okay:

    mtx_enter(foo);
    mtx_enter(bar);
    mtx_leave(bar);
    mtx_leave(foo);

While this is not:

    mtx_enter(foo);
    mtx_enter(bar);
    mtx_leave(foo);
    mtx_leave(bar);

November 4, 2019 | Debian