Mutex for thread synchronization. More...

Detailed Description

Mutex for thread synchronization.

Mutex Implementation Basics

Data Structures and Encoding

A mutex_t contains basically a point, which can have one of the following values:

  1. NULL, in case it is unlocked
  2. MUTEX_LOCKED in case it is locked, but no other thread is waiting on it
  3. A pointer to the head of single linked list of threads (or more precisely their thread_t structures) blocked waiting for obtaining the mutex. This list is terminated by NULL, not by MUTEX_LOCKED

The same information graphically:

Unlocked mutex:
+-------+
| Mutex | --> NULL
+-------+
Locked mutex, no waiters:
+-------+
| Mutex | --> MUTEX_LOCKED
+-------+
Locked mutex, one waiter:
+-------+ +--------+
| Mutex | --> | Waiter | --> NULL
+-------+ +--------+
Locked mutex, 2 waiters:
+-------+ +--------+ +--------+
| Mutex | --> | Waiter | --> | Waiter | --> NULL
+-------+ +--------+ +--------+

Obtaining a Mutex

If a mutex_lock() is called, one of the following happens:

  1. If the mutex was unlocked (value of NULL), its value is changed to MUTEX_LOCKED and the call to mutex_lock() returns right away without blocking.
  2. If the mutex as a vale of MUTEX_LOCKED, it will be changed to point to the thread_t of the running thread. The single item list is terminated be setting the thread_t::rq_entry.next of the running thread to NULL. The running thread blocks as described below.
  3. Otherwise, the current thread is inserted into the list of waiting threads sorted by thread priority. The running thread blocks as described below.

In case 2) and 3), the running thread will mark itself as blocked (waiting for a mutex) and yields. Once control is transferred back to this thread (which is done in the call to mutex_unlock()), it has the mutex and the function mutex_lock() returns.

Returning a Mutex

If mutex_unlock() is called, one of the following happens:

  1. If the mutex was already unlocked (value of NULL), the call returns without modifying the mutex.
  2. If the mutex was locked without waiters (value of MUTEX_LOCKED), it is unlocked by setting its value to NULL.
  3. Otherwise the first thread_t from the linked list of waiters is removed from the list.
    • This thread is the one with the highest priority, as the list is sorted by priority.
    • This thread's status is set to pending and its added to the appropriate run queue.
    • If that thread was the last item in the list, the mutex is set to MUTEX_LOCK.
    • The scheduler is run, so that if the unblocked waiting thread can run now, in case it has a higher priority than the running thread.

Files

file  mutex.h
 Mutex for thread synchronization.
 

Data Structures

struct  mutex_t
 Mutex structure. More...
 

Macros

#define MUTEX_INIT   { { NULL } }
 Static initializer for mutex_t. More...
 
#define MUTEX_INIT_LOCKED   { { MUTEX_LOCKED } }
 Static initializer for mutex_t with a locked mutex.
 

Functions

static void mutex_init (mutex_t *mutex)
 Initializes a mutex object. More...
 
static int mutex_trylock (mutex_t *mutex)
 Tries to get a mutex, non-blocking. More...
 
void mutex_lock (mutex_t *mutex)
 Locks a mutex, blocking. More...
 
void mutex_unlock (mutex_t *mutex)
 Unlocks the mutex. More...
 
void mutex_unlock_and_sleep (mutex_t *mutex)
 Unlocks the mutex and sends the current thread to sleep. More...
 

Macro Definition Documentation

◆ MUTEX_INIT

#define MUTEX_INIT   { { NULL } }

Static initializer for mutex_t.

This initializer is preferable to mutex_init().

Definition at line 133 of file mutex.h.

Function Documentation

◆ mutex_init()

static void mutex_init ( mutex_t mutex)
inlinestatic

Initializes a mutex object.

For initialization of variables use MUTEX_INIT instead. Only use the function call for dynamically allocated mutexes.

Parameters
[out]mutexpre-allocated mutex structure, must not be NULL.

Definition at line 156 of file mutex.h.

◆ mutex_lock()

void mutex_lock ( mutex_t mutex)

Locks a mutex, blocking.

Parameters
[in,out]mutexMutex object to lock.
Precondition
mutex is not NULL
Mutex at mutex has been initialized
Must be called in thread context
Postcondition
The mutex is locked and held by the calling thread.

◆ mutex_trylock()

static int mutex_trylock ( mutex_t mutex)
inlinestatic

Tries to get a mutex, non-blocking.

Parameters
[in,out]mutexMutex object to lock.
Return values
1if mutex was unlocked, now it is locked.
0if the mutex was locked.
Precondition
mutex is not NULL
Mutex at mutex has been initialized
Must be called in thread context

Definition at line 173 of file mutex.h.

◆ mutex_unlock()

void mutex_unlock ( mutex_t mutex)

Unlocks the mutex.

Parameters
[in,out]mutexMutex object to unlock.
Precondition
mutex is not NULL
Note
It is safe to unlock a mutex held by a different thread.
It is safe to call this function from IRQ context.

◆ mutex_unlock_and_sleep()

void mutex_unlock_and_sleep ( mutex_t mutex)

Unlocks the mutex and sends the current thread to sleep.

Parameters
[in,out]mutexMutex object to unlock.
Precondition
mutex is not NULL
Must be called in thread context.
Mutex
Mutex struct within mqtt paho.
Definition: paho_mqtt.h:145