From d9ff829a71d7b5723206e4923bcab6cbe3f5b715 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 7 Mar 2009 15:32:40 +0000 Subject: Fixes to the zero timeout. Added a test case. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@813 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- src/chcond.c | 42 +++++++++--------- src/chevents.c | 110 ++++++++++++++++++++++++++---------------------- src/chmboxes.c | 60 ++++++++++++++++++-------- src/chschd.c | 29 ++++++------- src/chsem.c | 38 ++++++++++------- src/chvt.c | 4 +- src/include/scheduler.h | 14 ++++-- test/testsem.c | 11 +++-- 8 files changed, 178 insertions(+), 130 deletions(-) diff --git a/src/chcond.c b/src/chcond.c index b531cffa4..fea5bebee 100644 --- a/src/chcond.c +++ b/src/chcond.c @@ -35,7 +35,7 @@ /** * @brief Initializes s @p CondVar structure. * - * @param cp pointer to a @p CondVar structure + * @param[out] cp pointer to a @p CondVar structure * @note This function can be invoked from within an interrupt handler even if * it is not an I-Class API because it does not touch any critical kernel * data structure. @@ -50,7 +50,7 @@ void chCondInit(CondVar *cp) { /** * @brief Signals one thread that is waiting on the condition variable. * - * @param cp pointer to the @p CondVar structure + * @param[in] cp pointer to the @p CondVar structure */ void chCondSignal(CondVar *cp) { @@ -65,7 +65,7 @@ void chCondSignal(CondVar *cp) { /** * @brief Signals one thread that is waiting on the condition variable. * - * @param cp pointer to the @p CondVar structure + * @param[in] cp pointer to the @p CondVar structure */ void chCondSignalI(CondVar *cp) { @@ -78,7 +78,7 @@ void chCondSignalI(CondVar *cp) { /** * @brief Signals all threads that are waiting on the condition variable. * - * @param cp pointer to the @p CondVar structure + * @param[in] cp pointer to the @p CondVar structure */ void chCondBroadcast(CondVar *cp) { @@ -91,7 +91,7 @@ void chCondBroadcast(CondVar *cp) { /** * @brief Signals all threads that are waiting on the condition variable. * - * @param cp pointer to the @p CondVar structure + * @param[in] cp pointer to the @p CondVar structure */ void chCondBroadcastI(CondVar *cp) { @@ -107,9 +107,9 @@ void chCondBroadcastI(CondVar *cp) { /** * @brief Waits on the condition variable releasing the mutex lock. * @details Releases the mutex, waits on the condition variable, and finally - * acquires the mutex again. This is done atomically. + * acquires the mutex again. This is done atomically. * - * @param cp pointer to the @p CondVar structure + * @param[in] cp pointer to the @p CondVar structure * @return The wakep mode. * @retval RDY_OK if the condvar was signaled using chCondSignal(). * @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). @@ -128,9 +128,9 @@ msg_t chCondWait(CondVar *cp) { /** * @brief Waits on the condition variable releasing the mutex lock. * @details Releases the mutex, waits on the condition variable, and finally - * acquires the mutex again. This is done atomically. + * acquires the mutex again. This is done atomically. * - * @param cp pointer to the @p CondVar structure + * @param[in] cp pointer to the @p CondVar structure * @return The wakep mode. * @retval RDY_OK if the condvar was signaled using chCondSignal(). * @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). @@ -159,13 +159,13 @@ msg_t chCondWaitS(CondVar *cp) { /** * @brief Waits on the condition variable releasing the mutex lock. * @details Releases the mutex, waits on the condition variable, and finally - * acquires the mutex again. This is done atomically. + * acquires the mutex again. This is done atomically. * - * @param cp pointer to the @p CondVar structure - * @param time the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_ZERO immediate timeout. - * - @a TIME_INFINITE no timeout. + * @param[in] cp pointer to the @p CondVar structure + * @param[in] time the number of ticks before the operation timeouts, + * the special value @p TIME_INFINITE is allowed. + * It is not possible to specify zero (@p TIME_ZERO) as timeout + * specification. * @return The wakep mode. * @retval RDY_OK if the condvar was signaled using chCondSignal(). * @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). @@ -186,13 +186,13 @@ msg_t chCondWaitTimeout(CondVar *cp, systime_t time) { /** * @brief Waits on the condition variable releasing the mutex lock. * @details Releases the mutex, waits on the condition variable, and finally - * acquires the mutex again. This is done atomically. + * acquires the mutex again. This is done atomically. * - * @param cp pointer to the @p CondVar structure - * @param time the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_ZERO immediate timeout. - * - @a TIME_INFINITE no timeout. + * @param[in] cp pointer to the @p CondVar structure + * @param[in] time the number of ticks before the operation timeouts, + * the special value @p TIME_INFINITE is allowed. + * It is not possible to specify zero (@p TIME_ZERO) as timeout + * specification. * @return The wakep mode. * @retval RDY_OK if the condvar was signaled using chCondSignal(). * @retval RDY_RESET if the condvar was signaled using chCondBroadcast(). diff --git a/src/chevents.c b/src/chevents.c index 83c487dcd..5633b7de3 100644 --- a/src/chevents.c +++ b/src/chevents.c @@ -29,10 +29,10 @@ /** * @brief Registers an Event Listener on an Event Source. * - * @param esp pointer to the @p EventSource structure - * @param elp pointer to the @p EventListener structure - * @param emask the mask of event flags to be pended to the thread when the - * event source is broadcasted + * @param[in] esp pointer to the @p EventSource structure + * @param[in] elp pointer to the @p EventListener structure + * @param[in] emask the mask of event flags to be pended to the thread when the + * event source is broadcasted * @note Multiple Event Listeners can specify the same bits to be pended. */ void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask) { @@ -50,8 +50,8 @@ void chEvtRegisterMask(EventSource *esp, EventListener *elp, eventmask_t emask) /** * @brief Unregisters an Event Listener from its Event Source. * - * @param esp pointer to the @p EventSource structure - * @param elp pointer to the @p EventListener structure + * @param[in] esp pointer to the @p EventSource structure + * @param[in] elp pointer to the @p EventListener structure * @note If the event listener is not registered on the specified event source * then the function does nothing. * @note For optimal performance it is better to perform the unregister @@ -78,7 +78,7 @@ void chEvtUnregister(EventSource *esp, EventListener *elp) { /** * @brief Clears the pending events specified in the mask. * - * @param mask the events to be cleared + * @param[in] mask the events to be cleared * @return The pending events that were cleared. */ eventmask_t chEvtClear(eventmask_t mask) { @@ -94,10 +94,10 @@ eventmask_t chEvtClear(eventmask_t mask) { } /** - * @brief Pends a set of event flags on the current thread, this is \b much - * faster than using @p chEvtBroadcast() or @p chEvtSignal(). + * @brief Pends a set of event flags on the current thread, this is @b much + * faster than using @p chEvtBroadcast() or @p chEvtSignal(). * - * @param mask the events to be pended + * @param[in] mask the events to be pended * @return The current pending events mask. */ eventmask_t chEvtPend(eventmask_t mask) { @@ -113,8 +113,8 @@ eventmask_t chEvtPend(eventmask_t mask) { /** * @brief Pends a set of event flags on the specified @p Thread. * - * @param tp the thread to be signaled - * @param mask the event flags set to be pended + * @param[in] tp the thread to be signaled + * @param[in] mask the event flags set to be pended */ void chEvtSignal(Thread *tp, eventmask_t mask) { @@ -128,8 +128,8 @@ void chEvtSignal(Thread *tp, eventmask_t mask) { /** * @brief Pends a set of event flags on the specified @p Thread. * - * @param tp the thread to be signaled - * @param mask the event flags set to be pended + * @param[in] tp the thread to be signaled + * @param[in] mask the event flags set to be pended */ void chEvtSignalI(Thread *tp, eventmask_t mask) { @@ -144,9 +144,9 @@ void chEvtSignalI(Thread *tp, eventmask_t mask) { /** * @brief Signals all the Event Listeners registered on the specified Event - * Source. + * Source. * - * @param esp pointer to the @p EventSource structure + * @param[in] esp pointer to the @p EventSource structure */ void chEvtBroadcast(EventSource *esp) { @@ -158,9 +158,9 @@ void chEvtBroadcast(EventSource *esp) { /** * @brief Signals all the Event Listeners registered on the specified Event - * Source. + * Source. * - * @param esp pointer to the @p EventSource structure + * @param[in] esp pointer to the @p EventSource structure */ void chEvtBroadcastI(EventSource *esp) { EventListener *elp; @@ -177,10 +177,10 @@ void chEvtBroadcastI(EventSource *esp) { /** * @brief Invokes the event handlers associated with a mask. * - * @param mask mask of the events to be dispatched - * @param handlers an array of @p evhandler_t. The array must be - * have indexes from zero up the higher registered event - * identifier. + * @param[in] mask mask of the events to be dispatched + * @param[in] handlers an array of @p evhandler_t. The array must be + * have indexes from zero up the higher registered event + * identifier. */ void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) { eventid_t eid; @@ -204,10 +204,10 @@ void chEvtDispatch(const evhandler_t handlers[], eventmask_t mask) { /** * @brief Waits for exactly one of the specified events. * @details The function waits for one event among those specified in - * @p ewmask to become pending then the event is cleared and returned. + * @p ewmask to become pending then the event is cleared and returned. * - * @param ewmask mask of the events that the function should wait for, - * @p ALL_EVENTS enables all the events + * @param[in] 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 One and only one event is served in the function, the one with the * lowest event id. The function is meant to be invoked into a loop in @@ -235,10 +235,10 @@ eventmask_t chEvtWaitOne(eventmask_t ewmask) { /** * @brief Waits for any of the specified events. * @details The function waits for any event among those specified in - * @p ewmask to become pending then the events are cleared and returned. + * @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[in] 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. */ eventmask_t chEvtWaitAny(eventmask_t ewmask) { @@ -260,9 +260,9 @@ eventmask_t chEvtWaitAny(eventmask_t ewmask) { /** * @brief Waits for all the specified events. * @details The function waits for all the events specified in @p ewmask to - * become pending then the events are cleared and returned. + * become pending then the events are cleared and returned. * - * @param ewmask mask of the event ids that the function should wait for + * @param[in] ewmask mask of the event ids that the function should wait for * @return The mask of the served and cleared events. */ eventmask_t chEvtWaitAll(eventmask_t ewmask) { @@ -284,14 +284,15 @@ eventmask_t chEvtWaitAll(eventmask_t ewmask) { /** * @brief Waits for exactly one of the specified events. * @details The function waits for one event among those specified in - * @p ewmask to become pending then the event is cleared and returned. + * @p ewmask to become pending then the event is 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 timeouts, - * the following special values are allowed: - * - @a TIME_ZERO immediate timeout. - * - @a TIME_INFINITE no timeout. + * @param[in] ewmask mask of the events that the function should wait for, + * @p ALL_EVENTS enables all the events + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_ZERO immediate timeout. + * - @a TIME_INFINITE no timeout. + * . * @return The mask of the lowest id served and cleared event. * @retval 0 if the specified timeout expired. * @note One and only one event is served in the function, the one with the @@ -306,6 +307,8 @@ eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) { chSysLock(); if ((m = (currp->p_epending & ewmask)) == 0) { + if (TIME_ZERO == time) + return (eventmask_t)0; currp->p_ewmask = ewmask; if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK) return (eventmask_t)0; @@ -321,14 +324,16 @@ eventmask_t chEvtWaitOneTimeout(eventmask_t ewmask, systime_t time) { /** * @brief Waits for any of the specified events. * @details The function waits for any event among those specified in - * @p ewmask to become pending then the events are cleared and returned. + * @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 timeouts, - * the following special values are allowed: - * - @a TIME_ZERO immediate timeout. - * - @a TIME_INFINITE no timeout. + * @param[in] ewmask mask of the events that the function should wait for, + * @p ALL_EVENTS enables all the events + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_ZERO immediate timeout. + * - @a TIME_INFINITE no timeout. + * . * @return The mask of the served and cleared events. * @retval 0 if the specified timeout expired. */ @@ -338,6 +343,8 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) { chSysLock(); if ((m = (currp->p_epending & ewmask)) == 0) { + if (TIME_ZERO == time) + return (eventmask_t)0; currp->p_ewmask = ewmask; if (chSchGoSleepTimeoutS(PRWTOREVT, time) < RDY_OK) return (eventmask_t)0; @@ -352,13 +359,14 @@ eventmask_t chEvtWaitAnyTimeout(eventmask_t ewmask, systime_t time) { /** * @brief Waits for all the specified events. * @details The function waits for all the events specified in @p ewmask to - * become pending then the events are cleared and returned. + * 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 timeouts - * the following special values are allowed: - * - @a TIME_ZERO immediate timeout. - * - @a TIME_INFINITE no timeout. + * @param[in] ewmask mask of the event ids that the function should wait for + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_ZERO immediate timeout. + * - @a TIME_INFINITE no timeout. + * . * @return The mask of the served and cleared events. * @retval 0 if the specified timeout expired. */ @@ -367,6 +375,8 @@ eventmask_t chEvtWaitAllTimeout(eventmask_t ewmask, systime_t time) { chSysLock(); if ((currp->p_epending & ewmask) != ewmask) { + if (TIME_ZERO == time) + return (eventmask_t)0; currp->p_ewmask = ewmask; if (chSchGoSleepTimeoutS(PRWTANDEVT, time) < RDY_OK) return (eventmask_t)0; diff --git a/src/chmboxes.c b/src/chmboxes.c index b682e2ab7..25c4001ef 100644 --- a/src/chmboxes.c +++ b/src/chmboxes.c @@ -70,17 +70,21 @@ void chMBReset(Mailbox *mbp) { * * @param[in] mbp the pointer to an initialized Mailbox object * @param[in] msg the message to be posted on the mailbox - * @param[in] timeout the number of ticks before the operation fails + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_ZERO immediate timeout. + * - @a TIME_INFINITE no timeout. + * . * @return The operation status. * @retval RDY_OK if the message was correctly posted. * @retval RDY_RESET if the mailbox was reset while waiting. * @retval RDY_TIMEOUT if the operation timed out. */ -msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t timeout) { +msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; chSysLock(); - rdymsg = chMBPostS(mbp, msg, timeout); + rdymsg = chMBPostS(mbp, msg, time); chSysUnlock(); return rdymsg; } @@ -92,18 +96,22 @@ msg_t chMBPost(Mailbox *mbp, msg_t msg, systime_t timeout) { * * @param[in] mbp the pointer to an initialized Mailbox object * @param[in] msg the message to be posted on the mailbox - * @param[in] timeout the number of ticks before the operation fails + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_ZERO immediate timeout. + * - @a TIME_INFINITE no timeout. + * . * @return The operation status. * @retval RDY_OK if the message was correctly posted. * @retval RDY_RESET if the mailbox was reset while waiting. * @retval RDY_TIMEOUT if the operation timed out. */ -msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t timeout) { +msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; chDbgCheck(mbp != NULL, "chMBPostS"); - rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, timeout); + rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, time); if (rdymsg == RDY_OK) { *mbp->mb_wrptr++ = msg; if (mbp->mb_wrptr >= mbp->mb_top) @@ -121,17 +129,21 @@ msg_t chMBPostS(Mailbox *mbp, msg_t msg, systime_t timeout) { * * @param[in] mbp the pointer to an initialized Mailbox object * @param[in] msg the message to be posted on the mailbox - * @param[in] timeout the number of ticks before the operation timeouts + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_ZERO immediate timeout. + * - @a TIME_INFINITE no timeout. + * . * @return The operation status. * @retval RDY_OK if the message was correctly posted. * @retval RDY_RESET if the mailbox was reset while waiting. * @retval RDY_TIMEOUT if the operation timed out. */ -msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t timeout) { +msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; chSysLock(); - rdymsg = chMBPostAheadS(mbp, msg, timeout); + rdymsg = chMBPostAheadS(mbp, msg, time); chSysUnlock(); return rdymsg; } @@ -143,18 +155,22 @@ msg_t chMBPostAhead(Mailbox *mbp, msg_t msg, systime_t timeout) { * * @param[in] mbp the pointer to an initialized Mailbox object * @param[in] msg the message to be posted on the mailbox - * @param[in] timeout the number of ticks before the operation timeouts + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_ZERO immediate timeout. + * - @a TIME_INFINITE no timeout. + * . * @return The operation status. * @retval RDY_OK if the message was correctly posted. * @retval RDY_RESET if the mailbox was reset while waiting. * @retval RDY_TIMEOUT if the operation timed out. */ -msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t timeout) { +msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t time) { msg_t rdymsg; chDbgCheck(mbp != NULL, "chMBPostAheadS"); - rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, timeout); + rdymsg = chSemWaitTimeoutS(&mbp->mb_emptysem, time); if (rdymsg == RDY_OK) { if (--mbp->mb_rdptr < mbp->mb_buffer) mbp->mb_rdptr = mbp->mb_top - 1; @@ -172,17 +188,21 @@ msg_t chMBPostAheadS(Mailbox *mbp, msg_t msg, systime_t timeout) { * * @param[in] mbp the pointer to an initialized Mailbox object * @param[out] msgp pointer to a message variable for the received message - * @param[in] timeout the number of ticks before the operation timeouts + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_ZERO immediate timeout. + * - @a TIME_INFINITE no timeout. + * . * @return The operation status. * @retval RDY_OK if a message was correctly fetched. * @retval RDY_RESET if the mailbox was reset while waiting. * @retval RDY_TIMEOUT if the operation timed out. */ -msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t timeout) { +msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t time) { msg_t rdymsg; chSysLock(); - rdymsg = chMBFetchS(mbp, msgp, timeout); + rdymsg = chMBFetchS(mbp, msgp, time); chSysUnlock(); return rdymsg; } @@ -194,18 +214,22 @@ msg_t chMBFetch(Mailbox *mbp, msg_t *msgp, systime_t timeout) { * * @param[in] mbp the pointer to an initialized Mailbox object * @param[out] msgp pointer to a message variable for the received message - * @param[in] timeout the number of ticks before the operation timeouts + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_ZERO immediate timeout. + * - @a TIME_INFINITE no timeout. + * . * @return The operation status. * @retval RDY_OK if a message was correctly fetched. * @retval RDY_RESET if the mailbox was reset while waiting. * @retval RDY_TIMEOUT if the operation timed out. */ -msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t timeout) { +msg_t chMBFetchS(Mailbox *mbp, msg_t *msgp, systime_t time) { msg_t rdymsg; chDbgCheck((mbp != NULL) && (msgp != NULL), "chMBFetchS"); - rdymsg = chSemWaitTimeoutS(&mbp->mb_fullsem, timeout); + rdymsg = chSemWaitTimeoutS(&mbp->mb_fullsem, time); if (rdymsg == RDY_OK) { *msgp = *mbp->mb_rdptr++; if (mbp->mb_rdptr >= mbp->mb_top) diff --git a/src/chschd.c b/src/chschd.c index 6742bf5f8..944841dbe 100644 --- a/src/chschd.c +++ b/src/chschd.c @@ -46,7 +46,7 @@ void scheduler_init(void) { /** * @brief Inserts a thread in the Ready List. * - * @param tp the Thread to be made ready + * @param[in] tp the Thread to be made ready * @return The Thread pointer. * @note The function must be called in the system mutex zone. * @note The function does not reschedule, the @p chSchRescheduleS() should @@ -74,7 +74,7 @@ Thread *chSchReadyI(Thread *tp) { /** * @brief Puts the current thread to sleep into the specified state. * @details The next highest priority thread becomes running. The threads - * states are described into @p threads.h. + * states are described into @p threads.h. * * @param newstate the new thread state * @note The function must be called in the system mutex zone. @@ -119,13 +119,13 @@ static void wakeup(void *p) { /** * @brief Puts the current thread to sleep into the specified state. * @details The next highest priority thread becomes running. The thread put - * to sleep is awakened after the specified time has elapsed. + * to sleep is awakened after the specified time has elapsed. * - * @param newstate the new thread state - * @param time the number of ticks before the operation timeouts, - * the following special values are allowed: - * - @a TIME_ZERO immediate timeout. - * - @a TIME_INFINITE no timeout. + * @param[in] newstate the new thread state + * @param[in] time the number of ticks before the operation timeouts, + * the special value @p TIME_INFINITE is allowed. + * It is not possible to specify zero (@p TIME_ZERO) as timeout + * specification. * @return The wakeup message. * @retval RDY_TIMEOUT if a timeout occurs. * @note The function must be called in the system mutex zone. @@ -133,10 +133,6 @@ static void wakeup(void *p) { */ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { - if (TIME_ZERO == time) { - chSchRescheduleS(); - return RDY_OK; - } if (TIME_INFINITE != time) { VirtualTimer vt; @@ -153,10 +149,11 @@ msg_t chSchGoSleepTimeoutS(tstate_t newstate, systime_t time) { /** * @brief Wakes up a thread. * @details The thread is inserted into the ready list or immediately made - * running depending on its relative priority compared to the current thread. + * running depending on its relative priority compared to the current + * thread. * - * @param ntp the Thread to be made ready - * @param msg message to the awakened thread + * @param[in] ntp the Thread to be made ready + * @param[in] msg message to the awakened thread * @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. * @note It is equivalent to a @p chSchReadyI() followed by a @@ -209,7 +206,7 @@ void chSchDoRescheduleI(void) { /** * @brief Performs a reschedulation if a higher priority thread is runnable. * @details If a thread with a higher priority than the current thread is in - * the ready list then make the higher priority thread running. + * the ready list then make the higher priority thread running. * * @note The function must be called in the system mutex zone. */ diff --git a/src/chsem.c b/src/chsem.c index b682db108..b5717e69c 100644 --- a/src/chsem.c +++ b/src/chsem.c @@ -37,8 +37,8 @@ /** * @brief Initializes a semaphore with the specified counter value. * - * @param sp pointer to a @p Semaphore structure - * @param n initial value of the semaphore counter. Must be non-negative. + * @param[out] sp pointer to a @p Semaphore structure + * @param[in] n initial value of the semaphore counter. Must be non-negative. * @note This function can be invoked from within an interrupt handler even if * it is not an I-Class API because it does not touch any critical kernel * data structure. @@ -54,8 +54,8 @@ void chSemInit(Semaphore *sp, cnt_t n) { /** * @brief Performs a reset operation on the semaphore. * - * @param sp pointer to a @p Semaphore structure - * @param n the new value of the semaphore counter. The value must be non-negative. + * @param[in] sp pointer to a @p Semaphore structure + * @param[in] n the new value of the semaphore counter. The value must be non-negative. * @note The released threads can recognize they were waked up by a reset * instead than a signal because the @p chSemWait() will return * @p RDY_RESET instead of @p RDY_OK. @@ -71,8 +71,8 @@ void chSemReset(Semaphore *sp, cnt_t n) { /** * @brief Performs a reset operation on the semaphore. * - * @param sp pointer to a @p Semaphore structure - * @param n the new value of the semaphore counter. The value must be non-negative. + * @param[in] sp pointer to a @p Semaphore structure + * @param[in] n the new value of the semaphore counter. The value must be non-negative. * @note The released threads can recognize they were waked up by a reset * instead than a signal because the @p chSemWait() will return * @p RDY_RESET instead of @p RDY_OK. @@ -92,7 +92,7 @@ void chSemResetI(Semaphore *sp, cnt_t n) { /** * @brief Performs a wait operation on a semaphore. * - * @param sp pointer to a @p Semaphore structure + * @param[in] sp pointer to a @p Semaphore structure * @retval RDY_OK if the semaphore was signaled or not taken. * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). */ @@ -108,7 +108,7 @@ msg_t chSemWait(Semaphore *sp) { /** * @brief Performs a wait operation on a semaphore. * - * @param sp pointer to a @p Semaphore structure + * @param[in] sp pointer to a @p Semaphore structure * @retval RDY_OK if the semaphore was signaled or not taken. * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). * @note This function must be called with interrupts disabled. @@ -131,8 +131,8 @@ msg_t chSemWaitS(Semaphore *sp) { /** * @brief Performs a wait operation on a semaphore with timeout specification. * - * @param sp pointer to a @p Semaphore structure - * @param time the number of ticks before the operation timeouts, + * @param[in] sp pointer to a @p Semaphore structure + * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_ZERO immediate timeout. * - @a TIME_INFINITE no timeout. @@ -155,8 +155,12 @@ msg_t chSemWaitTimeout(Semaphore *sp, systime_t time) { /** * @brief Performs a wait operation on a semaphore with timeout specification. * - * @param sp pointer to a @p Semaphore structure - * @param time the number of ticks before the operation fails + * @param[in] sp pointer to a @p Semaphore structure + * @param[in] time the number of ticks before the operation timeouts, + * the following special values are allowed: + * - @a TIME_ZERO immediate timeout. + * - @a TIME_INFINITE no timeout. + * . * @retval RDY_OK if the semaphore was signaled or not taken. * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). * @retval RDY_TIMEOUT if the semaphore was not signaled or reset within the specified @@ -169,6 +173,8 @@ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { chDbgCheck(sp != NULL, "chSemWaitTimeoutS"); if (--sp->s_cnt < 0) { + if (TIME_ZERO == time) + return RDY_TIMEOUT; sem_insert(currp, &sp->s_queue); currp->p_wtsemp = sp; return chSchGoSleepTimeoutS(PRWTSEM, time); @@ -180,7 +186,7 @@ msg_t chSemWaitTimeoutS(Semaphore *sp, systime_t time) { /** * @brief Performs a signal operation on a semaphore. * - * @param sp pointer to a @p Semaphore structure + * @param[in] sp pointer to a @p Semaphore structure * @note The function is available only if the @p CH_USE_SEMAPHORES * option is enabled in @p chconf.h. */ @@ -197,7 +203,7 @@ void chSemSignal(Semaphore *sp) { /** * @brief Performs a signal operation on a semaphore. * - * @param sp pointer to a @p Semaphore structure + * @param[in] sp pointer to a @p Semaphore structure * @note The function is available only if the @p CH_USE_SEMAPHORES * option is enabled in @p chconf.h. * @note This function does not reschedule. @@ -219,8 +225,8 @@ void chSemSignalI(Semaphore *sp) { /** * @brief Performs atomic signal and wait operations on two semaphores. * - * @param sps pointer to a @p Semaphore structure to be signaled - * @param spw pointer to a @p Semaphore structure to be wait on + * @param[in] sps pointer to a @p Semaphore structure to be signaled + * @param[in] spw pointer to a @p Semaphore structure to be wait on * @retval RDY_OK if the semaphore was signaled or not taken. * @retval RDY_RESET if the semaphore was reset using @p chSemReset(). * @note The function is available only if the @p CH_USE_SEMSW diff --git a/src/chvt.c b/src/chvt.c index 0e2eae794..f37ddd423 100644 --- a/src/chvt.c +++ b/src/chvt.c @@ -56,8 +56,8 @@ void vt_init(void) { void chVTSetI(VirtualTimer *vtp, systime_t time, vtfunc_t vtfunc, void *par) { VirtualTimer *p; - chDbgCheck((vtp != NULL) && (time != TIME_ZERO) && - (time != TIME_INFINITE) && (vtfunc != NULL), "chVTSetI"); + chDbgCheck((vtp != NULL) && (vtfunc != NULL) && + (time != TIME_ZERO) && (time != TIME_INFINITE), "chVTSetI"); vtp->vt_par = par; vtp->vt_func = vtfunc; diff --git a/src/include/scheduler.h b/src/include/scheduler.h index c79f061f7..565496dd3 100644 --- a/src/include/scheduler.h +++ b/src/include/scheduler.h @@ -41,12 +41,18 @@ #define HIGHPRIO 127 /**< Highest user priority.*/ #define ABSPRIO 255 /**< Greatest possible priority.*/ -/** Zero time specification for all the syscalls with a timeout - specification.*/ +/** + * Zero time specification for some syscalls with a timeout + * specification. + * @note Not all functions accept @p TIME_ZERO as timeout parameter, see the + * specific documentation. + */ #define TIME_ZERO ((systime_t)0) -/** Infinite time specification for all the syscalls with a timeout - specification.*/ +/** + * Infinite time specification for all the syscalls with a timeout + * specification. + */ #define TIME_INFINITE ((systime_t)-1) /** The priority of the first thread on the given ready list. */ diff --git a/test/testsem.c b/test/testsem.c index 4f2943964..07fd40840 100644 --- a/test/testsem.c +++ b/test/testsem.c @@ -81,13 +81,18 @@ static void sem2_setup(void) { static void sem2_execute(void) { int i; systime_t target_time; + msg_t msg; + + msg= chSemWaitTimeout(&sem1, TIME_ZERO); + test_assert(msg == RDY_TIMEOUT, "#1"); target_time = chSysGetTime() + MS2ST(5 * 500); for (i = 0; i < 5; i++) { test_emit_token('A' + i); - chSemWaitTimeout(&sem1, MS2ST(500)); - test_assert(isempty(&sem1.s_queue), "#1"); /* Queue not empty */ - test_assert(&sem1.s_cnt != 0, "#2"); /* Counter not zero */ + msg = chSemWaitTimeout(&sem1, MS2ST(500)); + test_assert(msg == RDY_TIMEOUT, "#2"); + test_assert(isempty(&sem1.s_queue), "#3"); /* Queue not empty */ + test_assert(&sem1.s_cnt != 0, "#4"); /* Counter not zero */ } test_assert_sequence("ABCDE"); test_assert_time_window(target_time, target_time + ALLOWED_DELAY); -- cgit v1.2.3