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... | |
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
#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:
Is equivalent to doing
But the initialization of the mutex is performed automatically during runtime initialization
#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:
Is equivalent to doing
But the initialization of the mutex is performed automatically during runtime initialization
|
inlinestatic |
Test whether a critical_section has been initialized.
crit_sec | Pointer to critical_section structure |
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.
mtx | Pointer to mutex structure |
until | The time after which to return if the caller cannot be granted ownership of the mutex |
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
mtx | Pointer to mutex structure |
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.
mtx | Pointer to mutex structure |
timeout_ms | The timeout in milliseconds. |
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.
mtx | Pointer to mutex structure |
timeout_us | The timeout in microseconds. |
void mutex_exit | ( | mutex_t * | mtx | ) |
Release ownership of a mutex.
mtx | Pointer to mutex structure |
void mutex_init | ( | mutex_t * | mtx | ) |
Initialise a mutex structure.
mtx | Pointer to mutex structure |
|
inlinestatic |
Test for mutex initialized state.
mtx | Pointer to mutex structure |
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.
mtx | Pointer to mutex structure |
owner_out | If 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 |
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
mtx | Pointer to mutex structure |
until | The time after which to return if the caller cannot be granted ownership of the mutex |
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.
mtx | Pointer to recursive mutex structure |
until | The time after which to return if the caller cannot be granted ownership of the mutex |
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
mtx | Pointer to recursive mutex structure |
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.
mtx | Pointer to recursive mutex structure |
timeout_ms | The timeout in milliseconds. |
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.
mtx | Pointer to mutex structure |
timeout_us | The timeout in microseconds. |
void recursive_mutex_exit | ( | recursive_mutex_t * | mtx | ) |
Release ownership of a recursive mutex.
mtx | Pointer to recursive mutex structure |
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
mtx | Pointer to recursive mutex structure |
|
inlinestatic |
Test for recursive mutex initialized state.
mtx | Pointer to recursive mutex structure |
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.
mtx | Pointer to recursive mutex structure |
owner_out | If 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 |