git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@182 35acf78f-673a-0410-8e92-d51de3d6d3f4

This commit is contained in:
gdisirio 2008-01-23 14:50:42 +00:00
parent 1aecb14913
commit 68003a03c2
16 changed files with 60 additions and 173 deletions

View File

@ -95,12 +95,6 @@
* included in the kernel.*/ * included in the kernel.*/
//#define CH_USE_MESSAGES //#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() /** Configuration option: if specified then the \p chMsgSendWithEvent()
* function is included in the kernel. * function is included in the kernel.
* @note requires \p CH_USE_MESSAGES. * @note requires \p CH_USE_MESSAGES.

View File

@ -95,12 +95,6 @@
* included in the kernel.*/ * included in the kernel.*/
#define CH_USE_MESSAGES #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() /** Configuration option: if specified then the \p chMsgSendWithEvent()
* function is included in the kernel. * function is included in the kernel.
* @note requires \p CH_USE_MESSAGES. * @note requires \p CH_USE_MESSAGES.

View File

@ -96,12 +96,6 @@
* included in the kernel.*/ * included in the kernel.*/
#define CH_USE_MESSAGES #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() /** Configuration option: if specified then the \p chMsgSendWithEvent()
* function is included in the kernel. * function is included in the kernel.
* @note requires \p CH_USE_MESSAGES. * @note requires \p CH_USE_MESSAGES.

View File

@ -100,12 +100,6 @@
* included in the kernel.*/ * included in the kernel.*/
#define CH_USE_MESSAGES #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() /** Configuration option: if specified then the \p chMsgSendWithEvent()
* function is included in the kernel. * function is included in the kernel.
* @note requires \p CH_USE_MESSAGES. * @note requires \p CH_USE_MESSAGES.

View File

@ -100,12 +100,6 @@
* included in the kernel.*/ * included in the kernel.*/
#define CH_USE_MESSAGES #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() /** Configuration option: if specified then the \p chMsgSendWithEvent()
* function is included in the kernel. * function is included in the kernel.
* @note requires \p CH_USE_MESSAGES. * @note requires \p CH_USE_MESSAGES.

View File

@ -241,7 +241,6 @@ PREDEFINED = __JUST_STUBS__ \
CH_USE_SERIAL_FULLDUPLEX \ CH_USE_SERIAL_FULLDUPLEX \
CH_USE_SERIAL_HALFDUPLEX \ CH_USE_SERIAL_HALFDUPLEX \
CH_USE_MESSAGES \ CH_USE_MESSAGES \
CH_USE_MESSAGES_TIMEOUT \
CH_USE_MESSAGES_EVENT \ CH_USE_MESSAGES_EVENT \
CH_USE_MESSAGES_PRIORITY \ CH_USE_MESSAGES_PRIORITY \
CH_USE_SEMSW \ CH_USE_SEMSW \

View File

@ -39,6 +39,20 @@ AVR-AT90CANx-GCC - Port on AVR AT90CAN128, not complete yet.
*** Releases *** *** 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 *** *** 0.5.2 ***
- Fixed a small problem in the main header file ch.h. - Fixed a small problem in the main header file ch.h.
- Small reordering in the fields of the Thread structure in order to optimize - Small reordering in the fields of the Thread structure in order to optimize

View File

@ -142,12 +142,6 @@ t_eventid chEvtWait(t_eventmask ewmask,
return chEvtWaitTimeout(ewmask, handlers, TIME_INFINITE); 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 * 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 * event identifier, if an event handler is specified then the handler is
@ -177,17 +171,9 @@ t_eventid chEvtWaitTimeout(t_eventmask ewmask,
chSysLock(); chSysLock();
if ((currp->p_epending & ewmask) == 0) { if ((currp->p_epending & ewmask) == 0) {
VirtualTimer vt;
chVTSetI(&vt, time, wakeup, currp);
currp->p_ewmask = ewmask; currp->p_ewmask = ewmask;
chSchGoSleepS(PRWTEVENT); if (chSchGoSleepTimeoutS(PRWTEVENT, time) < RDY_OK)
if (!chVTIsArmedI(&vt)) {
chSysUnlock();
return RDY_TIMEOUT; return RDY_TIMEOUT;
}
chVTResetI(&vt);
} }
i = 0, m = 1; i = 0, m = 1;
while ((currp->p_epending & ewmask & m) == 0) while ((currp->p_epending & ewmask & m) == 0)

View File

@ -94,57 +94,6 @@ t_msg chMsgSendWithEvent(Thread *tp, t_msg msg, EventSource *esp) {
} }
#endif #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. * Suspends the thread and waits for an incoming message.
* *

View File

@ -90,6 +90,33 @@ void chSchGoSleepS(t_tstate newstate) {
chSysSwitchI(otp, currp); 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 * Wakeups a thread, the thread is inserted into the ready list or made
* running directly depending on its relative priority compared to the current * running directly depending on its relative priority compared to the current

View File

@ -117,13 +117,6 @@ t_msg chSemWaitS(Semaphore *sp) {
} }
#ifdef CH_USE_SEMAPHORES_TIMEOUT #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. * Performs a wait operation on a semaphore with timeout specification.
* @param sp pointer to a \p Semaphore structure * @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) { t_msg chSemWaitTimeoutS(Semaphore *sp, t_time time) {
if (--sp->s_cnt < 0) { if (--sp->s_cnt < 0) {
VirtualTimer vt;
chVTSetI(&vt, time, wakeup, currp);
fifo_insert(currp, &sp->s_queue); fifo_insert(currp, &sp->s_queue);
currp->p_wtsemp = sp; currp->p_wtsemp = sp;
chSchGoSleepS(PRWTSEM); return chSchGoSleepTimeoutS(PRWTSEM, time);
if (chVTIsArmedI(&vt))
chVTResetI(&vt);
return currp->p_rdymsg;
} }
return RDY_OK; return RDY_OK;
} }

