From ba030d32c3e65ec5d4c6c6eaf7f55d7c61aae0b8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 8 Jan 2008 13:41:04 +0000 Subject: [PATCH] git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@170 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- readme.txt | 2 +- src/chmsg.c | 5 ++++- src/chmtx.c | 14 +++++++++++--- src/chsem.c | 8 ++++---- src/include/threads.h | 25 +++++++++++++++---------- 5 files changed, 35 insertions(+), 19 deletions(-) diff --git a/readme.txt b/readme.txt index 03a6035c8..36e94e505 100644 --- a/readme.txt +++ b/readme.txt @@ -41,7 +41,7 @@ AVR-AT90CANx-GCC - Port on AVR AT90CAN128, not complete yet. *** 0.5.1 *** - 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 message servers threads. Threads serving messages by priority and threads serving messages in FIFO orded can exist at the same time in the system. diff --git a/src/chmsg.c b/src/chmsg.c index 20a59904e..ef8b111dc 100644 --- a/src/chmsg.c +++ b/src/chmsg.c @@ -45,6 +45,7 @@ t_msg chMsgSend(Thread *tp, t_msg msg) { 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); @@ -83,6 +84,7 @@ t_msg chMsgSendWithEvent(Thread *tp, t_msg msg, EventSource *esp) { fifo_insert(currp, &tp->p_msgqueue); #endif chEvtSendI(esp); + currp->p_wtthdp = tp; currp->p_msg = msg; chSchGoSleepS(PRSNDMSG); msg = currp->p_rdymsg; @@ -129,9 +131,10 @@ t_msg chMsgSendTimeout(Thread *tp, t_msg msg, t_time time) { #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); - currp->p_msg = msg; chSchGoSleepS(PRSNDMSG); msg = currp->p_rdymsg; if (chVTIsArmedI(&vt)) diff --git a/src/chmtx.c b/src/chmtx.c index 25f3ce664..3a1e2e00f 100644 --- a/src/chmtx.c +++ b/src/chmtx.c @@ -65,11 +65,19 @@ void chMtxLockS(Mutex *mp) { Thread *tp = mp->m_owner; while (tp->p_prio < currp->p_prio) { tp->p_prio = currp->p_prio; + /* + * The following states need priority queues reordering. + */ switch (tp->p_state) { case PRWTMTX: - prio_insert(dequeue(tp), &tp->p_mtxp->m_queue); - tp = tp->p_mtxp->m_owner; + prio_insert(dequeue(tp), &tp->p_wtmtxp->m_queue); + tp = tp->p_wtmtxp->m_owner; 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: chSchReadyI(dequeue(tp), RDY_OK); } @@ -79,7 +87,7 @@ void chMtxLockS(Mutex *mp) { * Goes to sleep on the mutex. */ prio_insert(currp, &mp->m_queue); - currp->p_mtxp = mp; + currp->p_wtmtxp = mp; chSchGoSleepS(PRWTMTX); chDbgAssert(mp->m_owner == NULL, "chmtx.c, chMtxLockS()"); } diff --git a/src/chsem.c b/src/chsem.c index 8e5073248..0ab603b03 100644 --- a/src/chsem.c +++ b/src/chsem.c @@ -109,7 +109,7 @@ t_msg chSemWaitS(Semaphore *sp) { if (--sp->s_cnt < 0) { fifo_insert(currp, &sp->s_queue); - currp->p_semp = sp; + currp->p_wtsemp = sp; chSchGoSleepS(PRWTSEM); return currp->p_rdymsg; } @@ -120,7 +120,7 @@ t_msg chSemWaitS(Semaphore *sp) { static void wakeup(void *p) { chDbgAssert(((Thread *)p)->p_state == PRWTSEM, "chsem.c, wakeup()"); - chSemFastSignalI(((Thread *)p)->p_semp); + chSemFastSignalI(((Thread *)p)->p_wtsemp); chSchReadyI(dequeue(p), RDY_TIMEOUT); } @@ -158,7 +158,7 @@ t_msg chSemWaitTimeoutS(Semaphore *sp, t_time time) { chVTSetI(&vt, time, wakeup, currp); fifo_insert(currp, &sp->s_queue); - currp->p_semp = sp; + currp->p_wtsemp = sp; chSchGoSleepS(PRWTSEM); if (chVTIsArmedI(&vt)) chVTResetI(&vt); @@ -215,7 +215,7 @@ void chSemSignalWait(Semaphore *sps, Semaphore *spw) { if (--spw->s_cnt < 0) { fifo_insert(currp, &spw->s_queue); - currp->p_semp = spw; + currp->p_wtsemp = spw; chSchGoSleepS(PRWTSEM); } else diff --git a/src/include/threads.h b/src/include/threads.h index 8b862f4f3..37c962793 100644 --- a/src/include/threads.h +++ b/src/include/threads.h @@ -48,23 +48,30 @@ struct Thread { /** Mode 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 * thread in the system. */ 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() * (only while in \p PRREADY state).*/ t_msg p_rdymsg; /** The thread exit code (only while in \p PREXIT state).*/ 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 /** Enabled events mask (only while in \p PRWTEVENT state).*/ t_eventmask p_ewmask; @@ -73,8 +80,6 @@ struct Thread { /** Message (only while in \p PRSNDMSG state).*/ t_msg p_msg; #endif - /** Generic way to access the union.*/ - void *p_common; }; /** Machine dependent processor context.*/ Context p_ctx;