mutex.h
Go to the documentation of this file.
1 /*
2  * SPDX-FileCopyrightText: 2015 Kaspar Schleiser <kaspar@schleiser.de>
3  * SPDX-FileCopyrightText: 2013-2014 Freie Universität Berlin
4  * SPDX-License-Identifier: LGPL-2.1-only
5  */
6 
7 #pragma once
8 
20 #include <stddef.h>
21 #include <stdint.h>
22 #include <stdbool.h>
23 
24 #include "architecture.h"
25 #include "kernel_defines.h"
26 #include "list.h"
27 #include "thread.h"
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
36 typedef struct {
43 #if defined(DOXYGEN) || defined(MODULE_CORE_MUTEX_PRIORITY_INHERITANCE) \
44  || defined(MODULE_CORE_MUTEX_DEBUG)
55 #endif
56 #if defined(DOXYGEN) || defined(MODULE_CORE_MUTEX_DEBUG)
65 #endif
66 #if defined(DOXYGEN) || defined(MODULE_CORE_MUTEX_PRIORITY_INHERITANCE)
73 #endif
74 } mutex_t;
75 
95 bool mutex_lock_internal(mutex_t *mutex, bool block);
96 
103 typedef struct {
106  uint8_t cancelled;
108 
109 #ifndef __cplusplus
114 # define MUTEX_INIT { .queue = { .next = NULL } }
115 
119 # define MUTEX_INIT_LOCKED { .queue = { .next = MUTEX_LOCKED } }
120 #else
121 # define MUTEX_INIT {}
122 # define MUTEX_INIT_LOCKED { { MUTEX_LOCKED } }
123 #endif /* __cplusplus */
124 
130 #define MUTEX_LOCKED ((list_node_t *)-1)
141 static inline void mutex_init(mutex_t *mutex)
142 {
143  mutex->queue.next = NULL;
144 }
145 
152 static inline void mutex_init_locked(mutex_t *mutex)
153 {
154  *mutex = (mutex_t)MUTEX_INIT_LOCKED;
155 }
156 
168 {
169  mutex_cancel_t result = { mutex, thread_get_active(), 0 };
170 
171  return result;
172 }
173 
186 static inline int mutex_trylock(mutex_t *mutex)
187 {
188  return mutex_lock_internal(mutex, false);
189 }
190 
202 static inline void mutex_lock(mutex_t *mutex)
203 {
204 #if (MAXTHREADS > 1)
205  mutex_lock_internal(mutex, true);
206 #else
207  /* dummy implementation for when no scheduler is used */
208  /* (ab)use next pointer as lock variable */
209  volatile uintptr_t *lock = (void *)&mutex->queue.next;
210 
211  /* spin until lock is released (e.g. by interrupt).
212  *
213  * Note: since only the numbers 0 and 1 are ever stored in lock, this
214  * read does not need to be atomic here - even while a concurrent write
215  * is performed on lock, a read will still either yield 0 or 1 (so the old
216  * or new value, which both is fine), even if the lock is read out byte-wise
217  * (e.g. on AVR).
218  */
219  while (*lock) {}
220 
221  /* set lock variable */
222  *lock = 1;
223 #endif
224 }
225 
249 
259 #if (MAXTHREADS > 1) || DOXYGEN
260 void mutex_unlock(mutex_t *mutex);
261 #else
265 static inline void mutex_unlock(mutex_t *mutex)
266 {
267  /* (ab)use next pointer as lock variable */
268  mutex->queue.next = NULL;
269 }
270 #endif
271 
280 
343 
344 #ifdef __cplusplus
345 }
346 #endif
347 
Platform-independent access to architecture details.
int16_t kernel_pid_t
Unique process identifier.
Definition: sched.h:135
void mutex_unlock(mutex_t *mutex)
Unlocks the mutex.
void mutex_cancel(mutex_cancel_t *mc)
Cancels a call to mutex_lock_cancelable.
static mutex_cancel_t mutex_cancel_init(mutex_t *mutex)
Initialize a mutex cancellation structure.
Definition: mutex.h:167
int mutex_lock_cancelable(mutex_cancel_t *mc)
Locks a mutex, blocking.
static void mutex_init_locked(mutex_t *mutex)
Initializes a mutex object in a locked state.
Definition: mutex.h:152
#define MUTEX_INIT_LOCKED
Static initializer for mutex_t with a locked mutex.
Definition: mutex.h:119
static void mutex_init(mutex_t *mutex)
Initializes a mutex object.
Definition: mutex.h:141
void mutex_unlock_and_sleep(mutex_t *mutex)
Unlocks the mutex and sends the current thread to sleep.
static void mutex_lock(mutex_t *mutex)
Locks a mutex, blocking.
Definition: mutex.h:202
static int mutex_trylock(mutex_t *mutex)
Tries to get a mutex, non-blocking.
Definition: mutex.h:186
bool mutex_lock_internal(mutex_t *mutex, bool block)
Internal function implementing mutex_lock and mutex_trylock.
static thread_t * thread_get_active(void)
Returns a pointer to the Thread Control Block of the currently running thread.
Definition: thread.h:410
uintptr_t uinttxtptr_t
Pointer type to point anywhere in the .text section.
Definition: architecture.h:135
Common macros and compiler attributes/pragmas configuration.
Intrusive linked list.
thread_t holds thread's context data.
Definition: thread.h:167
List node structure.
Definition: list.h:36
struct list_node * next
pointer to next list entry
Definition: list.h:37
A cancellation structure for use with mutex_lock_cancelable and mutex_cancel.
Definition: mutex.h:103
thread_t * thread
The thread trying to lock the mutex.
Definition: mutex.h:105
uint8_t cancelled
Flag whether the mutex has been cancelled.
Definition: mutex.h:106
mutex_t * mutex
The mutex to lock.
Definition: mutex.h:104
Mutex structure.
Definition: mutex.h:36
uint8_t owner_original_priority
Original priority of the owner.
Definition: mutex.h:72
kernel_pid_t owner
The current owner of the mutex or NULL
Definition: mutex.h:54
list_node_t queue
The process waiting queue of the mutex.
Definition: mutex.h:42
uinttxtptr_t owner_calling_pc
Program counter of the call to mutex_lock that most recently acquired this mutex.
Definition: mutex.h:64
Provides utility functions for event handler threads.