View File

@ -25,47 +25,18 @@
#include <ch.h> #include <ch.h>
#ifdef CH_USE_SLEEP #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. * Suspends the invoking thread for the specified time.
* @param time the system ticks number * @param time the system ticks number
*/ */
void chThdSleep(t_time time) { void chThdSleep(t_time time) {
VirtualTimer vt;
chSysLock(); chSysLock();
chVTSetI(&vt, time, wakeup, currp); chSchGoSleepTimeoutS(PRSLEEP, time);
chSchGoSleepS(PRSLEEP);
chSysUnlock(); 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 */ #endif /* CH_USE_SLEEP */
/** @} */ /** @} */

View File

@ -60,6 +60,7 @@ extern "C" {
void chSchInit(void); void chSchInit(void);
void chSchReadyI(Thread *tp, t_msg msg); void chSchReadyI(Thread *tp, t_msg msg);
void chSchGoSleepS(t_tstate newstate); void chSchGoSleepS(t_tstate newstate);
t_msg chSchGoSleepTimeoutS(t_tstate newstate, t_time time);
void chSchWakeupS(Thread *tp, t_msg msg); void chSchWakeupS(Thread *tp, t_msg msg);
void chSchDoRescheduleI(void); void chSchDoRescheduleI(void);
void chSchRescheduleS(void); void chSchRescheduleS(void);

View File

@ -30,14 +30,12 @@ extern "C" {
#endif #endif
#ifdef CH_USE_SLEEP #ifdef CH_USE_SLEEP
void chThdSleep(t_time time); void chThdSleep(t_time time);
#ifdef CH_USE_SYSTEMTIME
void chThdSleepUntil(t_time time);
#endif /* CH_USE_SYSTEMTIME */
#endif /* CH_USE_SLEEP */ #endif /* CH_USE_SLEEP */
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#ifdef CH_USE_SYSTEMTIME
/** /**
* Returns the number of system ticks since the \p chSysInit() invocation. * Returns the number of system ticks since the \p chSysInit() invocation.
* @return the system ticks number * @return the system ticks number
@ -48,6 +46,20 @@ extern "C" {
*/ */
#define chSysGetTime() rlist.r_stime #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_ */ #endif /* _SLEEP_H_ */
/** @} */ /** @} */

View File

@ -96,12 +96,6 @@
* included in the kernel.*/ * included in the kernel.*/
#define CH_USE_MESSAGES #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() /** Configuration option: if specified then the \p chMsgSendWithEvent()
* function is included in the kernel. * function is included in the kernel.
* @note requires \p CH_USE_MESSAGES. * @note requires \p CH_USE_MESSAGES.

View File

@ -134,14 +134,6 @@ t_msg Thread4(void *p) {
return 0; 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) { t_msg Thread6(void *p) {
while (!chThdShouldTerminate()) while (!chThdShouldTerminate())
@ -386,20 +378,6 @@ void testmsg1(void) {
println(""); 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)) __attribute__((noinline))
unsigned int msg_loop_test(Thread *tp) { unsigned int msg_loop_test(Thread *tp) {
unsigned int i; unsigned int i;
@ -565,7 +543,6 @@ t_msg TestThread(void *p) {
* Messages tests. * Messages tests.
*/ */
testmsg1(); testmsg1();
testmsg2();
/* /*
* Kernel benchmarks. * Kernel benchmarks.