From cf3378588cedd2015f8c59b77fcc3fb8f9164ec8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 22 Dec 2007 11:34:39 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@155 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- src/chinit.c | 3 ++- src/chlists.c | 19 ++++++++++++++++++- src/chmtx.c | 34 ++++------------------------------ src/chschd.c | 21 ++++++--------------- src/include/inline.h | 10 ++++++++++ src/include/lists.h | 1 + src/include/scheduler.h | 1 - 7 files changed, 41 insertions(+), 48 deletions(-) (limited to 'src') diff --git a/src/chinit.c b/src/chinit.c index e57c0614e..06ee2fc9b 100644 --- a/src/chinit.c +++ b/src/chinit.c @@ -66,7 +66,8 @@ void chSysInit(void) { */ void chSysTimerHandlerI(void) { - rlist.r_preempt--; + if (rlist.r_preempt > 0) + rlist.r_preempt--; #ifdef CH_USE_SYSTEMTIME rlist.r_stime++; #endif diff --git a/src/chlists.c b/src/chlists.c index 7994f8ac6..37db948b2 100644 --- a/src/chlists.c +++ b/src/chlists.c @@ -18,12 +18,29 @@ */ /** - * @addtogroup Messages + * @addtogroup Threads * @{ */ #include #ifndef CH_OPTIMIZE_SPEED +/* + * Inserts a thread into a priority ordered queue. + * @param tp the pointer to the thread to be inserted in the list + * @param tqp the pointer to the threads list header + * @note the insertion is done by scanning the list from the highest priority + * toward the lowest + */ +void prio_insert(Thread *tp, ThreadsQueue *tqp) { + + Thread *cp = tqp->p_next; + while ((cp != (Thread *)tqp) && (cp->p_prio >= tp->p_prio)) + cp = cp->p_next; + /* Insertion on p_prev.*/ + tp->p_prev = (tp->p_next = cp)->p_prev; + tp->p_prev->p_next = cp->p_prev = tp; +} + /* * Inserts a thread into a FIFO queue. * @param tp the pointer to the thread to be inserted in the list diff --git a/src/chmtx.c b/src/chmtx.c index 822789270..9037621bb 100644 --- a/src/chmtx.c +++ b/src/chmtx.c @@ -36,25 +36,6 @@ void chMtxInit(Mutex *mp) { mp->m_owner = NULL; } -/* - * Inserts a thread into a list ordering it by priority. - * @param tp the pointer to the thread to be inserted in the list - * @param tqp the pointer to the threads list header - */ -#ifdef CH_OPTIMIZE_SPEED -static INLINE void prio_enq(Thread *tp, ThreadsQueue *tqp) { -#else -static void prio_enq(Thread *tp, ThreadsQueue *tqp) { -#endif - - Thread *cp = tqp->p_next; - while ((cp != (Thread *)tqp) && (cp->p_prio >= tp->p_prio)) - cp = cp->p_next; - /* Insertion on p_prev.*/ - tp->p_prev = (tp->p_next = cp)->p_prev; - tp->p_prev->p_next = cp->p_prev = tp; -} - /** * Locks the specified mutex. * @param mp pointer to the \p Mutex structure @@ -86,7 +67,7 @@ void chMtxLockS(Mutex *mp) { tp->p_prio = currp->p_prio; switch (tp->p_state) { case PRWTMTX: - prio_enq(dequeue(tp), &tp->p_mtxp->m_queue); + prio_insert(dequeue(tp), &tp->p_mtxp->m_queue); tp = tp->p_mtxp->m_owner; continue; case PRREADY: @@ -97,7 +78,7 @@ void chMtxLockS(Mutex *mp) { /* * Goes to sleep on the mutex. */ - prio_enq(currp, &mp->m_queue); + prio_insert(currp, &mp->m_queue); currp->p_mtxp = mp; chSchGoSleepS(PRWTMTX); chDbgAssert(mp->m_owner == NULL, "chmtx.c, chMtxLockS()"); @@ -189,15 +170,8 @@ void chMtxUnlockS(void) { newprio = mp->m_queue.p_next->p_prio; mp = mp->m_next; } - if (currp->p_prio == newprio) - chSchWakeupS(tp, RDY_OK); - else { - /* Note, changing priority and use chSchWakeupS() is wrong because the - internal optimization, see the chSchWakeupS() notes.*/ - currp->p_prio = newprio; - chSchReadyI(tp, RDY_OK); - chSchRescheduleS(); - } + currp->p_prio = newprio; + chSchWakeupS(tp, RDY_OK); } } diff --git a/src/chschd.c b/src/chschd.c index 78efa57f7..78f051bf8 100644 --- a/src/chschd.c +++ b/src/chschd.c @@ -35,7 +35,7 @@ ReadyList rlist; void chSchInit(void) { fifo_init(&rlist.r_queue); - rlist.r_prio = ABSPRIO; +// rlist.r_prio = ABSPRIO; rlist.r_preempt = CH_TIME_QUANTUM; #ifdef CH_USE_SYSTEMTIME rlist.r_stime = 0; @@ -58,15 +58,10 @@ INLINE void chSchReadyI(Thread *tp, t_msg msg) { #else void chSchReadyI(Thread *tp, t_msg msg) { #endif - Thread *cp = rlist.r_queue.p_prev; tp->p_state = PRREADY; tp->p_rdymsg = msg; - while (cp->p_prio < tp->p_prio) - cp = cp->p_prev; - /* Insertion on p_next.*/ - tp->p_next = (tp->p_prev = cp)->p_next; - tp->p_next->p_prev = cp->p_next = tp; + prio_insert(tp, &rlist.r_queue); } /** @@ -104,8 +99,6 @@ void chSchGoSleepS(t_tstate newstate) { * @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 * \p chSchRescheduleS() but much more efficient. - * @note The function assumes that the invoking thread is the highest priority - * thread, so you can't use it to change priority and reschedule. */ void chSchWakeupS(Thread *ntp, t_msg msg) { @@ -113,15 +106,13 @@ void chSchWakeupS(Thread *ntp, t_msg msg) { chSchReadyI(ntp, msg); else { Thread *otp = currp; - /* Optimization, assumes that the invoking thread has the highest priority - which is always true unless the priority was willingly changed. - This assumption allows us to place the thread always on top of the - ready list without have to scan it, free lunch.*/ + /* Note, does a prio_insert() instead of a chSchReadyI() because of the + relative priority between the two threads, prio_insert() scans the + list starting from the highest priority end downward.*/ /* chSchReadyI(otp, RDY_OK);*/ otp->p_state = PRREADY; otp->p_rdymsg = RDY_OK; - otp->p_next = (otp->p_prev = (Thread *)&rlist.r_queue)->p_next; - otp->p_next->p_prev = rlist.r_queue.p_next = otp; + prio_insert(otp, &rlist.r_queue); (currp = ntp)->p_state = PRCURR; ntp->p_rdymsg = msg; rlist.r_preempt = CH_TIME_QUANTUM; diff --git a/src/include/inline.h b/src/include/inline.h index 1982fd075..85de20f3f 100644 --- a/src/include/inline.h +++ b/src/include/inline.h @@ -26,6 +26,16 @@ * this is true for GCC, not sure about other compilers. */ #ifdef CH_OPTIMIZE_SPEED +static INLINE void prio_insert(Thread *tp, ThreadsQueue *tqp) { + + Thread *cp = tqp->p_next; + while ((cp != (Thread *)tqp) && (cp->p_prio >= tp->p_prio)) + cp = cp->p_next; + /* Insertion on p_prev.*/ + tp->p_prev = (tp->p_next = cp)->p_prev; + tp->p_prev->p_next = cp->p_prev = tp; +} + static INLINE void fifo_insert(Thread *tp, ThreadsQueue *tqp) { tp->p_prev = (tp->p_next = (Thread *)tqp)->p_prev; diff --git a/src/include/lists.h b/src/include/lists.h index 043538457..2a8f20e82 100644 --- a/src/include/lists.h +++ b/src/include/lists.h @@ -59,6 +59,7 @@ typedef struct { #ifdef __cplusplus extern "C" { #endif + void prio_insert(Thread *tp, ThreadsQueue *tqp); void fifo_insert(Thread *tp, ThreadsQueue *tqp); Thread *fifo_remove(ThreadsQueue *tqp); Thread *dequeue(Thread *tp); diff --git a/src/include/scheduler.h b/src/include/scheduler.h index 183e3af79..565b75ccb 100644 --- a/src/include/scheduler.h +++ b/src/include/scheduler.h @@ -39,7 +39,6 @@ */ typedef struct { ThreadsQueue r_queue; - t_prio r_prio; t_cnt r_preempt; #ifndef CH_CURRP_REGISTER_CACHE Thread *r_current; -- cgit v1.2.3