PebbleOS
Loading...
Searching...
No Matches
Data Structures | Macros | Functions
Mutexes

Recursive mutexes with priority inheritance. More...

Data Structures

struct  pbl_mutex
 Recursive mutex. More...
 

Macros

#define PBL_MUTEX_INITIALIZER   {.owner = NULL, .count = 0, .lock_lr = 0}
 Static initializer for an unlocked mutex.
 
#define PBL_MUTEX_DEFINE(name)   struct pbl_mutex name = PBL_MUTEX_INITIALIZER
 Define an unlocked mutex, usable without pbl_mutex_init().
 

Functions

void pbl_mutex_init (struct pbl_mutex *m)
 Initialize a mutex in dynamically allocated memory.
 
void pbl_mutex_deinit (struct pbl_mutex *m)
 Release a mutex before its memory is reused.
 
int pbl_mutex_lock_lr (struct pbl_mutex *m, pbl_timeout_t timeout, uintptr_t lr)
 Lock a mutex, recording a given lock site.
 
static int pbl_mutex_lock (struct pbl_mutex *m, pbl_timeout_t timeout)
 Lock a mutex.
 
void pbl_mutex_unlock (struct pbl_mutex *m)
 Undo one lock of a mutex.
 
bool pbl_mutex_is_owner (const struct pbl_mutex *m)
 Check whether the calling thread owns a mutex.
 
void pbl_mutex_assert_held (const struct pbl_mutex *m, bool held)
 Assert that ownership of a mutex by the calling thread matches held.
 

Detailed Description

Recursive mutexes with priority inheritance.

The owning thread may lock a mutex again; it is released once every lock has been undone. While a higher priority thread waits, the owner runs at the waiter's priority until it holds no mutex any more. Waiters are served highest priority first, FIFO within a priority, and an unlock hands the mutex directly to the next waiter. Mutexes cannot be used from ISRs.

Non-recursive use is expressed with pbl_mutex_assert_held().

static PBL_MUTEX_DEFINE(s_lock);
int cache_update(const struct entry *e) {
int rc = pbl_mutex_lock(&s_lock, PBL_MSEC(50));
if (rc != 0) {
return rc; // -EAGAIN: still held by another thread after 50 ms
}
prv_store(e);
pbl_mutex_unlock(&s_lock);
return 0;
}
static int pbl_mutex_lock(struct pbl_mutex *m, pbl_timeout_t timeout)
Lock a mutex.
Definition mutex.h:102
void pbl_mutex_unlock(struct pbl_mutex *m)
Undo one lock of a mutex.
#define PBL_MUTEX_DEFINE(name)
Define an unlocked mutex, usable without pbl_mutex_init().
Definition mutex.h:57
#define PBL_MSEC(ms)
Timeout in milliseconds, rounded down to whole ticks.
Definition types.h:62

Data Structure Documentation

◆ pbl_mutex

struct pbl_mutex

Recursive mutex.

Not usable from ISRs.

Data Fields
struct pbl_mutex_backend backend Backend state.
uint32_t count Recursion depth of the owner, 0 when unlocked.
uintptr_t lock_lr Return address of the outermost lock, for diagnostics (CONFIG_KERNEL_MUTEX_LOCK_LR).
struct pbl_thread * owner Owning thread, NULL when unlocked.

Macro Definition Documentation

◆ PBL_MUTEX_DEFINE

#define PBL_MUTEX_DEFINE (   name)    struct pbl_mutex name = PBL_MUTEX_INITIALIZER

Define an unlocked mutex, usable without pbl_mutex_init().

Parameters
nameName of the mutex variable.

◆ PBL_MUTEX_INITIALIZER

#define PBL_MUTEX_INITIALIZER   {.owner = NULL, .count = 0, .lock_lr = 0}

Static initializer for an unlocked mutex.

Function Documentation

◆ pbl_mutex_assert_held()

void pbl_mutex_assert_held ( const struct pbl_mutex *  m,
bool  held 
)

Assert that ownership of a mutex by the calling thread matches held.

Parameters
mMutex.
heldExpected ownership.

◆ pbl_mutex_deinit()

void pbl_mutex_deinit ( struct pbl_mutex *  m)

Release a mutex before its memory is reused.

Required for dynamically allocated mutexes. Asserts that the mutex is not held.

Parameters
mMutex.

◆ pbl_mutex_init()

void pbl_mutex_init ( struct pbl_mutex *  m)

Initialize a mutex in dynamically allocated memory.

Parameters
[out]mMutex.

◆ pbl_mutex_is_owner()

bool pbl_mutex_is_owner ( const struct pbl_mutex *  m)

Check whether the calling thread owns a mutex.

Parameters
mMutex.
Returns
true if the calling thread holds m.

◆ pbl_mutex_lock()

static int pbl_mutex_lock ( struct pbl_mutex *  m,
pbl_timeout_t  timeout 
)
inlinestatic

Lock a mutex.

Succeeds at once if the calling thread already owns it.

Parameters
mMutex.
timeoutHow long to wait for another owner to release it.
Return values
0Locked.
-EAGAINTimed out.
-EBUSYHeld by another thread and timeout is PBL_NO_WAIT.
-EINTRThe thread was suspended while waiting.

References pbl_mutex_lock_lr(), and PBL_RETURN_ADDRESS.

◆ pbl_mutex_lock_lr()

int pbl_mutex_lock_lr ( struct pbl_mutex *  m,
pbl_timeout_t  timeout,
uintptr_t  lr 
)

Lock a mutex, recording a given lock site.

For wrappers that want their own caller recorded in pbl_mutex::lock_lr.

Parameters
mMutex.
timeoutHow long to wait for another owner to release it.
lrReturn address to record when this is the outermost lock.
Return values
0Locked.
-EAGAINTimed out.
-EBUSYHeld by another thread and timeout is PBL_NO_WAIT.
-EINTRThe thread was suspended while waiting.

Referenced by pbl_mutex_lock().

◆ pbl_mutex_unlock()

void pbl_mutex_unlock ( struct pbl_mutex *  m)

Undo one lock of a mutex.

Asserts that the calling thread owns it. The outermost unlock hands the mutex to the highest priority waiter and drops any inherited priority boost.

Parameters
mMutex.