Mutex API for non IRQ mutual exclusion between cores. More...

Data Structures

struct  __packed_aligned
 recursive mutex instance More...
 
struct  mutex
 regular (non recursive) mutex instance More...
 

Macros

#define auto_init_mutex(name)   static __attribute__((section(".mutex_array"))) mutex_t name
 Helper macro for static definition of mutexes. More...
 
#define auto_init_recursive_mutex(name)   static __attribute__((section(".mutex_array"))) recursive_mutex_t name = { .core = { .spin_lock = (spin_lock_t *)1 /* marker for runtime_init */ }, .owner = 0, .enter_count = 0 }
 Helper macro for static definition of recursive mutexes. More...
 

Typedefs

typedef struct __packed_aligned recursive_mutex_t
 recursive mutex instance
 
typedef struct __packed_aligned mutex mutex_t
 regular (non recursive) mutex instance
 

Functions

static bool critical_section_is_initialized (critical_section_t *crit_sec)
 Test whether a critical_section has been initialized. More...
 
void mutex_init (mutex_t *mtx)
 Initialise a mutex structure. More...
 
void recursive_mutex_init (recursive_mutex_t *mtx)
 Initialise a recursive mutex structure. More...
 
void mutex_enter_blocking (mutex_t *mtx)
 Take ownership of a mutex. More...
 
void recursive_mutex_enter_blocking (recursive_mutex_t *mtx)
 Take ownership of a recursive mutex. More...
 
bool mutex_try_enter (mutex_t *mtx, uint32_t *owner_out)
 Attempt to take ownership of a mutex. More...
 
bool mutex_try_enter_block_until (mutex_t *mtx, absolute_time_t until)
 Attempt to take ownership of a mutex until the specified time. More...
 
bool recursive_mutex_try_enter (recursive_mutex_t *mtx, uint32_t *owner_out)
 Attempt to take ownership of a recursive mutex. More...
 
bool mutex_enter_timeout_ms (mutex_t *mtx, uint32_t timeout_ms)
 Wait for mutex with timeout. More...
 
bool recursive_mutex_enter_timeout_ms (recursive_mutex_t *mtx, uint32_t timeout_ms)
 Wait for recursive mutex with timeout. More...
 
bool mutex_enter_timeout_us (mutex_t *mtx, uint32_t timeout_us)
 Wait for mutex with timeout. More...
 
bool recursive_mutex_enter_timeout_us (recursive_mutex_t *mtx, uint32_t timeout_us)
 Wait for recursive mutex with timeout. More...
 
bool mutex_enter_block_until (mutex_t *mtx, absolute_time_t until)
 Wait for mutex until a specific time. More...
 
bool recursive_mutex_enter_block_until (recursive_mutex_t *mtx, absolute_time_t until)
 Wait for mutex until a specific time. More...
 
void mutex_exit (mutex_t *mtx)
 Release ownership of a mutex. More...
 
void recursive_mutex_exit (recursive_mutex_t *mtx)
 Release ownership of a recursive mutex. More...
 
static bool mutex_is_initialized (mutex_t *mtx)
 Test for mutex initialized state. More...
 
static bool recursive_mutex_is_initialized (recursive_mutex_t *mtx)
 Test for recursive mutex initialized state. More...
 

Detailed Description

Mutex API for non IRQ mutual exclusion between cores.

Mutexes are application level locks usually used protecting data structures that might be used by multiple threads of execution. Unlike critical sections, the mutex protected code is not necessarily required/expected to complete quickly, as no other sytem wide locks are held on account of an acquired mutex.

When acquired, the mutex has an owner (see lock_get_caller_owner_id) which with the plain SDK is just the acquiring core, but in an RTOS it could be a task, or an IRQ handler context.

Two variants of mutex are provided; mutex_t (and associated mutex_ functions) is a regular mutex that cannot be acquired recursively by the same owner (a deadlock will occur if you try). recursive_mutex_t (and associated recursive_mutex_ functions) is a recursive mutex that can be recursively obtained by the same caller, at the expense of some more overhead when acquiring and releasing.

It is generally a bad idea to call blocking mutex_ or recursive_mutex_ functions from within an IRQ handler. It is valid to call mutex_try_enter or recursive_mutex_try_enter from within an IRQ handler, if the operation that would be conducted under lock can be skipped if the mutex is locked (at least by the same owner).

NOTE: For backwards compatibility with version 1.2.0 of the SDK, if the define PICO_MUTEX_ENABLE_SDK120_COMPATIBILITY is set to 1, then the the regular mutex_ functions may also be used for recursive mutexes. This flag will be removed in a future version of the SDK.

