From cbc30670d8004caeb7b0a8a9567377ac99032805 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 8 Nov 2008 12:44:36 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@502 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- src/chevents.c | 173 ++++++++++++++++++++++++++++++++++++++----------- src/include/events.h | 37 +++-------- src/templates/chconf.h | 10 ++- 3 files changed, 150 insertions(+), 70 deletions(-) (limited to 'src') diff --git a/src/chevents.c b/src/chevents.c index f75a667e3..8aab8ca5c 100644 --- a/src/chevents.c +++ b/src/chevents.c @@ -147,32 +147,49 @@ void chEvtBroadcastI(EventSource *esp) { } /** - * Waits for a single event. + * Invokes the event handlers associated with a mask. + * @param mask mask of the events that should be invoked by the function, + * \p ALL_EVENTS enables all the sources + * @param handlers an array of \p evhandler_t. The array must be + * have indexes from zero up the higher registered event + * identifier. The array can be \p NULL or contain \p NULL + * elements (no callbacks specified). + */ +void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) { + eventid_t i; + eventmask_t m; + + i = 0, m = 1; + while ((mask & m) == 0) { + i += 1, m <<= 1; + mask &= ~m; + handlers[i](i); + } +} + +#if defined(CH_OPTIMIZE_SPEED) || !defined(CH_USE_EVENT_TIMEOUT) +/** * A pending event among those specified in \p ewmask is selected, cleared and * its mask returned. * @param ewmask mask of the events that the function should wait for, * \p ALL_EVENTS enables all the events - * @param time the number of ticks before the operation timouts * @return The mask of the lowest id served and cleared event. - * @retval 0 if the specified timeout expired * @note Only a single event is served in the function, the one with the * lowest event id. The function is meant to be invoked into a loop in * order to serve all the pending events.
* This means that Event Listeners with a lower event identifier have * an higher priority. */ -eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) { +eventmask_t chEvtWaitOne(eventmask_t ewmask) { eventmask_t m; chSysLock(); if ((m = (currp->p_epending & ewmask)) == 0) { currp->p_ewmask = ewmask; - if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK) - return (eventmask_t)0; + chSchGoSleepS(PRWTOREVT); m = currp->p_epending & ewmask; } -// m ^= m & (m - 1); m &= -m; currp->p_epending &= ~m; @@ -186,19 +203,16 @@ eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) { * become pending then the events are cleared and returned. * @param ewmask mask of the events that the function should wait for, * \p ALL_EVENTS enables all the events - * @param time the number of ticks before the operation timouts * @return The mask of the served and cleared events. - * @retval 0 if the specified timeout expired */ -eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) { +eventmask_t chEvtWaitAny(eventmask_t ewmask) { eventmask_t m; chSysLock(); if ((m = (currp->p_epending & ewmask)) == 0) { currp->p_ewmask = ewmask; - if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK) - return (eventmask_t)0; + chSchGoSleepS(PRWTOREVT); m = currp->p_epending & ewmask; } currp->p_epending &= ~m; @@ -212,18 +226,15 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) { * The function waits for all the events specified in \p ewmask to become * pending then the events are cleared and returned. * @param ewmask mask of the event ids that the function should wait for - * @param time the number of ticks before the operation timouts * @return The mask of the served and cleared events. - * @retval 0 if the specified timeout expired */ -eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time) { +eventmask_t chEvtWaitAll(eventmask_t ewmask) { chSysLock(); if ((currp->p_epending & ewmask) != ewmask) { currp->p_ewmask = ewmask; - if (chSchGoSleepTimeoutS(PRWTANDEVT, time) < RDY_OK) - return (eventmask_t)0; + chSchGoSleepS(PRWTOREVT); } currp->p_epending &= ~ewmask; @@ -231,27 +242,6 @@ eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time) { return ewmask; } -/** - * Invokes the event handlers associated with a mask. - * @param mask mask of the events that should be invoked by the function, - * \p ALL_EVENTS enables all the sources - * @param handlers an array of \p evhandler_t. The array must be - * have indexes from zero up the higher registered event - * identifier. The array can be \p NULL or contain \p NULL - * elements (no callbacks specified). - */ -void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) { - eventid_t i; - eventmask_t m; - - i = 0, m = 1; - while ((mask & m) == 0) { - i += 1, m <<= 1; - mask &= ~m; - handlers[i](i); - } -} - /** * The function waits for an event and returns the event identifier, if an * event handler is specified then the handler is executed before returning. @@ -272,8 +262,112 @@ void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) { */ eventid_t chEvtWait(eventmask_t ewmask, const evhandler_t handlers[]) { + eventid_t i; + eventmask_t m; + + chSysLock(); + + if ((currp->p_epending & ewmask) == 0) { + currp->p_ewmask = ewmask; + chSchGoSleepS(PRWTOREVT); + } + i = 0, m = 1; + while ((currp->p_epending & ewmask & m) == 0) + i += 1, m <<= 1; + currp->p_epending &= ~m; + + chSysUnlock(); + + if (handlers && handlers[i]) + handlers[i](i); + + return i; +} +#endif /* defined(CH_OPTIMIZE_SPEED) || !defined(CH_USE_EVENT_TIMEOUT) */ + +#ifdef CH_USE_EVENT_TIMEOUT +/** + * Waits for a single event. + * A pending event among those specified in \p ewmask is selected, cleared and + * its mask returned. + * @param ewmask mask of the events that the function should wait for, + * \p ALL_EVENTS enables all the events + * @param time the number of ticks before the operation timouts + * @return The mask of the lowest id served and cleared event. + * @retval 0 if the specified timeout expired + * @note Only a single event is served in the function, the one with the + * lowest event id. The function is meant to be invoked into a loop in + * order to serve all the pending events.
+ * This means that Event Listeners with a lower event identifier have + * an higher priority. + */ +eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) { + eventmask_t m; + + chSysLock(); + + if ((m = (currp->p_epending & ewmask)) == 0) { + currp->p_ewmask = ewmask; + if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK) + return (eventmask_t)0; + m = currp->p_epending & ewmask; + } + m &= -m; + currp->p_epending &= ~m; + + chSysUnlock(); + return m; +} + +/** + * Waits for any of the specified events. + * The function waits for any event among those specified in \p ewmask to + * become pending then the events are cleared and returned. + * @param ewmask mask of the events that the function should wait for, + * \p ALL_EVENTS enables all the events + * @param time the number of ticks before the operation timouts + * @return The mask of the served and cleared events. + * @retval 0 if the specified timeout expired + */ +eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) { + eventmask_t m; + + chSysLock(); + + if ((m = (currp->p_epending & ewmask)) == 0) { + currp->p_ewmask = ewmask; + if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK) + return (eventmask_t)0; + m = currp->p_epending & ewmask; + } + currp->p_epending &= ~m; + + chSysUnlock(); + return m; +} + +/** + * Waits for all the specified event flags then clears them. + * The function waits for all the events specified in \p ewmask to become + * pending then the events are cleared and returned. + * @param ewmask mask of the event ids that the function should wait for + * @param time the number of ticks before the operation timouts + * @return The mask of the served and cleared events. + * @retval 0 if the specified timeout expired + */ +eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time) { + + chSysLock(); + + if ((currp->p_epending & ewmask) != ewmask) { + currp->p_ewmask = ewmask; + if (chSchGoSleepTimeoutS(PRWTANDEVT, time) < RDY_OK) + return (eventmask_t)0; + } + currp->p_epending &= ~ewmask; - return chEvtWaitTimeout(ewmask, handlers, TIME_INFINITE); + chSysUnlock(); + return ewmask; } /** @@ -322,6 +416,7 @@ eventid_t chEvtWaitTimeout(eventmask_t ewmask, return i; } +#endif /* CH_USE_EVENT_TIMEOUT */ #endif /* CH_USE_EVENTS */ diff --git a/src/include/events.h b/src/include/events.h index 47d898dad..6474dcf4a 100644 --- a/src/include/events.h +++ b/src/include/events.h @@ -83,6 +83,11 @@ extern "C" { void chEvtUnregister(EventSource *esp, EventListener *elp); eventmask_t chEvtClear(eventmask_t mask); eventmask_t chEvtPend(eventmask_t mask); +#if defined(CH_OPTIMIZE_SPEED) || !defined(CH_USE_EVENT_TIMEOUT) + eventmask_t chEvtWaitOne(eventmask_t ewmask); + eventmask_t chEvtWaitAny(eventmask_t ewmask); + eventmask_t chEvtWaitAll(eventmask_t ewmask); +#endif eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time); eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time); eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time); @@ -97,38 +102,12 @@ extern "C" { } #endif -/** - * A pending event among those specified in \p ewmask is selected, cleared and - * its mask returned. - * @param ewmask mask of the events that the function should wait for, - * \p ALL_EVENTS enables all the events - * @return The mask of the lowest id served and cleared event. - * @note Only a single event is served in the function, the one with the - * lowest event id. The function is meant to be invoked into a loop in - * order to serve all the pending events.
- * This means that Event Listeners with a lower event identifier have - * an higher priority. - */ +#if !defined(CH_OPTIMIZE_SPEED) && defined(CH_USE_EVENT_TIMEOUT) #define chEvtWaitOne(ewmask) chEvtWaitOneTimeout(ewmask, TIME_INFINITE) - -/** - * Waits for any of the specified events. - * The function waits for any event among those specified in \p ewmask to - * become pending then the events are cleared and returned. - * @param ewmask mask of the events that the function should wait for, - * \p ALL_EVENTS enables all the events - * @return The mask of the served and cleared events. - */ #define chEvtWaitAny(ewmask) chEvtWaitAnyTimeout(ewmask, TIME_INFINITE) - -/** - * Waits for all the specified event flags then clears them. - * The function waits for all the events specified in \p ewmask to become - * pending then the events are cleared and returned. - * @param ewmask mask of the event ids that the function should wait for - * @return The mask of the served and cleared events. - */ #define chEvtWaitAll(ewmask) chEvtWaitAllTimeout(ewmask, TIME_INFINITE) +#define chEvtWait(ewmask, handlers) chEvtWaitTimeout(ewmask, handlers, TIME_INFINITE) +#endif /* * Old function names, deprecated, will be removed in some next release. diff --git a/src/templates/chconf.h b/src/templates/chconf.h index 0be7e1d50..9e34e381f 100644 --- a/src/templates/chconf.h +++ b/src/templates/chconf.h @@ -64,6 +64,12 @@ * the kernel.*/ #define CH_USE_EVENTS +/** Configuration option: if specified then the \p chEvtWaitXXXTimeout() + * functions are included in the kernel. + * @note requires \p CH_USE_EVENTS. + */ +#define CH_USE_EVENTS_TIMEOUT + /** Configuration option: if specified then the Synchronous Messages APIs are * included in the kernel.*/ #define CH_USE_MESSAGES @@ -156,8 +162,8 @@ //#define CH_CURRP_REGISTER_CACHE "reg" /** Debug option: Includes basic debug support to the kernel. - * @note the debug support is port-dependent, it may be not present on some - * targets. In that case stub functions will be included. + * @note The debug support is port-dependent, it may be not present on some + * targets. In that case stub functions will be included. */ #define CH_USE_DEBUG -- cgit v1.2.3