ChibiOS/RT  5.1.0
chbsem.h
Go to the documentation of this file.
1 /*
2  ChibiOS - Copyright (C) 2006..2018 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; either version 3 of the License, or
9  (at your option) any later version.
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 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 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  */
75 typedef struct ch_binary_semaphore {
76  semaphore_t sem;
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  */
124 static 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 bsemReset().
138  *
139  * @api
140  */
141 static inline msg_t chBSemWait(binary_semaphore_t *bsp) {
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 bsemReset().
155  *
156  * @sclass
157  */
158 static inline msg_t chBSemWaitS(binary_semaphore_t *bsp) {
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 bsemReset().
179  * @retval MSG_TIMEOUT if the binary semaphore has not been signaled or reset
180  * within the specified timeout.
181  *
182  * @sclass
183  */
184 static inline msg_t chBSemWaitTimeoutS(binary_semaphore_t *bsp,
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 bsemReset().
206  * @retval MSG_TIMEOUT if the binary semaphore has not been signaled or reset
207  * within the specified timeout.
208  *
209  * @api
210  */
211 static inline msg_t chBSemWaitTimeout(binary_semaphore_t *bsp,
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 bsemWait() 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  */
232 static 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 bsemWait() 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  */
253 static 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  */
266 static 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  */
282 static 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  */
300 static 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 /** @} */
msg_t chSemWait(semaphore_t *sp)
Performs a wait operation on a semaphore.
Definition: chsem.c:175
static bool chBSemGetStateI(const binary_semaphore_t *bsp)
Returns the binary semaphore current state.
Definition: chbsem.h:300
void chDbgCheckClassS(void)
S-class functions context check.
Definition: chdebug.c:250
static void chBSemObjectInit(binary_semaphore_t *bsp, bool taken)
Initializes a binary semaphore.
Definition: chbsem.h:124
cnt_t cnt
The semaphore counter.
Definition: chsem.h:55
uint64_t sysinterval_t
Type of time interval.
Definition: chtime.h:150
static void chSysLock(void)
Enters the kernel lock state.
Definition: chsys.h:353
msg_t chSemWaitTimeoutS(semaphore_t *sp, sysinterval_t timeout)
Performs a wait operation on a semaphore with timeout specification.
Definition: chsem.c:264
msg_t chSemWaitS(semaphore_t *sp)
Performs a wait operation on a semaphore.
Definition: chsem.c:197
static void chBSemSignal(binary_semaphore_t *bsp)
Performs a signal operation on a binary semaphore.
Definition: chbsem.h:282
static void chBSemReset(binary_semaphore_t *bsp, bool taken)
Reset operation on the binary semaphore.
Definition: chbsem.h:253
static void chSysUnlock(void)
Leaves the kernel lock state.
Definition: chsys.h:365
static void chBSemResetI(binary_semaphore_t *bsp, bool taken)
Reset operation on the binary semaphore.
Definition: chbsem.h:232
struct ch_binary_semaphore binary_semaphore_t
Binary semaphore type.
void chDbgCheckClassI(void)
I-class functions context check.
Definition: chdebug.c:235
Binary semaphore type.
Definition: chbsem.h:75
void chSchRescheduleS(void)
Performs a reschedule if a higher priority thread is runnable.
Definition: chschd.c:456
void chSemReset(semaphore_t *sp, cnt_t n)
Performs a reset operation on the semaphore.
Definition: chsem.c:120
static msg_t chBSemWaitS(binary_semaphore_t *bsp)
Wait operation on the binary semaphore.
Definition: chbsem.h:158
static msg_t chBSemWaitTimeoutS(binary_semaphore_t *bsp, sysinterval_t timeout)
Wait operation on the binary semaphore.
Definition: chbsem.h:184
static void chBSemSignalI(binary_semaphore_t *bsp)
Performs a signal operation on a binary semaphore.
Definition: chbsem.h:266
Semaphore structure.
Definition: chsem.h:52
static msg_t chBSemWait(binary_semaphore_t *bsp)
Wait operation on the binary semaphore.
Definition: chbsem.h:141
void chSemObjectInit(semaphore_t *sp, cnt_t n)
Initializes a semaphore with the specified counter value.
Definition: chsem.c:97
static msg_t chBSemWaitTimeout(binary_semaphore_t *bsp, sysinterval_t timeout)
Wait operation on the binary semaphore.
Definition: chbsem.h:211
msg_t chSemWaitTimeout(semaphore_t *sp, sysinterval_t timeout)
Performs a wait operation on a semaphore with timeout specification.
Definition: chsem.c:235
void chSemSignalI(semaphore_t *sp)
Performs a signal operation on a semaphore.
Definition: chsem.c:319
void chSemResetI(semaphore_t *sp, cnt_t n)
Performs a reset operation on the semaphore.
Definition: chsem.c:147