ChibiOS 21.11.4
chbsem.h
Go to the documentation of this file.
1/*
2 ChibiOS - Copyright (C) 2006,2007,2008,2009,2010,2011,2012,2013,2014,
3 2015,2016,2017,2018,2019,2020,2021 Giovanni Di Sirio.
4
5 This file is part of ChibiOS.
6
7 ChibiOS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation version 3 of the License.
10
11 ChibiOS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20/**
21 * @file oslib/include/chbsem.h
22 * @brief Binary semaphores structures and macros.
23 * @details Binary semaphores related APIs and services.
24 * <h2>Operation mode</h2>
25 * Binary semaphores are implemented as a set of inline functions
26 * that use the existing counting semaphores primitives. The
27 * difference between counting and binary semaphores is that the
28 * counter of binary semaphores is not allowed to grow above the
29 * value 1. Repeated signal operation are ignored. A binary
30 * semaphore can thus have only two defined states:
31 * - <b>Taken</b>, when its counter has a value of zero or lower
32 * than zero. A negative number represent the number of threads
33 * queued on the binary semaphore.
34 * - <b>Not taken</b>, when its counter has a value of one.
35 * .
36 * Binary semaphores are different from mutexes because there is no
37 * concept of ownership, a binary semaphore can be taken by a
38 * thread and signaled by another thread or an interrupt handler,
39 * mutexes can only be taken and released by the same thread. Another
40 * difference is that binary semaphores, unlike mutexes, do not
41 * implement the priority inheritance protocol.<br>
42 * In order to use the binary semaphores APIs the
43 * @p CH_CFG_USE_SEMAPHORES option must be enabled in @p chconf.h.
44 *
45 * @addtogroup oslib_binary_semaphores
46 * @{
47 */
48
49#ifndef CHBSEM_H
50#define CHBSEM_H
51
52#if (CH_CFG_USE_SEMAPHORES == TRUE) || defined(__DOXYGEN__)
53
54/*===========================================================================*/
55/* Module constants. */
56/*===========================================================================*/
57
58/*===========================================================================*/
59/* Module pre-compile time settings. */
60/*===========================================================================*/
61
62/*===========================================================================*/
63/* Derived constants and error checks. */
64/*===========================================================================*/
65
66/*===========================================================================*/
67/* Module data structures and types. */
68/*===========================================================================*/
69
70/**
71 * @extends semaphore_t
72 *
73 * @brief Binary semaphore type.
74 */
78
79/*===========================================================================*/
80/* Module macros. */
81/*===========================================================================*/
82
83/**
84 * @brief Data part of a static semaphore initializer.
85 * @details This macro should be used when statically initializing a semaphore
86 * that is part of a bigger structure.
87 *
88 * @param[in] name the name of the semaphore variable
89 * @param[in] taken the semaphore initial state
90 */
91#define __BSEMAPHORE_DATA(name, taken) \
92 {__SEMAPHORE_DATA(name.sem, ((taken) ? 0 : 1))}
93
94/**
95 * @brief Static semaphore initializer.
96 * @details Statically initialized semaphores require no explicit
97 * initialization using @p chBSemInit().
98 *
99 * @param[in] name the name of the semaphore variable
100 * @param[in] taken the semaphore initial state
101 */
102#define BSEMAPHORE_DECL(name, taken) \
103 binary_semaphore_t name = __BSEMAPHORE_DATA(name, taken)
104
105/*===========================================================================*/
106/* External declarations. */
107/*===========================================================================*/
108
109/*===========================================================================*/
110/* Module inline functions. */
111/*===========================================================================*/
112
113/**
114 * @brief Initializes a binary semaphore.
115 *
116 * @param[out] bsp pointer to a @p binary_semaphore_t structure
117 * @param[in] taken initial state of the binary semaphore:
118 * - @a false, the initial state is not taken.
119 * - @a true, the initial state is taken.
120 * .
121 *
122 * @init
123 */
124static inline void chBSemObjectInit(binary_semaphore_t *bsp, bool taken) {
125
126 chSemObjectInit(&bsp->sem, taken ? (cnt_t)0 : (cnt_t)1);
127}
128
129/**
130 * @brief Wait operation on the binary semaphore.
131 *
132 * @param[in] bsp pointer to a @p binary_semaphore_t structure
133 * @return A message specifying how the invoking thread has been
134 * released from the semaphore.
135 * @retval MSG_OK if the binary semaphore has been successfully taken.
136 * @retval MSG_RESET if the binary semaphore has been reset using
137 * @p chBSemReset().
138 *
139 * @api
140 */
142
143 return chSemWait(&bsp->sem);
144}
145
146/**
147 * @brief Wait operation on the binary semaphore.
148 *
149 * @param[in] bsp pointer to a @p binary_semaphore_t structure
150 * @return A message specifying how the invoking thread has been
151 * released from the semaphore.
152 * @retval MSG_OK if the binary semaphore has been successfully taken.
153 * @retval MSG_RESET if the binary semaphore has been reset using
154 * @p chBSemReset().
155 *
156 * @sclass
157 */
159
161
162 return chSemWaitS(&bsp->sem);
163}
164
165/**
166 * @brief Wait operation on the binary semaphore.
167 *
168 * @param[in] bsp pointer to a @p binary_semaphore_t structure
169 * @param[in] timeout the number of ticks before the operation timeouts,
170 * the following special values are allowed:
171 * - @a TIME_IMMEDIATE immediate timeout.
172 * - @a TIME_INFINITE no timeout.
173 * .
174 * @return A message specifying how the invoking thread has been
175 * released from the semaphore.
176 * @retval MSG_OK if the binary semaphore has been successfully taken.
177 * @retval MSG_RESET if the binary semaphore has been reset using
178 * @p chBSemReset().
179 * @retval MSG_TIMEOUT if the binary semaphore has not been signaled or reset
180 * within the specified timeout.
181 *
182 * @sclass
183 */
185 sysinterval_t timeout) {
186
188
189 return chSemWaitTimeoutS(&bsp->sem, timeout);
190}
191
192/**
193 * @brief Wait operation on the binary semaphore.
194 *
195 * @param[in] bsp pointer to a @p binary_semaphore_t structure
196 * @param[in] timeout the number of ticks before the operation timeouts,
197 * the following special values are allowed:
198 * - @a TIME_IMMEDIATE immediate timeout.
199 * - @a TIME_INFINITE no timeout.
200 * .
201 * @return A message specifying how the invoking thread has been
202 * released from the semaphore.
203 * @retval MSG_OK if the binary semaphore has been successfully taken.
204 * @retval MSG_RESET if the binary semaphore has been reset using
205 * @p chBSemReset().
206 * @retval MSG_TIMEOUT if the binary semaphore has not been signaled or reset
207 * within the specified timeout.
208 *
209 * @api
210 */
212 sysinterval_t timeout) {
213
214 return chSemWaitTimeout(&bsp->sem, timeout);
215}
216
217/**
218 * @brief Reset operation on the binary semaphore.
219 * @note The released threads can recognize they were waked up by a reset
220 * rather than a signal because the @p chBSemWait() will return
221 * @p MSG_RESET instead of @p MSG_OK.
222 * @note This function does not reschedule.
223 *
224 * @param[in] bsp pointer to a @p binary_semaphore_t structure
225 * @param[in] taken new state of the binary semaphore
226 * - @a false, the new state is not taken.
227 * - @a true, the new state is taken.
228 * .
229 *
230 * @iclass
231 */
232static inline void chBSemResetI(binary_semaphore_t *bsp, bool taken) {
233
235
236 chSemResetI(&bsp->sem, taken ? (cnt_t)0 : (cnt_t)1);
237}
238
239/**
240 * @brief Reset operation on the binary semaphore.
241 * @note The released threads can recognize they were waked up by a reset
242 * rather than a signal because the @p chBSemWait() will return
243 * @p MSG_RESET instead of @p MSG_OK.
244 *
245 * @param[in] bsp pointer to a @p binary_semaphore_t structure
246 * @param[in] taken new state of the binary semaphore
247 * - @a false, the new state is not taken.
248 * - @a true, the new state is taken.
249 * .
250 *
251 * @api
252 */
253static inline void chBSemReset(binary_semaphore_t *bsp, bool taken) {
254
255 chSemReset(&bsp->sem, taken ? (cnt_t)0 : (cnt_t)1);
256}
257
258/**
259 * @brief Performs a signal operation on a binary semaphore.
260 * @note This function does not reschedule.
261 *
262 * @param[in] bsp pointer to a @p binary_semaphore_t structure
263 *
264 * @iclass
265 */
266static inline void chBSemSignalI(binary_semaphore_t *bsp) {
267
269
270 if (bsp->sem.cnt < (cnt_t)1) {
271 chSemSignalI(&bsp->sem);
272 }
273}
274
275/**
276 * @brief Performs a signal operation on a binary semaphore.
277 *
278 * @param[in] bsp pointer to a @p binary_semaphore_t structure
279 *
280 * @api
281 */
282static inline void chBSemSignal(binary_semaphore_t *bsp) {
283
284 chSysLock();
285 chBSemSignalI(bsp);
287 chSysUnlock();
288}
289
290/**
291 * @brief Returns the binary semaphore current state.
292 *
293 * @param[in] bsp pointer to a @p binary_semaphore_t structure
294 * @return The binary semaphore current state.
295 * @retval false if the binary semaphore is not taken.
296 * @retval true if the binary semaphore is taken.
297 *
298 * @iclass
299 */
300static inline bool chBSemGetStateI(const binary_semaphore_t *bsp) {
301
303
304 return (bsp->sem.cnt > (cnt_t)0) ? false : true;
305}
306
307#endif /* CH_CFG_USE_SEMAPHORES == TRUE */
308
309#endif /* CHBSEM_H */
310
311/** @} */
#define chSysUnlock()
Leaves the kernel lock state.
#define chSysLock()
Enters the kernel lock state.
#define chSemReset(sp, n)
Performs a reset operation on the semaphore.
#define chSemWait(sp)
Performs a wait operation on a semaphore.
#define chSemResetI(sp, n)
Performs a reset operation on the semaphore.
#define chSemWaitS(sp)
Performs a wait operation on a semaphore.
#define chSemObjectInit(sp, n)
Initializes a semaphore with the specified counter value.
#define chDbgCheckClassS()
Definition chdebug.h:100
#define chDbgCheckClassI()
Definition chdebug.h:99
int32_t cnt_t
Definition chearly.h:92
int32_t msg_t
Definition chearly.h:88
static msg_t chBSemWaitTimeoutS(binary_semaphore_t *bsp, sysinterval_t timeout)
Wait operation on the binary semaphore.
Definition chbsem.h:184
static void chBSemObjectInit(binary_semaphore_t *bsp, bool taken)
Initializes a binary semaphore.
Definition chbsem.h:124
static void chBSemReset(binary_semaphore_t *bsp, bool taken)
Reset operation on the binary semaphore.
Definition chbsem.h:253
static void chBSemResetI(binary_semaphore_t *bsp, bool taken)
Reset operation on the binary semaphore.
Definition chbsem.h:232
static bool chBSemGetStateI(const binary_semaphore_t *bsp)
Returns the binary semaphore current state.
Definition chbsem.h:300
static void chBSemSignalI(binary_semaphore_t *bsp)
Performs a signal operation on a binary semaphore.
Definition chbsem.h:266
struct ch_binary_semaphore binary_semaphore_t
Binary semaphore type.
static void chBSemSignal(binary_semaphore_t *bsp)
Performs a signal operation on a binary semaphore.
Definition chbsem.h:282
static msg_t chBSemWait(binary_semaphore_t *bsp)
Wait operation on the binary semaphore.
Definition chbsem.h:141
static msg_t chBSemWaitS(binary_semaphore_t *bsp)
Wait operation on the binary semaphore.
Definition chbsem.h:158
static msg_t chBSemWaitTimeout(binary_semaphore_t *bsp, sysinterval_t timeout)
Wait operation on the binary semaphore.
Definition chbsem.h:211
void chSchRescheduleS(void)
Performs a reschedule if a higher priority thread is runnable.
Definition chschd.c:458
msg_t chSemWaitTimeout(semaphore_t *sp, sysinterval_t timeout)
Performs a wait operation on a semaphore with timeout specification.
struct ch_semaphore semaphore_t
Semaphore structure.
msg_t chSemWaitTimeoutS(semaphore_t *sp, sysinterval_t timeout)
Performs a wait operation on a semaphore with timeout specification.
void chSemSignalI(semaphore_t *sp)
Performs a signal operation on a semaphore.
uint64_t sysinterval_t
Type of time interval.
Definition chtime.h:119
Binary semaphore type.
Definition chbsem.h:75
semaphore_t sem
Definition chbsem.h:76
cnt_t cnt
The semaphore counter.