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