diff --git a/demos/ARM7-AT91SAM7X-GCC/chconf.h b/demos/ARM7-AT91SAM7X-GCC/chconf.h index 7bf6e138e..45c63947b 100644 --- a/demos/ARM7-AT91SAM7X-GCC/chconf.h +++ b/demos/ARM7-AT91SAM7X-GCC/chconf.h @@ -59,14 +59,6 @@ * the kernel.*/ #define CH_USE_EVENTS -/** Configuration option: if specified then the - * \p chThdGetExitEventSource() function is included in the kernel. - * @note requires \p CH_USE_EVENTS. - * @deprecated \p THREAD_EXT_EXIT should be used, this functionality will be - * removed in version 1.0.0. - */ -#define CH_USE_EVENTS_TIMEOUT - /** Configuration option: if specified then the Synchronous Messages APIs are * included in the kernel.*/ #define CH_USE_MESSAGES @@ -83,8 +75,9 @@ /** Configuration option: if specified then the * \p chThdGetExitEventSource() function is included in the kernel. - * @note requires \p CH_USE_MESSAGES. - * @note requires \p CH_USE_EVENTS.*/ + * @note requires \p CH_USE_EVENTS. + * @deprecated \p THREAD_EXT_EXIT should be used, this functionality will be + * removed in version 1.0.0.*/ #define CH_USE_EXIT_EVENT /** Configuration option: if specified then the I/O queues APIs are included diff --git a/demos/ARM7-AT91SAM7X-WEB-GCC/chconf.h b/demos/ARM7-AT91SAM7X-WEB-GCC/chconf.h index 45202074e..493c66fb0 100644 --- a/demos/ARM7-AT91SAM7X-WEB-GCC/chconf.h +++ b/demos/ARM7-AT91SAM7X-WEB-GCC/chconf.h @@ -59,11 +59,6 @@ * the kernel.*/ #define CH_USE_EVENTS -/** Configuration option: if specified then the \p chEvtWaitTimeout() - * function is 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 diff --git a/demos/ARM7-LPC214x-G++/chconf.h b/demos/ARM7-LPC214x-G++/chconf.h index ea0e068c6..77b8b109d 100644 --- a/demos/ARM7-LPC214x-G++/chconf.h +++ b/demos/ARM7-LPC214x-G++/chconf.h @@ -59,11 +59,6 @@ * the kernel.*/ #define CH_USE_EVENTS -/** Configuration option: if specified then the \p chEvtWaitTimeout() - * function is 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 diff --git a/demos/ARM7-LPC214x-GCC-minimal/chconf.h b/demos/ARM7-LPC214x-GCC-minimal/chconf.h index 543edbea2..fbc6d496e 100644 --- a/demos/ARM7-LPC214x-GCC-minimal/chconf.h +++ b/demos/ARM7-LPC214x-GCC-minimal/chconf.h @@ -59,11 +59,6 @@ * the kernel.*/ //#define CH_USE_EVENTS -/** Configuration option: if specified then the \p chEvtWaitTimeout() - * function is 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 diff --git a/demos/ARM7-LPC214x-GCC/chconf.h b/demos/ARM7-LPC214x-GCC/chconf.h index 45202074e..493c66fb0 100644 --- a/demos/ARM7-LPC214x-GCC/chconf.h +++ b/demos/ARM7-LPC214x-GCC/chconf.h @@ -59,11 +59,6 @@ * the kernel.*/ #define CH_USE_EVENTS -/** Configuration option: if specified then the \p chEvtWaitTimeout() - * function is 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 diff --git a/demos/ARMCM3-STM32F103-GCC/chconf.h b/demos/ARMCM3-STM32F103-GCC/chconf.h index 45202074e..493c66fb0 100644 --- a/demos/ARMCM3-STM32F103-GCC/chconf.h +++ b/demos/ARMCM3-STM32F103-GCC/chconf.h @@ -59,11 +59,6 @@ * the kernel.*/ #define CH_USE_EVENTS -/** Configuration option: if specified then the \p chEvtWaitTimeout() - * function is 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 diff --git a/demos/AVR-AT90CANx-GCC/chconf.h b/demos/AVR-AT90CANx-GCC/chconf.h index 8408f6f22..383f714f3 100644 --- a/demos/AVR-AT90CANx-GCC/chconf.h +++ b/demos/AVR-AT90CANx-GCC/chconf.h @@ -59,11 +59,6 @@ * the kernel.*/ #define CH_USE_EVENTS -/** Configuration option: if specified then the \p chEvtWaitTimeout() - * function is 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 diff --git a/demos/AVR-ATmega128-GCC/chconf.h b/demos/AVR-ATmega128-GCC/chconf.h index a3e829134..87b92479e 100644 --- a/demos/AVR-ATmega128-GCC/chconf.h +++ b/demos/AVR-ATmega128-GCC/chconf.h @@ -59,11 +59,6 @@ * the kernel.*/ #define CH_USE_EVENTS -/** Configuration option: if specified then the \p chEvtWaitTimeout() - * function is 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 diff --git a/demos/MSP430-MSP430x1611-GCC/chconf.h b/demos/MSP430-MSP430x1611-GCC/chconf.h index fb6203d46..c2204e3da 100644 --- a/demos/MSP430-MSP430x1611-GCC/chconf.h +++ b/demos/MSP430-MSP430x1611-GCC/chconf.h @@ -64,11 +64,6 @@ * the kernel.*/ #define CH_USE_EVENTS -/** Configuration option: if specified then the \p chEvtWaitTimeout() - * function is 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 diff --git a/demos/Win32-MinGW/chconf.h b/demos/Win32-MinGW/chconf.h index f33f54930..7c0420af6 100644 --- a/demos/Win32-MinGW/chconf.h +++ b/demos/Win32-MinGW/chconf.h @@ -59,11 +59,6 @@ * the kernel.*/ #define CH_USE_EVENTS -/** Configuration option: if specified then the \p chEvtWaitTimeout() - * function is 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 diff --git a/docs/Doxyfile b/docs/Doxyfile index 2b3ebc8ee..87854bc1b 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -5,7 +5,7 @@ #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = ChibiOS/RT -PROJECT_NUMBER = "0.7.4 beta" +PROJECT_NUMBER = "0.8.0 beta" OUTPUT_DIRECTORY = . CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English diff --git a/docs/index.html b/docs/index.html index 73d9030eb..e4cb1abfd 100644 --- a/docs/index.html +++ b/docs/index.html @@ -12,7 +12,7 @@ Current -Version 0.7.4
+Version 0.8.0
-
Project on SourceForge
Documentation
diff --git a/readme.txt b/readme.txt index a3375fbb5..24e874ed7 100644 --- a/readme.txt +++ b/readme.txt @@ -73,10 +73,23 @@ Win32-MinGW - ChibiOS/RT simulator and demo into a WIN32 process, *** Releases *** ***************************************************************************** -*** 0.7.4 *** +*** 0.8.0 *** +- NEW: Improved events subsystems, now it is also possible to use it just as + "event flags" without have to use event handler callbacks. + Some new APIs were introduced: + * chEvtWaitOne() - Wait for a single event. + * chEvtWaitAny() - Wait with OR condition. + * chEvtWaitAll() - Wait with AND condition. + * chEvtDispatch() - Invokes the event handlers associated to a mask. + * chEvtPend() - Quickly self-pends some events. + All the "wait"-type APIs have a timeout-capable variant. +- CHANGE: The old chEvtWait() and chEvtWaitTimeout() APIs are now deprecated + and will be removed in version 1.0.0. +- CHANGE: Removed the CH_USE_EVENT_TIMEOUT configuration option in order to + make the chconf.h file simpler. - CHANGE: Modified chDbgAssert() to syntax check the condition even when the CH_USE_DEBUG is disabled, it produces no code but allows to check the - option without have to compile twice. + optional code without have to compile twice. - Added a new benchmark to the test suite (timers set/reset performance). - Renamed the macro fifo_init() to queue_init() because it is used to init both FIFO queues and priority queues. diff --git a/src/chevents.c b/src/chevents.c index 25d9d5d39..f75a667e3 100644 --- a/src/chevents.c +++ b/src/chevents.c @@ -76,14 +76,34 @@ void chEvtUnregister(EventSource *esp, EventListener *elp) { /** * Clears the pending events specified in the mask. * @param mask the events to be cleared + * @return The pending events that were cleared. */ -void chEvtClear(eventmask_t mask) { +eventmask_t chEvtClear(eventmask_t mask) { + eventmask_t m; chSysLock(); + m = currp->p_epending & mask; currp->p_epending &= ~mask; chSysUnlock(); + return m; +} + +/** + * Makes an events mask pending in the current thread, this is \b much faster than + * using \p chEvtBreadcast(). + * @param mask the events to be pended + * @return The current pending events mask. + */ +eventmask_t chEvtPend(eventmask_t mask) { + + chSysLock(); + + mask = (currp->p_epending |= mask); + + chSysUnlock(); + return mask; } /** @@ -113,13 +133,125 @@ void chEvtBroadcastI(EventSource *esp) { Thread *tp = elp->el_listener; tp->p_epending |= EventMask(elp->el_id); - if ((tp->p_state == PRWTEVENT) && (tp->p_epending & tp->p_ewmask)) + + /* Test on the AND/OR conditions wait states.*/ + if ((tp->p_state == PRWTOREVT) && + ((tp->p_epending & tp->p_ewmask) != 0)) chSchReadyI(tp)->p_rdymsg = RDY_OK; + else if ((tp->p_state == PRWTANDEVT) && + ((tp->p_epending & tp->p_ewmask) == tp->p_ewmask)) + chSchReadyI(tp)->p_rdymsg = RDY_OK; + elp = elp->el_next; } } -#ifdef CH_USE_EVENTS_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 & (m - 1); + 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; + + chSysUnlock(); + 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. @@ -135,6 +267,8 @@ void chEvtBroadcastI(EventSource *esp) { * that all events are received and served.
* This means that Event Listeners with a lower event identifier have * an higher priority. + * @deprecated Please use \p chEvtWaitOne() and \p chEvtDispatch() instead, + * this function will be removed in version 1.0.0. */ eventid_t chEvtWait(eventmask_t ewmask, const evhandler_t handlers[]) { @@ -160,8 +294,8 @@ eventid_t chEvtWait(eventmask_t ewmask, * that all events are received and served.
* This means that Event Listeners with a lower event identifier have * an higher priority. - * @note The function is available only if the \p CH_USE_EVENTS_TIMEOUT - * option is enabled in \p chconf.h. + * @deprecated Please use \p chEvtWaitOneTimeout() and \p chEvtDispatch() + * instead, this function will be removed in version 1.0.0. */ eventid_t chEvtWaitTimeout(eventmask_t ewmask, const evhandler_t handlers[], @@ -173,7 +307,7 @@ eventid_t chEvtWaitTimeout(eventmask_t ewmask, if ((currp->p_epending & ewmask) == 0) { currp->p_ewmask = ewmask; - if (chSchGoSleepTimeoutS(PRWTEVENT, time) < RDY_OK) + if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK) return RDY_TIMEOUT; } i = 0, m = 1; @@ -189,33 +323,6 @@ eventid_t chEvtWaitTimeout(eventmask_t ewmask, return i; } -#else /* !CH_USE_EVENTS_TIMEOUT */ -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(PRWTEVENT); - } - 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 /* CH_USE_EVENTS_TIMEOUT */ - #endif /* CH_USE_EVENTS */ /** @} */ diff --git a/src/include/events.h b/src/include/events.h index 28134d483..47d898dad 100644 --- a/src/include/events.h +++ b/src/include/events.h @@ -81,20 +81,55 @@ extern "C" { #endif void chEvtRegister(EventSource *esp, EventListener *elp, eventid_t eid); void chEvtUnregister(EventSource *esp, EventListener *elp); - void chEvtClear(eventmask_t mask); + eventmask_t chEvtClear(eventmask_t mask); + eventmask_t chEvtPend(eventmask_t mask); + 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); void chEvtBroadcast(EventSource *esp); void chEvtBroadcastI(EventSource *esp); eventid_t chEvtWait(eventmask_t ewmask, const evhandler_t handlers[]); -#ifdef CH_USE_EVENTS_TIMEOUT eventid_t chEvtWaitTimeout(eventmask_t ewmask, const evhandler_t handlers[], systime_t time); -#endif #ifdef __cplusplus } #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. + */ +#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) + /* * Old function names, deprecated, will be removed in some next release. */ diff --git a/src/include/threads.h b/src/include/threads.h index ba136ee85..a0b0b362b 100644 --- a/src/include/threads.h +++ b/src/include/threads.h @@ -127,17 +127,22 @@ struct Thread { /** Thread state: Waiting on a mutex. */ #define PRWTMTX 4 /** Thread state: Waiting in \p chThdSleep() or \p chThdSleepUntil(). */ -#define PRSLEEP 5 +#define PRWTCOND 5 +/** Thread state: Waiting in \p chCondWait(). */ +#define PRSLEEP 6 /** Thread state: Waiting in \p chThdWait(). */ -#define PRWAIT 6 -/** Thread state: Waiting in \p chEvtWait(). */ -#define PRWTEVENT 7 +#define PRWAIT 7 +/** Thread state: Waiting in \p chEvtWaitOneTimeout() or + \p chEvtWaitAnyTimeout(). */ +#define PRWTOREVT 8 +/** Thread state: Waiting in \p chEvtWaitAllTimeout(). */ +#define PRWTANDEVT 9 /** Thread state: Waiting in \p chMsgSend(). */ -#define PRSNDMSG 8 +#define PRSNDMSG 10 /** Thread state: Waiting in \p chMsgWait(). */ -#define PRWTMSG 9 +#define PRWTMSG 11 /** Thread state: After termination.*/ -#define PREXIT 10 +#define PREXIT 12 /* * Various flags into the thread p_flags field. diff --git a/src/templates/chconf.h b/src/templates/chconf.h index 5a16800bc..0be7e1d50 100644 --- a/src/templates/chconf.h +++ b/src/templates/chconf.h @@ -64,11 +64,6 @@ * the kernel.*/ #define CH_USE_EVENTS -/** Configuration option: if specified then the \p chEvtWaitTimeout() - * function is 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