v2.0.0
Data Structures | Macros | Typedefs | Functions
mutex
High Level APIs » pico_sync

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

## Data Structures
struct | recursive_mutex_t
| 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 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 system 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);
auto_init_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);
}
mutex_init
void mutex_init(mutex_t *mtx)
Initialise a mutex structure.
Definition: mutex.c:43
mutex
regular (non recursive) mutex instance
Definition: mutex.h:60

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);
auto_init_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);
}
recursive_mutex_init
void recursive_mutex_init(recursive_mutex_t *mtx)
Initialise a recursive mutex structure.
Definition: mutex.c:52
recursive_mutex_t
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_sec | Pointer 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

  mtx | Pointer to mutex structure
  until | The 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

  mtx | Pointer 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

  mtx | Pointer to mutex structure
  timeout_ms | The 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

  mtx | Pointer to mutex structure
  timeout_us | The 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

  mtx | Pointer to mutex structure

## ◆ mutex_init()

void mutex_init | ( | mutex_t * | mtx | ) |

Initialise a mutex structure.

Parameters

  mtx | Pointer to mutex structure

## ◆ mutex_is_initialized()

static bool mutex_is_initialized | ( | mutex_t * | mtx | ) |
| inlinestatic

Test for mutex initialized state.

Parameters

  mtx | Pointer 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

  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

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

  mtx | Pointer to mutex structure
  until | The 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

  mtx | Pointer to recursive mutex structure
  until | The 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

  mtx | Pointer 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

  mtx | Pointer to recursive mutex structure
  timeout_ms | The 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

  mtx | Pointer to mutex structure
  timeout_us | The 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

  mtx | Pointer 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

  mtx | Pointer 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

  mtx | Pointer 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

  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

Returns
  true if the recursive mutex (now) owned, false otherwise