From 62f4b7f471a4b1037468d382f927c5061e5fa9ed Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 24 Jun 2010 14:19:52 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2036 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/include/chbsem.h | 218 +++++++++++++++++++++++++++++++++++++++++++++ os/kernel/kernel.dox | 7 +- os/kernel/src/chcond.c | 3 +- os/kernel/src/chqueues.c | 7 +- 4 files changed, 229 insertions(+), 6 deletions(-) create mode 100644 os/kernel/include/chbsem.h (limited to 'os/kernel') diff --git a/os/kernel/include/chbsem.h b/os/kernel/include/chbsem.h new file mode 100644 index 000000000..b8cd08306 --- /dev/null +++ b/os/kernel/include/chbsem.h @@ -0,0 +1,218 @@ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + + This file is part of ChibiOS/RT. + + ChibiOS/RT is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + ChibiOS/RT is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +/** + * @file chbsem.h + * @brief Binary semaphores structures and macros. + * + * @addtogroup binary_semaphores + * @details Binary semaphores related APIs and services. + * + *

Operation mode

+ * Binary semaphores are implemented as a set of macros that use the + * existing counting semaphores primitives. The difference between + * counting and binary semaphores is that the counter of binary + * semaphores is not allowed to grow above the value 1. Repeated + * signal operation are ignored. A binary semaphore can thus have + * only two defined states: + * - Taken, when its counter has a value of zero or lower + * than zero. A negative number represent the number of threads + * queued on the binary semaphore. + * - Not taken, when its counter has a value of one. + * . + * Binary semaphores are different from mutexes because there is no + * the concept of ownership, a binary semaphore can be taken by a + * thread and signaled by another thread or an interrupt handler, + * mutexes can only be taken and released by the same thread. Another + * difference is that binary semaphores, unlike mutexes, do not + * implement the priority inheritance protocol.
+ * In order to use the binary semaphores APIs the @p CH_USE_SEMAPHORES + * option must be enabled in @p chconf.h. + * @{ + */ + +#ifndef _CHBSEM_H_ +#define _CHBSEM_H_ + +#if CH_USE_SEMAPHORES + +/** + * @extends Semaphore + * + * @brief Binary semaphore type. + */ +typedef struct { + Semaphore bs_sem; +} BinarySemaphore; + +/** + * @brief Data part of a static semaphore initializer. + * @details This macro should be used when statically initializing a semaphore + * that is part of a bigger structure. + * + * @param[in] name the name of the semaphore variable + * @param[in] n the counter initial value, this value must be + * non-negative + */ +#define _BSEMAPHORE_DATA(name, t) {_SEMAPHORE_DATA(name.bs_sem), ((t) ? 0 : 1)} + +/** + * @brief Static semaphore initializer. + * @details Statically initialized semaphores require no explicit + * initialization using @p chSemInit(). + * + * @param[in] name the name of the semaphore variable + * @param[in] n the counter initial value, this value must be + * non-negative + */ +#define BSEMAPHORE_DECL(name, t) Semaphore name = _BSEMAPHORE_DATA(name, t) + + +/** + * @brief Initializes a binary semaphore. + * + * @param[out] bsp pointer to a @p BinarySemaphore structure + * @param[in] taken initial state of the binary semaphore: + * - @a FALSE, the initial state is not taken. + * - @a TRUE, the initial state is taken. + * . + */ +#define chBSemInit(bsp, taken) chSemInit(&bsp->bs_sem, taken ? 0 : 1) + +/** + * @brief Wait operation on the binary semaphore. + * + * @param[in] bsp pointer to a @p BinarySemaphore structure + * @retval RDY_OK if the binary semaphore had been successfully taken. + * @retval RDY_RESET if the binary semaphore has been reset using + * @p bsemReset(). + */ +#define chBSemWait(bsp) chSemWait(&bsp->bs_sem) + +/** + * @brief Wait operation on the binary semaphore. + * + * @param[in] bsp pointer to a @p BinarySemaphore structure + * @retval RDY_OK if the binary semaphore had been successfully taken. + * @retval RDY_RESET if the binary semaphore has been reset using + * @p bsemReset(). + */ +#define chBSemWaitS(bsp) chSemWaitS(&bsp->bs_sem) + +/** + * @brief Wait operation on the binary semaphore. + * + * @param[in] bsp pointer to a @p BinarySemaphore structure + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @retval RDY_OK if the binary semaphore had been successfully taken. + * @retval RDY_RESET if the binary semaphore has been reset using + * @p bsemReset(). + * @retval RDY_TIMEOUT if the binary semaphore was not signaled or reset + * within the specified timeout. + */ +#define chBSemWaitTimeout(bsp, time) chSemWaitTimeout(&bsp->bs_sem, time) + +/** + * @brief Wait operation on the binary semaphore. + * + * @param[in] bsp pointer to a @p BinarySemaphore structure + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_IMMEDIATE immediate timeout. + * - @a TIME_INFINITE no timeout. + * . + * @retval RDY_OK if the binary semaphore had been successfully taken. + * @retval RDY_RESET if the binary semaphore has been reset using + * @p bsemReset(). + * @retval RDY_TIMEOUT if the binary semaphore was not signaled or reset + * within the specified timeout. + */ +#define chBSemWaitTimeoutS(bsp, time) chSemWaitTimeoutS(&bsp->bs_sem, time) + +/** + * @brief Reset operation on the binary semaphore. + * @note The released threads can recognize they were waked up by a reset + * rather than a signal because the @p bsemWait() will return + * @p RDY_RESET instead of @p RDY_OK. + * + * @param[in] bsp pointer to a @p BinarySemaphore structure + * @param[in] taken new state of the binary semaphore + * - @a FALSE, the new state is not taken. + * - @a TRUE, the new state is taken. + * . + */ +#define chBSemReset(bsp, taken) chSemReset(&bsp->bs_sem, taken ? 0 : 1) + +/** + * @brief Reset operation on the binary semaphore. + * @note The released threads can recognize they were waked up by a reset + * rather than a signal because the @p bsemWait() will return + * @p RDY_RESET instead of @p RDY_OK. + * @note This function does not reschedule. + * + * @param[in] bsp pointer to a @p BinarySemaphore structure + * @param[in] taken new state of the binary semaphore + * - @a FALSE, the new state is not taken. + * - @a TRUE, the new state is taken. + * . + */ +#define chBSemResetI(bsp, taken) chSemResetI(&bsp->bs_sem, taken ? 0 : 1) + +/** + * @brief Performs a signal operation on a binary semaphore. + * + * @param[in] bsp pointer to a @p BinarySemaphore structure + */ +#define chBSemSignal(bsp) { \ + chSysLock(); \ + chBSemSignalI(bsp); \ + chSchRescheduleS(); \ + chSysUnlock(); \ +} + +/** + * @brief Performs a signal operation on a binary semaphore. + * @note This function does not reschedule. + * + * @param[in] bsp pointer to a @p BinarySemaphore structure + */ +#define chBSemSignalI(bsp) { \ + if (bsp->bs_sem.s_cnt < 1) \ + chSemSignalI(&bsp->bs_sem); \ +} + +/** + * @brief Returns the binary semaphore current state. + * + * @param[in] bsp pointer to a @p BinarySemaphore structure + * @return The binary semaphore current state. + * @retval FALSE if the binary semaphore is not taken. + * @retval TRUE if the binary semaphore is taken. + */ +#define chBSemGetStateI(bsp) ((bsp)->bs_sem.s_cnt > 0 ? 0 : 1) + +#endif /* CH_USE_SEMAPHORES */ + +#endif /* _CHBSEM_H_ */ + +/** @} */ diff --git a/os/kernel/kernel.dox b/os/kernel/kernel.dox index 0cbcd17af..d4206c882 100644 --- a/os/kernel/kernel.dox +++ b/os/kernel/kernel.dox @@ -72,7 +72,12 @@ */ /** - * @defgroup semaphores Semaphores + * @defgroup semaphores Counting Semaphores + * @ingroup synchronization + */ + +/** + * @defgroup binary_semaphores Binary Semaphores * @ingroup synchronization */ diff --git a/os/kernel/src/chcond.c b/os/kernel/src/chcond.c index c450b0c32..92e1a4eb4 100644 --- a/os/kernel/src/chcond.c +++ b/os/kernel/src/chcond.c @@ -17,8 +17,7 @@ along with this program. If not, see . */ /* - Concepts and parts of this file are contributed by and Copyright (C) 2008 - of Leon Woestenberg. + Concepts and parts of this file have been contributed by Leon Woestenberg. */ /** diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 84cbbed94..d1aa03cc6 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -126,6 +126,10 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { msg_t msg; chSysLock(); + + if (iqp->q_notify) + iqp->q_notify(); + if ((msg = chSemWaitTimeoutS(&iqp->q_sem, time)) < RDY_OK) { chSysUnlock(); return msg; @@ -134,9 +138,6 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { if (iqp->q_rdptr >= iqp->q_top) iqp->q_rdptr = iqp->q_buffer; - if (iqp->q_notify) - iqp->q_notify(); - chSysUnlock(); return b; } -- cgit v1.2.3