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
This commit is contained in:
gdisirio 2009-03-07 15:32:40 +00:00
parent d785c8a7e5
commit d9ff829a71
8 changed files with 178 additions and 130 deletions

View File

@ -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().

View File

@ -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;

View File

@ -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)

View File

@ -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.
*/

View File

@ -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

View File

@ -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;

View File

@ -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. */

View File

@ -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);