From 673a7209613e33e063081465d55e8a3d38895669 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 21 Jun 2010 17:53:12 +0000 Subject: [PATCH] Fixed bugs 3019099 and 3019158. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/branches/stable_2.0.x@2029 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- docs/Doxyfile | 2 +- os/kernel/include/ch.h | 4 +-- os/kernel/src/chmtx.c | 58 +++++++++++++++++++++++++++++----------- os/kernel/src/chqueues.c | 10 +++++-- readme.txt | 5 ++++ 5 files changed, 59 insertions(+), 20 deletions(-) diff --git a/docs/Doxyfile b/docs/Doxyfile index a0e8d9b0b..8ec001333 100644 --- a/docs/Doxyfile +++ b/docs/Doxyfile @@ -31,7 +31,7 @@ PROJECT_NAME = ChibiOS/RT # This could be handy for archiving the generated documentation or # if some version control system is used. -PROJECT_NUMBER = 2.0.0 +PROJECT_NUMBER = 2.0.1 # The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute) # base path where the generated documentation will be put. diff --git a/os/kernel/include/ch.h b/os/kernel/include/ch.h index f259e5988..281aa7183 100644 --- a/os/kernel/include/ch.h +++ b/os/kernel/include/ch.h @@ -46,7 +46,7 @@ /** * @brief Kernel version string. */ -#define CH_KERNEL_VERSION "2.0.0" +#define CH_KERNEL_VERSION "2.0.1" /** * @brief Kernel version major number. @@ -61,7 +61,7 @@ /** * @brief Kernel version patch number. */ -#define CH_KERNEL_PATCH 0 +#define CH_KERNEL_PATCH 1 /* * Common values. diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 118dc0a0c..04e817821 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -152,12 +152,17 @@ void chMtxLockS(Mutex *mp) { prio_insert(ctp, &mp->m_queue); ctp->p_u.wtobjp = mp; chSchGoSleepS(THD_STATE_WTMTX); - chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned"); + /* It is assumed that the thread performing the unlock operation assigns + the mutex to this thread.*/ + chDbgAssert(mp->m_owner == ctp, "chMtxLockS(), #1", "not owner"); + chDbgAssert(ctp->p_mtxlist == mp, "chMtxLockS(), #2", "not owned"); + } + else { + /* It was not owned, inserted in the owned mutexes list.*/ + mp->m_owner = ctp; + mp->m_next = ctp->p_mtxlist; + ctp->p_mtxlist = mp; } - /* The mutex is now inserted in the owned mutexes list.*/ - mp->m_owner = ctp; - mp->m_next = ctp->p_mtxlist; - ctp->p_mtxlist = mp; } /** @@ -223,9 +228,10 @@ Mutex *chMtxUnlock(void) { as not owned.*/ ump = ctp->p_mtxlist; ctp->p_mtxlist = ump->m_next; - ump->m_owner = NULL; /* If a thread is waiting on the mutex then the fun part begins.*/ if (chMtxQueueNotEmptyS(ump)) { + Thread *tp; + /* Recalculates the optimal thread priority by scanning the owned mutexes list.*/ tprio_t newprio = ctp->p_realprio; @@ -241,9 +247,16 @@ Mutex *chMtxUnlock(void) { /* Assigns to the current thread the highest priority among all the waiting threads.*/ ctp->p_prio = newprio; - /* Awakens the highest priority thread waiting for the unlocked mutex.*/ - chSchWakeupS(fifo_remove(&ump->m_queue), RDY_OK); + /* Awakens the highest priority thread waiting for the unlocked mutex and + assigns the mutex to it.*/ + tp = fifo_remove(&ump->m_queue); + ump->m_owner = tp; + ump->m_next = tp->p_mtxlist; + tp->p_mtxlist = ump; + chSchWakeupS(tp, RDY_OK); } + else + ump->m_owner = NULL; chSysUnlock(); return ump; } @@ -269,9 +282,10 @@ Mutex *chMtxUnlockS(void) { owned.*/ ump = ctp->p_mtxlist; ctp->p_mtxlist = ump->m_next; - ump->m_owner = NULL; /* If a thread is waiting on the mutex then the fun part begins.*/ if (chMtxQueueNotEmptyS(ump)) { + Thread *tp; + /* Recalculates the optimal thread priority by scanning the owned mutexes list.*/ tprio_t newprio = ctp->p_realprio; @@ -285,8 +299,16 @@ Mutex *chMtxUnlockS(void) { mp = mp->m_next; } ctp->p_prio = newprio; - chSchReadyI(fifo_remove(&ump->m_queue)); + /* Awakens the highest priority thread waiting for the unlocked mutex and + assigns the mutex to it.*/ + tp = fifo_remove(&ump->m_queue); + ump->m_owner = tp; + ump->m_next = tp->p_mtxlist; + tp->p_mtxlist = ump; + chSchReadyI(tp); } + else + ump->m_owner = NULL; return ump; } @@ -303,11 +325,17 @@ void chMtxUnlockAll(void) { chSysLock(); if (ctp->p_mtxlist != NULL) { do { - Mutex *mp = ctp->p_mtxlist; - ctp->p_mtxlist = mp->m_next; - mp->m_owner = NULL; - if (chMtxQueueNotEmptyS(mp)) - chSchReadyI(fifo_remove(&mp->m_queue)); + Mutex *ump = ctp->p_mtxlist; + ctp->p_mtxlist = ump->m_next; + if (chMtxQueueNotEmptyS(ump)) { + Thread *tp = fifo_remove(&ump->m_queue); + ump->m_owner = tp; + ump->m_next = tp->p_mtxlist; + tp->p_mtxlist = ump; + chSchReadyI(tp); + } + else + ump->m_owner = NULL; } while (ctp->p_mtxlist != NULL); ctp->p_prio = ctp->p_realprio; chSchRescheduleS(); diff --git a/os/kernel/src/chqueues.c b/os/kernel/src/chqueues.c index 2a5ac7347..8c41878f0 100644 --- a/os/kernel/src/chqueues.c +++ b/os/kernel/src/chqueues.c @@ -161,7 +161,8 @@ msg_t chIQGetTimeout(InputQueue *iqp, systime_t time) { * * @param[in] iqp pointer to an @p InputQueue structure * @param[out] bp pointer to the data buffer - * @param[in] n the maximum amount of data to be transferred + * @param[in] n the maximum amount of data to be transferred, the + * value 0 is reserved * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. @@ -174,6 +175,8 @@ size_t chIQReadTimeout(InputQueue *iqp, uint8_t *bp, qnotify_t nfy = iqp->q_notify; size_t r = 0; + chDbgCheck(n > 0, "chIQReadTimeout"); + chSysLock(); while (TRUE) { if (chIQIsEmpty(iqp)) { @@ -311,7 +314,8 @@ msg_t chOQGetI(OutputQueue *oqp) { * * @param[in] oqp pointer to an @p OutputQueue structure * @param[out] bp pointer to the data buffer - * @param[in] n the maximum amount of data to be transferred + * @param[in] n the maximum amount of data to be transferred, the + * value 0 is reserved * @param[in] time the number of ticks before the operation timeouts, * the following special values are allowed: * - @a TIME_IMMEDIATE immediate timeout. @@ -324,6 +328,8 @@ size_t chOQWriteTimeout(OutputQueue *oqp, const uint8_t *bp, qnotify_t nfy = oqp->q_notify; size_t w = 0; + chDbgCheck(n > 0, "chOQWriteTimeout"); + chSysLock(); while (TRUE) { if (chOQIsFull(oqp)) { diff --git a/readme.txt b/readme.txt index 1f6215365..27c906888 100644 --- a/readme.txt +++ b/readme.txt @@ -58,6 +58,11 @@ *** Releases *** ***************************************************************************** +*** 2.0.1 *** +- FIX: Fixed missing check in chIQReadTimeout() and chIQWriteTimeout() (bug + 3019158). +- FIX: Fixed instability in Mutexes subsystem (bug 3019099). + *** 2.0.0 *** - NEW: Implemented the concept of thread references, this mechanism ensures that a dynamic thread's memory is not freed while some other thread still