mutex.h
3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
/*
* Copyright (C) 2015 Kaspar Schleiser <kaspar@schleiser.de>
* 2013, 2014 Freie Universität Berlin
*
* This file is subject to the terms and conditions of the GNU Lesser
* General Public License v2.1. See the file LICENSE in the top level
* directory for more details.
*/
/**
* @defgroup core_sync Synchronization
* @brief Mutex for thread synchronization
* @ingroup core
* @{
*
* @file
* @brief RIOT synchronization API
*
* @author Kaspar Schleiser <kaspar@schleiser.de>
*/
#ifndef MUTEX_H_
#define MUTEX_H_
#include <stddef.h>
#include "list.h"
#include "atomic.h"
#ifdef __cplusplus
extern "C" {
#endif
/**
* @brief Mutex structure. Must never be modified by the user.
*/
typedef struct {
/**
* @brief The process waiting queue of the mutex. **Must never be changed
* by the user.**
* @internal
*/
list_node_t queue;
} mutex_t;
/**
* @brief Static initializer for mutex_t.
* @details This initializer is preferable to mutex_init().
*/
#define MUTEX_INIT { { NULL } }
/**
* @brief Static initializer for mutex_t with a locked mutex
*/
#define MUTEX_INIT_LOCKED { { MUTEX_LOCKED } }
/**
* @internal
* @brief This is the value of the mutex when locked and no threads are waiting
* for it
*/
#define MUTEX_LOCKED ((void *)-1)
/**
* @brief Initializes a mutex object.
* @details For initialization of variables use MUTEX_INIT instead.
* Only use the function call for dynamically allocated mutexes.
* @param[out] mutex pre-allocated mutex structure, must not be NULL.
*/
static inline void mutex_init(mutex_t *mutex)
{
mutex->queue.next = NULL;
}
/**
* @brief Lock a mutex, blocking or non-blocking.
*
* @details For commit purposes you should probably use mutex_trylock() and
* mutex_lock() instead.
*
* @param[in] mutex Mutex object to lock. Has to be initialized first.
* Must not be NULL.
* @param[in] blocking if true, block until mutex is available.
*
* @return 1 if mutex was unlocked, now it is locked.
* @return 0 if the mutex was locked.
*/
int _mutex_lock(mutex_t *mutex, int blocking);
/**
* @brief Tries to get a mutex, non-blocking.
*
* @param[in] mutex Mutex object to lock. Has to be initialized first. Must not
* be NULL.
*
* @return 1 if mutex was unlocked, now it is locked.
* @return 0 if the mutex was locked.
*/
static inline int mutex_trylock(mutex_t *mutex)
{
return _mutex_lock(mutex, 0);
}
/**
* @brief Locks a mutex, blocking.
*
* @param[in] mutex Mutex object to lock. Has to be initialized first. Must not be NULL.
*/
static inline void mutex_lock(mutex_t *mutex)
{
_mutex_lock(mutex, 1);
}
/**
* @brief Unlocks the mutex.
*
* @param[in] mutex Mutex object to unlock, must not be NULL.
*/
void mutex_unlock(mutex_t *mutex);
/**
* @brief Unlocks the mutex and sends the current thread to sleep
*
* @param[in] mutex Mutex object to unlock, must not be NULL.
*/
void mutex_unlock_and_sleep(mutex_t *mutex);
#ifdef __cplusplus
}
#endif
#endif /* MUTEX_H_ */
/** @} */