mutex.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
3  * 2013, 2014 Freie Universit├Ąt Berlin
4  *
5  * This file is subject to the terms and conditions of the GNU Lesser
6  * General Public License v2.1. See the file LICENSE in the top level
7  * directory for more details.
8  */
9 
108 #ifndef MUTEX_H
109 #define MUTEX_H
110 
111 #include <stddef.h>
112 #include <stdint.h>
113 #include <stdbool.h>
114 
115 #include "kernel_defines.h"
116 #include "list.h"
117 #include "thread.h"
118 
119 #ifdef __cplusplus
120 extern "C" {
121 #endif
122 
126 typedef struct {
133 #if defined(DOXYGEN) || defined(MODULE_CORE_MUTEX_PRIORITY_INHERITANCE)
150 #endif
151 } mutex_t;
152 
172 bool mutex_lock_internal(mutex_t *mutex, bool block);
173 
180 typedef struct {
183  uint8_t cancelled;
185 
186 #ifndef __cplusplus
191 # define MUTEX_INIT { .queue = { .next = NULL } }
192 
196 # define MUTEX_INIT_LOCKED { .queue = { .next = MUTEX_LOCKED } }
197 #else
198 # define MUTEX_INIT {}
199 # define MUTEX_INIT_LOCKED { { MUTEX_LOCKED } }
200 #endif /* __cplusplus */
201 
207 #define MUTEX_LOCKED ((list_node_t *)-1)
218 static inline void mutex_init(mutex_t *mutex)
219 {
220  mutex->queue.next = NULL;
221 }
222 
234 {
235  mutex_cancel_t result = { mutex, thread_get_active(), 0 };
236 
237  return result;
238 }
239 
252 static inline int mutex_trylock(mutex_t *mutex)
253 {
254  return mutex_lock_internal(mutex, false);
255 }
256 
268 static inline void mutex_lock(mutex_t *mutex)
269 {
270 #if (MAXTHREADS > 1)
271  mutex_lock_internal(mutex, true);
272 #else
273  /* dummy implementation for when no scheduler is used */
274  /* (ab)use next pointer as lock variable */
275  volatile uintptr_t *lock = (void *)&mutex->queue.next;
276 
277  /* spin until lock is released (e.g. by interrupt).
278  *
279  * Note: since only the numbers 0 and 1 are ever stored in lock, this
280  * read does not need to be atomic here - even while a concurrent write
281  * is performed on lock, a read will still either yield 0 or 1 (so the old
282  * or new value, which both is fine), even if the lock is read out byte-wise
283  * (e.g. on AVR).
284  */
285  while (*lock) {}
286 
287  /* set lock variable */
288  *lock = 1;
289 #endif
290 }
291 
315 
325 #if (MAXTHREADS > 1) || DOXYGEN
326 void mutex_unlock(mutex_t *mutex);
327 #else
331 static inline void mutex_unlock(mutex_t *mutex)
332 {
333  /* (ab)use next pointer as lock variable */
334  mutex->queue.next = NULL;
335 }
336 #endif
337 
346 
409 
410 #ifdef __cplusplus
411 }
412 #endif
413 
414 #endif /* MUTEX_H */
int16_t kernel_pid_t
Unique process identifier.
Definition: sched.h:139
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:233
int mutex_lock_cancelable(mutex_cancel_t *mc)
Locks a mutex, blocking.
static void mutex_init(mutex_t *mutex)
Initializes a mutex object.
Definition: mutex.h:218
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:268
static int mutex_trylock(mutex_t *mutex)
Tries to get a mutex, non-blocking.
Definition: mutex.h:252
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:401
Common macros and compiler attributes/pragmas configuration.
Intrusive linked list.
thread_t holds thread's context data.
Definition: thread.h:169
List node structure.
Definition: list.h:40
struct list_node * next
pointer to next list entry
Definition: list.h:41
A cancellation structure for use with mutex_lock_cancelable and mutex_cancel.
Definition: mutex.h:180
thread_t * thread
The thread trying to lock the mutex.
Definition: mutex.h:182
uint8_t cancelled
Flag whether the mutex has been cancelled.
Definition: mutex.h:183
mutex_t * mutex
The mutex to lock.
Definition: mutex.h:181
Mutex structure.
Definition: mutex.h:126
uint8_t owner_original_priority
Original priority of the owner.
Definition: mutex.h:149
kernel_pid_t owner
The current owner of the mutex or NULL
Definition: mutex.h:143
list_node_t queue
The process waiting queue of the mutex.
Definition: mutex.h:132
Provides utility functions for event handler threads.