From 68003a03c299850f0b66adfa4df6c9d6b6ba6ab2 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 23 Jan 2008 14:50:42 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@182 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- demos/ARM7-LPC214x-GCC-minimal/chconf.h | 6 --- demos/ARM7-LPC214x-GCC/chconf.h | 6 --- demos/AVR-AT90CANx-GCC/chconf.h | 6 --- demos/Win32-MSVS/chconf.h | 6 --- demos/Win32-MinGW/chconf.h | 6 --- docs/Doxyfile | 1 - readme.txt | 14 +++++++ src/chevents.c | 16 +------- src/chmsg.c | 51 ------------------------- src/chschd.c | 27 +++++++++++++ src/chsem.c | 15 +------- src/chsleep.c | 31 +-------------- src/include/scheduler.h | 1 + src/include/sleep.h | 18 +++++++-- src/templates/chconf.h | 6 --- test/test.c | 23 ----------- 16 files changed, 60 insertions(+), 173 deletions(-) diff --git a/demos/ARM7-LPC214x-GCC-minimal/chconf.h b/demos/ARM7-LPC214x-GCC-minimal/chconf.h index 7db7c3618..d12a1827e 100644 --- a/demos/ARM7-LPC214x-GCC-minimal/chconf.h +++ b/demos/ARM7-LPC214x-GCC-minimal/chconf.h @@ -95,12 +95,6 @@ * included in the kernel.*/ //#define CH_USE_MESSAGES -/** Configuration option: if specified then the \p chMsgSendTimeout() - * function is included in the kernel. - * @note requires \p CH_USE_MESSAGES. - * @note requires \p CH_USE_VIRTUAL_TIMERS.*/ -//#define CH_USE_MESSAGES_TIMEOUT - /** Configuration option: if specified then the \p chMsgSendWithEvent() * function is included in the kernel. * @note requires \p CH_USE_MESSAGES. diff --git a/demos/ARM7-LPC214x-GCC/chconf.h b/demos/ARM7-LPC214x-GCC/chconf.h index eb1ebf7ea..c8817f85c 100644 --- a/demos/ARM7-LPC214x-GCC/chconf.h +++ b/demos/ARM7-LPC214x-GCC/chconf.h @@ -95,12 +95,6 @@ * included in the kernel.*/ #define CH_USE_MESSAGES -/** Configuration option: if specified then the \p chMsgSendTimeout() - * function is included in the kernel. - * @note requires \p CH_USE_MESSAGES. - * @note requires \p CH_USE_VIRTUAL_TIMERS.*/ -#define CH_USE_MESSAGES_TIMEOUT - /** Configuration option: if specified then the \p chMsgSendWithEvent() * function is included in the kernel. * @note requires \p CH_USE_MESSAGES. diff --git a/demos/AVR-AT90CANx-GCC/chconf.h b/demos/AVR-AT90CANx-GCC/chconf.h index f0f3caf26..162255af5 100644 --- a/demos/AVR-AT90CANx-GCC/chconf.h +++ b/demos/AVR-AT90CANx-GCC/chconf.h @@ -96,12 +96,6 @@ * included in the kernel.*/ #define CH_USE_MESSAGES -/** Configuration option: if specified then the \p chMsgSendTimeout() - * function is included in the kernel. - * @note requires \p CH_USE_MESSAGES. - * @note requires \p CH_USE_VIRTUAL_TIMERS.*/ -#define CH_USE_MESSAGES_TIMEOUT - /** Configuration option: if specified then the \p chMsgSendWithEvent() * function is included in the kernel. * @note requires \p CH_USE_MESSAGES. diff --git a/demos/Win32-MSVS/chconf.h b/demos/Win32-MSVS/chconf.h index b6d8e4c98..075f829d3 100644 --- a/demos/Win32-MSVS/chconf.h +++ b/demos/Win32-MSVS/chconf.h @@ -100,12 +100,6 @@ * included in the kernel.*/ #define CH_USE_MESSAGES -/** Configuration option: if specified then the \p chMsgSendTimeout() - * function is included in the kernel. - * @note requires \p CH_USE_MESSAGES. - * @note requires \p CH_USE_VIRTUAL_TIMERS.*/ -#define CH_USE_MESSAGES_TIMEOUT - /** Configuration option: if specified then the \p chMsgSendWithEvent() * function is included in the kernel. * @note requires \p CH_USE_MESSAGES. diff --git a/demos/Win32-MinGW/chconf.h b/demos/Win32-MinGW/chconf.h index b913a6cc4..15cf3d323 100644 --- a/demos/Win32-MinGW/chconf.h +++ b/demos/Win32-MinGW/chconf.h @@ -100,12 +100,6 @@ * included in the kernel.*/ #define CH_USE_MESSAGES -/** Configuration option: if specified then the \p chMsgSendTimeout() - * function is included in the kernel. - * @note requires \p CH_USE_MESSAGES. - * @note requires \p CH_USE_VIRTUAL_TIMERS.*/ -#define CH_USE_MESSAGES_TIMEOUT - /** Configuration option: if specified then the \p chMsgSendWithEvent() * function is included in the kernel. * @note requires \p CH_USE_MESSAGES. diff --git a/docs/Doxyfile b/docs/Doxyfile index 191480d19..0299bfa06 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -241,7 +241,6 @@ PREDEFINED = __JUST_STUBS__ \ CH_USE_SERIAL_FULLDUPLEX \ CH_USE_SERIAL_HALFDUPLEX \ CH_USE_MESSAGES \ - CH_USE_MESSAGES_TIMEOUT \ CH_USE_MESSAGES_EVENT \ CH_USE_MESSAGES_PRIORITY \ CH_USE_SEMSW \ diff --git a/readme.txt b/readme.txt index 505bcfc7e..499345d66 100644 --- a/readme.txt +++ b/readme.txt @@ -39,6 +39,20 @@ AVR-AT90CANx-GCC - Port on AVR AT90CAN128, not complete yet. *** Releases *** ***************************************************************************** +*** 0.5.3 *** +- Removed the chMsgSendTimeout() API, it was conceptually flawed because + after sending a message, the sender *has* to wait for the answer or + the next sender in queue would receive it instead (the messages server has + no way to know that the sender is gone because a timeout). + A workaround would make the messages subsystem much heavier and this is + not desiderable. +- Removed the test case for chMsgSendTimeout() from the test suite. +- Space saved by reorganizing the timeout code into a single scheduler + function. +- The API chThdSleepUntil() become a macro saving some more code space. +- Because all the above changes the kernel code (ARM) is over 600 bytes + smaller. + *** 0.5.2 *** - Fixed a small problem in the main header file ch.h. - Small reordering in the fields of the Thread structure in order to optimize diff --git a/src/chevents.c b/src/chevents.c index 13a858acd..72ca7c182 100644 --- a/src/chevents.c +++ b/src/chevents.c @@ -142,12 +142,6 @@ t_eventid chEvtWait(t_eventmask ewmask, return chEvtWaitTimeout(ewmask, handlers, TIME_INFINITE); } -static void wakeup(void *p) { - - chDbgAssert(((Thread *)p)->p_state == PRWTEVENT, "chevents.c, wakeup()"); - chSchReadyI(p, RDY_TIMEOUT); -} - /** * The function waits for an event or the specified timeout then returns the * event identifier, if an event handler is specified then the handler is @@ -177,17 +171,9 @@ t_eventid chEvtWaitTimeout(t_eventmask ewmask, chSysLock(); if ((currp->p_epending & ewmask) == 0) { - VirtualTimer vt; - - chVTSetI(&vt, time, wakeup, currp); currp->p_ewmask = ewmask; - chSchGoSleepS(PRWTEVENT); - if (!chVTIsArmedI(&vt)) { - - chSysUnlock(); + if (chSchGoSleepTimeoutS(PRWTEVENT, time) < RDY_OK) return RDY_TIMEOUT; - } - chVTResetI(&vt); } i = 0, m = 1; while ((currp->p_epending & ewmask & m) == 0) diff --git a/src/chmsg.c b/src/chmsg.c index ef8b111dc..91a6cc9fd 100644 --- a/src/chmsg.c +++ b/src/chmsg.c @@ -94,57 +94,6 @@ t_msg chMsgSendWithEvent(Thread *tp, t_msg msg, EventSource *esp) { } #endif -#ifdef CH_USE_MESSAGES_TIMEOUT -static void wakeup(void *p) { - - chDbgAssert(((Thread *)p)->p_state == PRSNDMSG, "chmsg.c, wakeup()"); - chSchReadyI(dequeue(p), RDY_TIMEOUT); -} - -/** - * Sends a message to the specified thread with timeout specification. The - * sender is stopped until the receiver executes a \p chMsgRelease(). - * - * @param tp the pointer to the thread - * @param msg the message. Note that it can be a pointer to a complex - * message structure. - * @param time the number of ticks before the operation fails - * @return the message return status from \p chMsgRelease() or - * \p RDY_TIMEOUT the specified time expired. - * @note The server thread can also return data into the message structure - * if you need messages to be bidirectional, just define the structure - * according your needs. If you dont need complicated messages exchange - * you may just use the \p chMsgRelease() status code as response - * to the message. - */ -t_msg chMsgSendTimeout(Thread *tp, t_msg msg, t_time time) { - VirtualTimer vt; - - chSysLock(); - - chVTSetI(&vt, time, wakeup, currp); -#ifdef CH_USE_MESSAGES_PRIORITY - if (tp->p_flags & P_MSGBYPRIO) - prio_insert(currp, &tp->p_msgqueue); - else - fifo_insert(currp, &tp->p_msgqueue); -#else - fifo_insert(currp, &tp->p_msgqueue); -#endif - currp->p_msg = msg; - currp->p_wtthdp = tp; - if (tp->p_state == PRWTMSG) - chSchReadyI(tp, RDY_OK); - chSchGoSleepS(PRSNDMSG); - msg = currp->p_rdymsg; - if (chVTIsArmedI(&vt)) - chVTResetI(&vt); - - chSysUnlock(); - return msg; -} -#endif /* CH_USE_MESSAGES_TIMEOUT */ - /** * Suspends the thread and waits for an incoming message. * diff --git a/src/chschd.c b/src/chschd.c index cbd1cfdd3..92a0fbb0d 100644 --- a/src/chschd.c +++ b/src/chschd.c @@ -90,6 +90,33 @@ void chSchGoSleepS(t_tstate newstate) { chSysSwitchI(otp, currp); } +static void wakeup(void *p) { + + if (((Thread *)p)->p_state == PRWTSEM) + chSemFastSignalI(((Thread *)p)->p_wtsemp); + chSchReadyI(p, RDY_TIMEOUT); +} + +/** + * Puts the current thread to sleep into the specified state, the next highest + * priority thread becomes running. The thread is automatically awakened after + * the specified time elapsed. + * @param newstate the new thread state + * @param time the number of ticks before the operation timouts + * @return the wakeup message, it is \p RDY_TIMEOUT if a timeout occurs + * @note The function must be called in the system mutex zone. + * @note The function is not meant to be used in the user code directly. + */ +t_msg chSchGoSleepTimeoutS(t_tstate newstate, t_time time) { + VirtualTimer vt; + + chVTSetI(&vt, time, wakeup, currp); + chSchGoSleepS(newstate); + if (chVTIsArmedI(&vt)) + chVTResetI(&vt); + return currp->p_rdymsg; +} + /** * Wakeups a thread, the thread is inserted into the ready list or made * running directly depending on its relative priority compared to the current diff --git a/src/chsem.c b/src/chsem.c index 0ab603b03..ceaa64399 100644 --- a/src/chsem.c +++ b/src/chsem.c @@ -117,13 +117,6 @@ t_msg chSemWaitS(Semaphore *sp) { } #ifdef CH_USE_SEMAPHORES_TIMEOUT -static void wakeup(void *p) { - - chDbgAssert(((Thread *)p)->p_state == PRWTSEM, "chsem.c, wakeup()"); - chSemFastSignalI(((Thread *)p)->p_wtsemp); - chSchReadyI(dequeue(p), RDY_TIMEOUT); -} - /** * Performs a wait operation on a semaphore with timeout specification. * @param sp pointer to a \p Semaphore structure @@ -154,15 +147,9 @@ t_msg chSemWaitTimeout(Semaphore *sp, t_time time) { t_msg chSemWaitTimeoutS(Semaphore *sp, t_time time) { if (--sp->s_cnt < 0) { - VirtualTimer vt; - - chVTSetI(&vt, time, wakeup, currp); fifo_insert(currp, &sp->s_queue); currp->p_wtsemp = sp; - chSchGoSleepS(PRWTSEM); - if (chVTIsArmedI(&vt)) - chVTResetI(&vt); - return currp->p_rdymsg; + return chSchGoSleepTimeoutS(PRWTSEM, time); } return RDY_OK; } diff --git a/src/chsleep.c b/src/chsleep.c index b6c31e1a4..9dad520c7 100644 --- a/src/chsleep.c +++ b/src/chsleep.c @@ -25,47 +25,18 @@ #include #ifdef CH_USE_SLEEP -static void wakeup(void *p) { - - chDbgAssert(((Thread *)p)->p_state == PRSLEEP, "chsleep.c, wakeup()"); - chSchReadyI(p, RDY_OK); -} - /** * Suspends the invoking thread for the specified time. * @param time the system ticks number */ void chThdSleep(t_time time) { - VirtualTimer vt; chSysLock(); - chVTSetI(&vt, time, wakeup, currp); - chSchGoSleepS(PRSLEEP); + chSchGoSleepTimeoutS(PRSLEEP, time); chSysUnlock(); } - -#ifdef CH_USE_SYSTEMTIME -/** - * Suspends the invoking thread until the system time arrives to the specified - * value. - * @param time the system time - * @note The function is available only if the \p CH_USE_SYSTEMTIME - * option is enabled in \p chconf.h. - */ -void chThdSleepUntil(t_time time) { - VirtualTimer vt; - - chSysLock(); - - chVTSetI(&vt, (t_time)(time - rlist.r_stime), wakeup, currp); - chSchGoSleepS(PRSLEEP); - - chSysUnlock(); -} -#endif /* CH_USE_SYSTEMTIME */ - #endif /* CH_USE_SLEEP */ /** @} */ diff --git a/src/include/scheduler.h b/src/include/scheduler.h index 67fae50a4..6f4d54e56 100644 --- a/src/include/scheduler.h +++ b/src/include/scheduler.h @@ -60,6 +60,7 @@ extern "C" { void chSchInit(void); void chSchReadyI(Thread *tp, t_msg msg); void chSchGoSleepS(t_tstate newstate); + t_msg chSchGoSleepTimeoutS(t_tstate newstate, t_time time); void chSchWakeupS(Thread *tp, t_msg msg); void chSchDoRescheduleI(void); void chSchRescheduleS(void); diff --git a/src/include/sleep.h b/src/include/sleep.h index 161842a29..022b7be23 100644 --- a/src/include/sleep.h +++ b/src/include/sleep.h @@ -30,14 +30,12 @@ extern "C" { #endif #ifdef CH_USE_SLEEP void chThdSleep(t_time time); -#ifdef CH_USE_SYSTEMTIME - void chThdSleepUntil(t_time time); -#endif /* CH_USE_SYSTEMTIME */ #endif /* CH_USE_SLEEP */ #ifdef __cplusplus } #endif +#ifdef CH_USE_SYSTEMTIME /** * Returns the number of system ticks since the \p chSysInit() invocation. * @return the system ticks number @@ -48,6 +46,20 @@ extern "C" { */ #define chSysGetTime() rlist.r_stime +/** + * Suspends the invoking thread until the system time arrives to the specified + * value. + * @note The function is available only if the \p CH_USE_SYSTEMTIME + * option is enabled in \p chconf.h. + */ +#define chThdSleepUntil(t) { \ + chSysLock(); \ + chSchGoSleepTimeoutS(PRSLEEP, \ + (t_time)((t) - chSysGetTime())) \ + chSysUnlock(); \ +} +#endif /* CH_USE_SYSTEMTIME */ + #endif /* _SLEEP_H_ */ /** @} */ diff --git a/src/templates/chconf.h b/src/templates/chconf.h index d8e5f88da..cc4f992f2 100644 --- a/src/templates/chconf.h +++ b/src/templates/chconf.h @@ -96,12 +96,6 @@ * included in the kernel.*/ #define CH_USE_MESSAGES -/** Configuration option: if specified then the \p chMsgSendTimeout() - * function is included in the kernel. - * @note requires \p CH_USE_MESSAGES. - * @note requires \p CH_USE_VIRTUAL_TIMERS.*/ -#define CH_USE_MESSAGES_TIMEOUT - /** Configuration option: if specified then the \p chMsgSendWithEvent() * function is included in the kernel. * @note requires \p CH_USE_MESSAGES. diff --git a/test/test.c b/test/test.c index 30aa43a2d..7d8d3b792 100644 --- a/test/test.c +++ b/test/test.c @@ -134,14 +134,6 @@ t_msg Thread4(void *p) { return 0; } -t_msg Thread5(void *p) { - - // NOTE, this thread does not serve messages this causes the client to - // timeout. - chThdSleep(3000); - return 0; -} - t_msg Thread6(void *p) { while (!chThdShouldTerminate()) @@ -386,20 +378,6 @@ void testmsg1(void) { println(""); } -void testmsg2(void) { - unsigned int i; - - println("*** Messages, timeout test, you should read ABCDE (slowly):"); - t1 = chThdCreate(chThdGetPriority()-1, 0, wsT1, sizeof(wsT1), Thread5, chThdSelf()); - for (i = 0; i < 5; i++) { - chFDDPut(comp, 'A' + i); - chMsgSendTimeout(t1, 'A' + i, 500); - } - chMsgSendTimeout(t1, 0, 500); - chThdWait(t1); - println(""); -} - __attribute__((noinline)) unsigned int msg_loop_test(Thread *tp) { unsigned int i; @@ -565,7 +543,6 @@ t_msg TestThread(void *p) { * Messages tests. */ testmsg1(); - testmsg2(); /* * Kernel benchmarks.