chbsem.h 11 KB

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