See critical_section.h for protecting access between multiple cores AND IRQ handlers

Macro Definition Documentation

◆ auto_init_mutex

#define auto_init_mutex (   name)    static __attribute__((section(".mutex_array"))) mutex_t name

Helper macro for static definition of mutexes.

A mutex defined as follows:

auto_init_mutex(my_mutex);
#define auto_init_mutex(name)
Helper macro for static definition of mutexes.
Definition: mutex.h:283

Is equivalent to doing

static mutex_t my_mutex;
void my_init_function() {
mutex_init(&my_mutex);
}
struct __packed_aligned mutex mutex_t
regular (non recursive) mutex instance
void mutex_init(mutex_t *mtx)
Initialise a mutex structure.
Definition: mutex.c:10

But the initialization of the mutex is performed automatically during runtime initialization

◆ auto_init_recursive_mutex

#define auto_init_recursive_mutex (   name)    static __attribute__((section(".mutex_array"))) recursive_mutex_t name = { .core = { .spin_lock = (spin_lock_t *)1 /* marker for runtime_init */ }, .owner = 0, .enter_count = 0 }

Helper macro for static definition of recursive mutexes.

A recursive mutex defined as follows:

auto_init_recursive_mutex(my_recursive_mutex);
#define auto_init_recursive_mutex(name)
Helper macro for static definition of recursive mutexes.
Definition: mutex.h:306

Is equivalent to doing

static recursive_mutex_t my_recursive_mutex;
void my_init_function() {
recursive_mutex_init(&my_recursive_mutex);
}
void recursive_mutex_init(recursive_mutex_t *mtx)
Initialise a recursive mutex structure.
Definition: mutex.c:19
recursive mutex instance
Definition: mutex.h:47

But the initialization of the mutex is performed automatically during runtime initialization

Function Documentation

◆ critical_section_is_initialized()

static bool critical_section_is_initialized ( critical_section_t *  crit_sec)
inlinestatic

Test whether a critical_section has been initialized.

Parameters
crit_secPointer to critical_section structure
Returns
true if the critical section is initialized, false otherwise

◆ mutex_enter_block_until()

bool mutex_enter_block_until ( mutex_t mtx,
absolute_time_t  until 
)

Wait for mutex until a specific time.

Wait until the specific time to take ownership of the mutex. If the caller can be granted ownership of the mutex before the timeout expires, then true will be returned and the caller will own the mutex, otherwise false will be returned and the caller will NOT own the mutex.

Parameters
mtxPointer to mutex structure
untilThe time after which to return if the caller cannot be granted ownership of the mutex
Returns
true if mutex now owned, false if timeout occurred before ownership could be granted

◆ mutex_enter_blocking()

void mutex_enter_blocking ( mutex_t mtx)

Take ownership of a mutex.

This function will block until the caller can be granted ownership of the mutex. On return the caller owns the mutex

Parameters
mtxPointer to mutex structure

◆ mutex_enter_timeout_ms()

bool mutex_enter_timeout_ms ( mutex_t mtx,
uint32_t  timeout_ms 
)

Wait for mutex with timeout.

Wait for up to the specific time to take ownership of the mutex. If the caller can be granted ownership of the mutex before the timeout expires, then true will be returned and the caller will own the mutex, otherwise false will be returned and the caller will NOT own the mutex.

Parameters
mtxPointer to mutex structure
timeout_msThe timeout in milliseconds.
Returns
true if mutex now owned, false if timeout occurred before ownership could be granted

◆ mutex_enter_timeout_us()

bool mutex_enter_timeout_us ( mutex_t mtx,
uint32_t  timeout_us 
)

Wait for mutex with timeout.

Wait for up to the specific time to take ownership of the mutex. If the caller can be granted ownership of the mutex before the timeout expires, then true will be returned and the caller will own the mutex, otherwise false will be returned and the caller will NOT own the mutex.

Parameters
mtxPointer to mutex structure
timeout_usThe timeout in microseconds.
Returns
true if mutex now owned, false if timeout occurred before ownership could be granted

◆ mutex_exit()

void mutex_exit ( mutex_t mtx)

Release ownership of a mutex.

Parameters
mtxPointer to mutex structure

◆ mutex_init()

void mutex_init ( mutex_t mtx)

Initialise a mutex structure.

Parameters
mtxPointer to mutex structure

◆ mutex_is_initialized()

static bool mutex_is_initialized ( mutex_t mtx)
inlinestatic

Test for mutex initialized state.

Parameters
mtxPointer to mutex structure
Returns
true if the mutex is initialized, false otherwise

◆ mutex_try_enter()

bool mutex_try_enter ( mutex_t mtx,
uint32_t *  owner_out 
)

