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

This commit is contained in:
gdisirio 2008-01-08 13:41:04 +00:00
parent 79194eae8e
commit ba030d32c3
5 changed files with 35 additions and 19 deletions

View File

@ -41,7 +41,7 @@ AVR-AT90CANx-GCC - Port on AVR AT90CAN128, not complete yet.
*** 0.5.1 *** *** 0.5.1 ***
- NEW: Priority enqueing for messages can be optionally enabled by specifying - NEW: Priority enqueing for messages can be optionally enabled by specifying
the P_MSGBYPRIO option when creating a server thread. the P_MSGBYPRIO option when creating a message server thread.
This change allows the implementation of a priority ceiling protocol into This change allows the implementation of a priority ceiling protocol into
message servers threads. Threads serving messages by priority and threads message servers threads. Threads serving messages by priority and threads
serving messages in FIFO orded can exist at the same time in the system. serving messages in FIFO orded can exist at the same time in the system.

View File

@ -45,6 +45,7 @@ t_msg chMsgSend(Thread *tp, t_msg msg) {
fifo_insert(currp, &tp->p_msgqueue); fifo_insert(currp, &tp->p_msgqueue);
#endif #endif
currp->p_msg = msg; currp->p_msg = msg;
currp->p_wtthdp = tp;
if (tp->p_state == PRWTMSG) if (tp->p_state == PRWTMSG)
chSchReadyI(tp, RDY_OK); chSchReadyI(tp, RDY_OK);
chSchGoSleepS(PRSNDMSG); chSchGoSleepS(PRSNDMSG);
@ -83,6 +84,7 @@ t_msg chMsgSendWithEvent(Thread *tp, t_msg msg, EventSource *esp) {
fifo_insert(currp, &tp->p_msgqueue); fifo_insert(currp, &tp->p_msgqueue);
#endif #endif
chEvtSendI(esp); chEvtSendI(esp);
currp->p_wtthdp = tp;
currp->p_msg = msg; currp->p_msg = msg;
chSchGoSleepS(PRSNDMSG); chSchGoSleepS(PRSNDMSG);
msg = currp->p_rdymsg; msg = currp->p_rdymsg;
@ -129,9 +131,10 @@ t_msg chMsgSendTimeout(Thread *tp, t_msg msg, t_time time) {
#else #else
fifo_insert(currp, &tp->p_msgqueue); fifo_insert(currp, &tp->p_msgqueue);
#endif #endif
currp->p_msg = msg;
currp->p_wtthdp = tp;
if (tp->p_state == PRWTMSG) if (tp->p_state == PRWTMSG)
chSchReadyI(tp, RDY_OK); chSchReadyI(tp, RDY_OK);
currp->p_msg = msg;
chSchGoSleepS(PRSNDMSG); chSchGoSleepS(PRSNDMSG);
msg = currp->p_rdymsg; msg = currp->p_rdymsg;
if (chVTIsArmedI(&vt)) if (chVTIsArmedI(&vt))

View File

@ -65,11 +65,19 @@ void chMtxLockS(Mutex *mp) {
Thread *tp = mp->m_owner; Thread *tp = mp->m_owner;
while (tp->p_prio < currp->p_prio) { while (tp->p_prio < currp->p_prio) {
tp->p_prio = currp->p_prio; tp->p_prio = currp->p_prio;
/*
* The following states need priority queues reordering.
*/
switch (tp->p_state) { switch (tp->p_state) {
case PRWTMTX: case PRWTMTX:
prio_insert(dequeue(tp), &tp->p_mtxp->m_queue); prio_insert(dequeue(tp), &tp->p_wtmtxp->m_queue);
tp = tp->p_mtxp->m_owner; tp = tp->p_wtmtxp->m_owner;
continue; continue;
#ifdef CH_USE_MESSAGES_PRIORITY
case PRSNDMSG:
if (tp->p_flags & P_MSGBYPRIO)
prio_insert(dequeue(tp), &tp->p_wtthdp->p_msgqueue);
#endif
case PRREADY: case PRREADY:
chSchReadyI(dequeue(tp), RDY_OK); chSchReadyI(dequeue(tp), RDY_OK);
} }
@ -79,7 +87,7 @@ void chMtxLockS(Mutex *mp) {
* Goes to sleep on the mutex. * Goes to sleep on the mutex.
*/ */
prio_insert(currp, &mp->m_queue); prio_insert(currp, &mp->m_queue);
currp->p_mtxp = mp; currp->p_wtmtxp = mp;
chSchGoSleepS(PRWTMTX); chSchGoSleepS(PRWTMTX);
chDbgAssert(mp->m_owner == NULL, "chmtx.c, chMtxLockS()"); chDbgAssert(mp->m_owner == NULL, "chmtx.c, chMtxLockS()");
} }

View File

@ -109,7 +109,7 @@ t_msg chSemWaitS(Semaphore *sp) {
if (--sp->s_cnt < 0) { if (--sp->s_cnt < 0) {
fifo_insert(currp, &sp->s_queue); fifo_insert(currp, &sp->s_queue);
currp->p_semp = sp; currp->p_wtsemp = sp;
chSchGoSleepS(PRWTSEM); chSchGoSleepS(PRWTSEM);
return currp->p_rdymsg; return currp->p_rdymsg;
} }
@ -120,7 +120,7 @@ t_msg chSemWaitS(Semaphore *sp) {
static void wakeup(void *p) { static void wakeup(void *p) {
chDbgAssert(((Thread *)p)->p_state == PRWTSEM, "chsem.c, wakeup()"); chDbgAssert(((Thread *)p)->p_state == PRWTSEM, "chsem.c, wakeup()");
chSemFastSignalI(((Thread *)p)->p_semp); chSemFastSignalI(((Thread *)p)->p_wtsemp);
chSchReadyI(dequeue(p), RDY_TIMEOUT); chSchReadyI(dequeue(p), RDY_TIMEOUT);
} }
@ -158,7 +158,7 @@ t_msg chSemWaitTimeoutS(Semaphore *sp, t_time time) {
chVTSetI(&vt, time, wakeup, currp); chVTSetI(&vt, time, wakeup, currp);
fifo_insert(currp, &sp->s_queue); fifo_insert(currp, &sp->s_queue);
currp->p_semp = sp; currp->p_wtsemp = sp;
chSchGoSleepS(PRWTSEM); chSchGoSleepS(PRWTSEM);
if (chVTIsArmedI(&vt)) if (chVTIsArmedI(&vt))
chVTResetI(&vt); chVTResetI(&vt);
@ -215,7 +215,7 @@ void chSemSignalWait(Semaphore *sps, Semaphore *spw) {
if (--spw->s_cnt < 0) { if (--spw->s_cnt < 0) {
fifo_insert(currp, &spw->s_queue); fifo_insert(currp, &spw->s_queue);
currp->p_semp = spw; currp->p_wtsemp = spw;
chSchGoSleepS(PRWTSEM); chSchGoSleepS(PRWTSEM);
} }
else else

View File

@ -48,23 +48,30 @@ struct Thread {
/** Mode flags.*/ /** Mode flags.*/
t_tmode p_flags; t_tmode p_flags;
/* /*
* The following fields are merged in an union because they are all * The following fields are merged in unions because they are all
* state-specific fields. This trick saves some extra space for each * state-specific fields. This trick saves some extra space for each
* thread in the system. * thread in the system.
*/ */
union { union {
#ifdef CH_USE_SEMAPHORES
/** Semaphore where the thread is waiting on (only in \p PRWTSEM state).*/
Semaphore *p_wtsemp;
#endif
#ifdef CH_USE_MUTEXES
/** Mutex where the thread is waiting on (only in \p PRWTMTX state).*/
Mutex *p_wtmtxp;
#endif
#ifdef CH_USE_MESSAGES
/** Destination thread for message send (only in \p PRSNDMSG state).*/
Thread *p_wtthdp;
#endif
};
union {
/** Thread wakeup code, normally set to \p RDY_OK by the \p chSchReadyI() /** Thread wakeup code, normally set to \p RDY_OK by the \p chSchReadyI()
* (only while in \p PRREADY state).*/ * (only while in \p PRREADY state).*/
t_msg p_rdymsg; t_msg p_rdymsg;
/** The thread exit code (only while in \p PREXIT state).*/ /** The thread exit code (only while in \p PREXIT state).*/
t_msg p_exitcode; t_msg p_exitcode;
#ifdef CH_USE_SEMAPHORES
/** Semaphore where the thread is waiting on (only in \p PRWTSEM state).*/
Semaphore *p_semp;
#endif
#ifdef CH_USE_MUTEXES
Mutex *p_mtxp;
#endif
#ifdef CH_USE_EVENTS #ifdef CH_USE_EVENTS
/** Enabled events mask (only while in \p PRWTEVENT state).*/ /** Enabled events mask (only while in \p PRWTEVENT state).*/
t_eventmask p_ewmask; t_eventmask p_ewmask;
@ -73,8 +80,6 @@ struct Thread {
/** Message (only while in \p PRSNDMSG state).*/ /** Message (only while in \p PRSNDMSG state).*/
t_msg p_msg; t_msg p_msg;
#endif #endif
/** Generic way to access the union.*/
void *p_common;
}; };
/** Machine dependent processor context.*/ /** Machine dependent processor context.*/
Context p_ctx; Context p_ctx;