git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2036 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2010-06-24 14:19:52 +00:00
parent 28437e3058
commit 62f4b7f471
6 changed files with 246 additions and 6 deletions

218
os/kernel/include/chbsem.h Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
*/
/**
* @file chbsem.h
* @brief Binary semaphores structures and macros.
*
* @addtogroup binary_semaphores
* @details Binary semaphores related APIs and services.
*
* <h2>Operation mode</h2>
* 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:
* - <b>Taken</b>, 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.
* - <b>Not taken</b>, 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.<br>
* 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_ */
/** @} */

View File

@ -72,7 +72,12 @@
*/ */
/** /**
* @defgroup semaphores Semaphores * @defgroup semaphores Counting Semaphores
* @ingroup synchronization
*/
/**
* @defgroup binary_semaphores Binary Semaphores
* @ingroup synchronization * @ingroup synchronization
*/ */

View File

@ -17,8 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
/* /*
Concepts and parts of this file are contributed by and Copyright (C) 2008 Concepts and parts of this file have been contributed by Leon Woestenberg.
of Leon Woestenberg.
*/ */
/** /**

View File

@ -126,6 +126,10 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) {
msg_t msg; msg_t msg;
chSysLock(); chSysLock();
if (iqp->q_notify)
iqp->q_notify();
if ((msg = chSemWaitTimeoutS(&iqp->q_sem, time)) < RDY_OK) { if ((msg = chSemWaitTimeoutS(&iqp->q_sem, time)) < RDY_OK) {
chSysUnlock(); chSysUnlock();
return msg; return msg;
@ -134,9 +138,6 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) {
if (iqp->q_rdptr >= iqp->q_top) if (iqp->q_rdptr >= iqp->q_top)
iqp->q_rdptr = iqp->q_buffer; iqp->q_rdptr = iqp->q_buffer;
if (iqp->q_notify)
iqp->q_notify();
chSysUnlock(); chSysUnlock();
return b; return b;
} }

View File

@ -27,6 +27,7 @@
#include "ch.h" #include "ch.h"
#if !defined(CH_CURRP_REGISTER_CACHE) || defined(__DOXXYGEN__)
/** /**
* @brief Internal context stacking. * @brief Internal context stacking.
*/ */
@ -40,6 +41,15 @@
#define POP_CONTEXT() { \ #define POP_CONTEXT() { \
asm volatile ("pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}"); \ asm volatile ("pop {r4, r5, r6, r7, r8, r9, r10, r11, pc}"); \
} }
#else /* defined(CH_CURRP_REGISTER_CACHE) */
#define PUSH_CONTEXT() { \
asm volatile ("push {r4, r5, r6, r8, r9, r10, r11, lr}"); \
}
#define POP_CONTEXT() { \
asm volatile ("pop {r4, r5, r6, r8, r9, r10, r11, pc}"); \
}
#endif /* defined(CH_CURRP_REGISTER_CACHE) */
#if !CH_OPTIMIZE_SPEED #if !CH_OPTIMIZE_SPEED
void _port_lock(void) { void _port_lock(void) {

View File

@ -59,6 +59,10 @@
***************************************************************************** *****************************************************************************
*** 2.1.0 *** *** 2.1.0 ***
- FIX: Fixed notification order in input queues (bug 3020708)(backported in
2.0.1).
- FIX: Fixed non functional CH_CURRP_REGISTER_CACHE option in the Cortex-M3
port (bug 3020702)(backported in 2.0.1).
- FIX: Fixed non functional CH_DBG_ENABLE_STACK_CHECK option in the Cortex-M3 - FIX: Fixed non functional CH_DBG_ENABLE_STACK_CHECK option in the Cortex-M3
caused by GCC 4.5.0, the fix also improves the context switch performance caused by GCC 4.5.0, the fix also improves the context switch performance
because GCC 4.5.0 apparently was generating useless instructions within the because GCC 4.5.0 apparently was generating useless instructions within the
@ -73,6 +77,9 @@
- FIX: Fixed assertion in adcStop() (bug 3015109)(backported in 2.0.0). - FIX: Fixed assertion in adcStop() (bug 3015109)(backported in 2.0.0).
- NEW: Added timers clock macros to the STM32 clock tree HAL driver (backported - NEW: Added timers clock macros to the STM32 clock tree HAL driver (backported
in 2.0.1). in 2.0.1).
- NEW: Added Binary Semaphores among the synchronization primitives. The new
subsystem is entirely implemented as macros over the existing and proven
Counting Semaphores thus takes no space.
- OPT: Simplified the test suite code, now it is smaller. - OPT: Simplified the test suite code, now it is smaller.
- Reorganized the documentation, now the description of the device drivers - Reorganized the documentation, now the description of the device drivers
implementation is under the HAL module instead of the Ports module. implementation is under the HAL module instead of the Ports module.