Attempt to take ownership of a mutex.

If the mutex wasn't owned, this will claim the mutex for the caller and return true. Otherwise (if the mutex was already owned) this will return false and the caller will NOT own the mutex.

Parameters
mtxPointer to mutex structure
owner_outIf mutex was already owned, and this pointer is non-zero, it will be filled in with the owner id of the current owner of the mutex
Returns
true if mutex now owned, false otherwise

◆ mutex_try_enter_block_until()

bool mutex_try_enter_block_until ( mutex_t mtx,
absolute_time_t  until 
)

Attempt to take ownership of a mutex until the specified time.

If the mutex wasn't owned, this method will immediately claim the mutex for the caller and return true. If the mutex is owned by the caller, this method will immediately return false, If the mutex is owned by someone else, this method will try to claim it until the specified time, returning true if it succeeds, or false on timeout

Parameters
mtxPointer to mutex structure
untilThe time after which to return if the caller cannot be granted ownership of the mutex
Returns
true if mutex now owned, false otherwise

◆ recursive_mutex_enter_block_until()

bool recursive_mutex_enter_block_until ( recursive_mutex_t mtx,
absolute_time_t  until 
)

Wait for mutex until a specific time.

Wait until the specific time to take ownership of the mutex. If the caller already has ownership of the mutex or can be granted ownership of the mutex before the timeout expires, then true will be returned and the caller will own the mutex, otherwise false will be returned and the caller will NOT own the mutex.

Parameters
mtxPointer to recursive mutex structure
untilThe time after which to return if the caller cannot be granted ownership of the mutex
Returns
true if the recursive mutex (now) owned, false if timeout occurred before ownership could be granted

◆ recursive_mutex_enter_blocking()

void recursive_mutex_enter_blocking ( recursive_mutex_t mtx)

Take ownership of a recursive mutex.

This function will block until the caller can be granted ownership of the mutex. On return the caller owns the mutex

Parameters
mtxPointer to recursive mutex structure

◆ recursive_mutex_enter_timeout_ms()

bool recursive_mutex_enter_timeout_ms ( recursive_mutex_t mtx,
uint32_t  timeout_ms 
)

Wait for recursive mutex with timeout.

Wait for up to the specific time to take ownership of the recursive mutex. If the caller already has ownership of the mutex or can be granted ownership of the mutex before the timeout expires, then true will be returned and the caller will own the mutex, otherwise false will be returned and the caller will NOT own the mutex.

Parameters
mtxPointer to recursive mutex structure
timeout_msThe timeout in milliseconds.
Returns
true if the recursive mutex (now) owned, false if timeout occurred before ownership could be granted

◆ recursive_mutex_enter_timeout_us()

bool recursive_mutex_enter_timeout_us ( recursive_mutex_t mtx,
uint32_t  timeout_us 
)

Wait for recursive mutex with timeout.

Wait for up to the specific time to take ownership of the recursive mutex. If the caller already has ownership of the mutex or can be granted ownership of the mutex before the timeout expires, then true will be returned and the caller will own the mutex, otherwise false will be returned and the caller will NOT own the mutex.

Parameters
mtxPointer to mutex structure
timeout_usThe timeout in microseconds.
Returns
true if the recursive mutex (now) owned, false if timeout occurred before ownership could be granted

◆ recursive_mutex_exit()

void recursive_mutex_exit ( recursive_mutex_t mtx)

Release ownership of a recursive mutex.

Parameters
mtxPointer to recursive mutex structure

◆ recursive_mutex_init()

void recursive_mutex_init ( recursive_mutex_t mtx)

Initialise a recursive mutex structure.

A recursive mutex may be entered in a nested fashion by the same owner

Parameters
mtxPointer to recursive mutex structure

◆ recursive_mutex_is_initialized()

static bool recursive_mutex_is_initialized ( recursive_mutex_t mtx)
inlinestatic

Test for recursive mutex initialized state.

Parameters
mtxPointer to recursive mutex structure
Returns
true if the recursive mutex is initialized, false otherwise

◆ recursive_mutex_try_enter()

bool recursive_mutex_try_enter ( recursive_mutex_t mtx,
uint32_t *  owner_out 
)

Attempt to take ownership of a recursive mutex.

If the mutex wasn't owned or was owned by the caller, this will claim the mutex and return true. Otherwise (if the mutex was already owned by another owner) this will return false and the caller will NOT own the mutex.

Parameters
mtxPointer to recursive mutex structure
owner_outIf mutex was already owned by another owner, and this pointer is non-zero, it will be filled in with the owner id of the current owner of the mutex
Returns
true if the recursive mutex (now) owned, false otherwise