ChibiOS/RT
2.5.1
chbsem.h
Go to the documentation of this file.
00001 /*
00002     ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010,
00003                  2011,2012 Giovanni Di Sirio.
00004 
00005     This file is part of ChibiOS/RT.
00006 
00007     ChibiOS/RT is free software; you can redistribute it and/or modify
00008     it under the terms of the GNU General Public License as published by
00009     the Free Software Foundation; either version 3 of the License, or
00010     (at your option) any later version.
00011 
00012     ChibiOS/RT is distributed in the hope that it will be useful,
00013     but WITHOUT ANY WARRANTY; without even the implied warranty of
00014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015     GNU General Public License for more details.
00016 
00017     You should have received a copy of the GNU General Public License
00018     along with this program.  If not, see <http://www.gnu.org/licenses/>.
00019 */
00020 
00021 /**
00022  * @file    chbsem.h
00023  * @brief   Binary semaphores structures and macros.
00024  *
00025  * @addtogroup binary_semaphores
00026  * @details Binary semaphores related APIs and services.
00027  *
00028  *          <h2>Operation mode</h2>
00029  *          Binary semaphores are implemented as a set of macros that use the
00030  *          existing counting semaphores primitives. The difference between
00031  *          counting and binary semaphores is that the counter of binary
00032  *          semaphores is not allowed to grow above the value 1. Repeated
00033  *          signal operation are ignored. A binary semaphore can thus have
00034  *          only two defined states:
00035  *          - <b>Taken</b>, when its counter has a value of zero or lower
00036  *            than zero. A negative number represent the number of threads
00037  *            queued on the binary semaphore.
00038  *          - <b>Not taken</b>, when its counter has a value of one.
00039  *          .
00040  *          Binary semaphores are different from mutexes because there is no
00041  *          the concept of ownership, a binary semaphore can be taken by a
00042  *          thread and signaled by another thread or an interrupt handler,
00043  *          mutexes can only be taken and released by the same thread. Another
00044  *          difference is that binary semaphores, unlike mutexes, do not
00045  *          implement the priority inheritance protocol.<br>
00046  *          In order to use the binary semaphores APIs the @p CH_USE_SEMAPHORES
00047  *          option must be enabled in @p chconf.h.
00048  * @{
00049  */
00050 
00051 #ifndef _CHBSEM_H_
00052 #define _CHBSEM_H_
00053 
00054 #if CH_USE_SEMAPHORES || defined(__DOXYGEN__)
00055 
00056 /**
00057  * @extends Semaphore
00058  *
00059  * @brief   Binary semaphore type.
00060  */
00061 typedef struct  {
00062   Semaphore             bs_sem;
00063 } BinarySemaphore;
00064 
00065 /**
00066  * @brief   Data part of a static semaphore initializer.
00067  * @details This macro should be used when statically initializing a semaphore
00068  *          that is part of a bigger structure.
00069  *
00070  * @param[in] name      the name of the semaphore variable
00071  * @param[in] taken     the semaphore initial state
00072  */
00073 #define _BSEMAPHORE_DATA(name, taken)                                       \
00074   {_SEMAPHORE_DATA(name.bs_sem, ((taken) ? 0 : 1))}
00075 
00076 /**
00077  * @brief   Static semaphore initializer.
00078  * @details Statically initialized semaphores require no explicit
00079  *          initialization using @p chSemInit().
00080  *
00081  * @param[in] name      the name of the semaphore variable
00082  * @param[in] taken     the semaphore initial state
00083  */
00084 #define BSEMAPHORE_DECL(name, taken)                                        \
00085   BinarySemaphore name = _BSEMAPHORE_DATA(name, taken)
00086 
00087 /**
00088  * @name    Macro Functions
00089  * @{
00090  */
00091 /**
00092  * @brief   Initializes a binary semaphore.
00093  *
00094  * @param[out] bsp      pointer to a @p BinarySemaphore structure
00095  * @param[in] taken     initial state of the binary semaphore:
00096  *                      - @a FALSE, the initial state is not taken.
00097  *                      - @a TRUE, the initial state is taken.
00098  *                      .
00099  *
00100  * @init
00101  */
00102 #define chBSemInit(bsp, taken) chSemInit(&(bsp)->bs_sem, (taken) ? 0 : 1)
00103 
00104 /**
00105  * @brief   Wait operation on the binary semaphore.
00106  *
00107  * @param[in] bsp       pointer to a @p BinarySemaphore structure
00108  * @return              A message specifying how the invoking thread has been
00109  *                      released from the semaphore.
00110  * @retval RDY_OK       if the binary semaphore has been successfully taken.
00111  * @retval RDY_RESET    if the binary semaphore has been reset using
00112  *                      @p bsemReset().
00113  *
00114  * @api
00115  */
00116 #define chBSemWait(bsp) chSemWait(&(bsp)->bs_sem)
00117 
00118 /**
00119  * @brief   Wait operation on the binary semaphore.
00120  *
00121  * @param[in] bsp       pointer to a @p BinarySemaphore structure
00122  * @return              A message specifying how the invoking thread has been
00123  *                      released from the semaphore.
00124  * @retval RDY_OK       if the binary semaphore has been successfully taken.
00125  * @retval RDY_RESET    if the binary semaphore has been reset using
00126  *                      @p bsemReset().
00127  *
00128  * @sclass
00129  */
00130 #define chBSemWaitS(bsp) chSemWaitS(&(bsp)->bs_sem)
00131 
00132 /**
00133  * @brief   Wait operation on the binary semaphore.
00134  *
00135  * @param[in] bsp       pointer to a @p BinarySemaphore structure
00136  * @param[in] time      the number of ticks before the operation timeouts,
00137  *                      the following special values are allowed:
00138  *                      - @a TIME_IMMEDIATE immediate timeout.
00139  *                      - @a TIME_INFINITE no timeout.
00140  *                      .
00141  * @return              A message specifying how the invoking thread has been
00142  *                      released from the semaphore.
00143  * @retval RDY_OK       if the binary semaphore has been successfully taken.
00144  * @retval RDY_RESET    if the binary semaphore has been reset using
00145  *                      @p bsemReset().
00146  * @retval RDY_TIMEOUT  if the binary semaphore has not been signaled or reset
00147  *                      within the specified timeout.
00148  *
00149  * @api
00150  */
00151 #define chBSemWaitTimeout(bsp, time) chSemWaitTimeout(&(bsp)->bs_sem, (time))
00152 
00153 /**
00154  * @brief   Wait operation on the binary semaphore.
00155  *
00156  * @param[in] bsp       pointer to a @p BinarySemaphore structure
00157  * @param[in] time      the number of ticks before the operation timeouts,
00158  *                      the following special values are allowed:
00159  *                      - @a TIME_IMMEDIATE immediate timeout.
00160  *                      - @a TIME_INFINITE no timeout.
00161  *                      .
00162  * @return              A message specifying how the invoking thread has been
00163  *                      released from the semaphore.
00164  * @retval RDY_OK       if the binary semaphore has been successfully taken.
00165  * @retval RDY_RESET    if the binary semaphore has been reset using
00166  *                      @p bsemReset().
00167  * @retval RDY_TIMEOUT  if the binary semaphore has not been signaled or reset
00168  *                      within the specified timeout.
00169  *
00170  * @sclass
00171  */
00172 #define chBSemWaitTimeoutS(bsp, time) chSemWaitTimeoutS(&(bsp)->bs_sem, (time))
00173 
00174 /**
00175  * @brief   Reset operation on the binary semaphore.
00176  * @note    The released threads can recognize they were waked up by a reset
00177  *          rather than a signal because the @p bsemWait() will return
00178  *          @p RDY_RESET instead of @p RDY_OK.
00179  *
00180  * @param[in] bsp       pointer to a @p BinarySemaphore structure
00181  * @param[in] taken     new state of the binary semaphore
00182  *                      - @a FALSE, the new state is not taken.
00183  *                      - @a TRUE, the new state is taken.
00184  *                      .
00185  *
00186  * @api
00187  */
00188 #define chBSemReset(bsp, taken) chSemReset(&(bsp)->bs_sem, (taken) ? 0 : 1)
00189 
00190 /**
00191  * @brief   Reset operation on the binary semaphore.
00192  * @note    The released threads can recognize they were waked up by a reset
00193  *          rather than a signal because the @p bsemWait() will return
00194  *          @p RDY_RESET instead of @p RDY_OK.
00195  * @note    This function does not reschedule.
00196  *
00197  * @param[in] bsp       pointer to a @p BinarySemaphore structure
00198  * @param[in] taken     new state of the binary semaphore
00199  *                      - @a FALSE, the new state is not taken.
00200  *                      - @a TRUE, the new state is taken.
00201  *                      .
00202  *
00203  * @iclass
00204  */
00205 #define chBSemResetI(bsp, taken) chSemResetI(&(bsp)->bs_sem, (taken) ? 0 : 1)
00206 
00207 /**
00208  * @brief   Performs a signal operation on a binary semaphore.
00209  *
00210  * @param[in] bsp       pointer to a @p BinarySemaphore structure
00211  *
00212  * @api
00213  */
00214 #define chBSemSignal(bsp) {                                                 \
00215   chSysLock();                                                              \
00216   chBSemSignalI((bsp));                                                     \
00217   chSchRescheduleS();                                                       \
00218   chSysUnlock();                                                            \
00219 }
00220 
00221 /**
00222  * @brief   Performs a signal operation on a binary semaphore.
00223  * @note    This function does not reschedule.
00224  *
00225  * @param[in] bsp       pointer to a @p BinarySemaphore structure
00226  *
00227  * @iclass
00228  */
00229 #define chBSemSignalI(bsp) {                                                \
00230   if ((bsp)->bs_sem.s_cnt < 1)                                              \
00231     chSemSignalI(&(bsp)->bs_sem);                                           \
00232 }
00233 
00234 /**
00235  * @brief   Returns the binary semaphore current state.
00236  *
00237  * @param[in] bsp       pointer to a @p BinarySemaphore structure
00238  * @return              The binary semaphore current state.
00239  * @retval FALSE        if the binary semaphore is not taken.
00240  * @retval TRUE         if the binary semaphore is taken.
00241  *
00242  * @iclass
00243  */
00244 #define chBSemGetStateI(bsp) ((bsp)->bs_sem.s_cnt > 0 ? FALSE : TRUE)
00245 /** @} */
00246 
00247 #endif /* CH_USE_SEMAPHORES */
00248 
00249 #endif /* _CHBSEM_H_ */
00250 
00251 /** @} */