diff options
author | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2009-09-05 15:33:27 +0000 |
---|---|---|
committer | gdisirio <gdisirio@35acf78f-673a-0410-8e92-d51de3d6d3f4> | 2009-09-05 15:33:27 +0000 |
commit | e8e651a11d611164e9390c40e174b15280527a7f (patch) | |
tree | e17ce8a75f0f621181a910ad041864191ed3578a /src/chmtx.c | |
parent | 7dfa36f86d896cdb824a9137a81f324c8243c4d9 (diff) | |
download | ChibiOS-e8e651a11d611164e9390c40e174b15280527a7f.tar.gz ChibiOS-e8e651a11d611164e9390c40e174b15280527a7f.tar.bz2 ChibiOS-e8e651a11d611164e9390c40e174b15280527a7f.zip |
git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1149 35acf78f-673a-0410-8e92-d51de3d6d3f4
Diffstat (limited to 'src/chmtx.c')
-rw-r--r-- | src/chmtx.c | 299 |
1 files changed, 0 insertions, 299 deletions
diff --git a/src/chmtx.c b/src/chmtx.c deleted file mode 100644 index 5fcb6fd5e..000000000 --- a/src/chmtx.c +++ /dev/null @@ -1,299 +0,0 @@ -/* - ChibiOS/RT - Copyright (C) 2006-2007 Giovanni Di Sirio. - - This file is part of ChibiOS/RT. - - ChibiOS/RT is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 3 of the License, or - (at your option) any later version. - - ChibiOS/RT is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see <http://www.gnu.org/licenses/>. -*/ - -/** - * @file chmtx.c - * @brief Mutexes code. - * @addtogroup Mutexes - * @{ - */ - -#include <ch.h> - -#if CH_USE_MUTEXES - -/** - * @brief Initializes s @p Mutex structure. - * - * @param[out] mp pointer to a @p Mutex structure - * @note This function can be invoked from within an interrupt handler even if - * it is not an I-Class API because it does not touch any critical kernel - * data structure. - */ -void chMtxInit(Mutex *mp) { - - chDbgCheck(mp != NULL, "chMtxInit"); - - queue_init(&mp->m_queue); - mp->m_owner = NULL; -} - -/** - * @brief Locks the specified mutex. - * - * @param[in] mp pointer to the @p Mutex structure - */ -void chMtxLock(Mutex *mp) { - - chSysLock(); - - chMtxLockS(mp); - - chSysUnlock(); -} - -/** - * @brief Locks the specified mutex. - * - * @param[in] mp pointer to the @p Mutex structure - * @note This function must be called within a @p chSysLock() / @p chSysUnlock() - * block. - */ -void chMtxLockS(Mutex *mp) { - - chDbgCheck(mp != NULL, "chMtxLockS"); - - /* the mutex is already locked? */ - if (mp->m_owner != NULL) { - /* - * Priority inheritance protocol; explores the thread-mutex dependencies - * boosting the priority of all the affected threads to equal the priority - * of the running thread requesting the mutex. - */ - Thread *tp = mp->m_owner; - /* { tp is the thread currently owning the mutex } */ - /* the running thread has higher priority than tp? */ - while (tp->p_prio < currp->p_prio) { - /* make priority of thread tp match the running thread's priority */ - tp->p_prio = currp->p_prio; - /* - * The following states need priority queues reordering. - */ - switch (tp->p_state) { - /* thread tp is waiting on a mutex? */ - case PRWTMTX: - /* Requeues tp with its new priority on the mutex wait queue. */ - prio_insert(dequeue(tp), &tp->p_wtmtxp->m_queue); - /* boost the owner of this mutex if needed */ - tp = tp->p_wtmtxp->m_owner; - continue; -#if CH_USE_CONDVARS - case PRWTCOND: - /* Requeues tp with its new priority on the condvar queue. */ - prio_insert(dequeue(tp), &tp->p_wtcondp->c_queue); - break; -#endif -#if CH_USE_SEMAPHORES_PRIORITY - case PRWTSEM: - /* Requeues tp with its new priority on the semaphore queue. */ - prio_insert(dequeue(tp), &tp->p_wtsemp->s_queue); - break; -#endif -#if CH_USE_MESSAGES_PRIORITY - case PRSNDMSG: - /* Requeues tp with its new priority on the server thread queue. */ - prio_insert(dequeue(tp), &tp->p_wtthdp->p_msgqueue); - break; -#endif - /* thread tp is ready? */ - case PRREADY: - /* Requeue tp with its new priority on the ready list. */ - chSchReadyI(dequeue(tp)); - } - break; - } - /* sleep on the mutex */ - prio_insert(currp, &mp->m_queue); - /* thread remembers the mutex where it is waiting on */ - currp->p_wtmtxp = mp; - chSchGoSleepS(PRWTMTX); - chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned"); - } - /* - * The mutex is now inserted in the owned mutexes list. - */ - mp->m_owner = currp; - mp->m_next = currp->p_mtxlist; - currp->p_mtxlist = mp; -} - -/** - * @brief Tries to lock a mutex. - * @details This function does not have any overhead related to - * the priority inheritance mechanism because it does not try to - * enter a sleep state on the mutex. - * - * @param[in] mp pointer to the @p Mutex structure - * @retval TRUE if the mutex was successfully acquired - * @retval FALSE if the lock attempt failed. - */ -bool_t chMtxTryLock(Mutex *mp) { - bool_t b; - - chSysLock(); - - b = chMtxTryLockS(mp); - - chSysUnlock(); - return b; -} - -/** - * @brief Tries to lock a mutex. - * @details This function does not have any overhead related to - * the priority inheritance mechanism because it does not try to - * enter a sleep state on the mutex. - * @param[in] mp pointer to the @p Mutex structure - * @retval TRUE if the mutex was successfully acquired - * @retval FALSE if the lock attempt failed. - * @note This function must be called within a @p chSysLock() / @p chSysUnlock() - * block. - */ -bool_t chMtxTryLockS(Mutex *mp) { - - chDbgCheck(mp != NULL, "chMtxTryLockS"); - - if (mp->m_owner != NULL) - return FALSE; - mp->m_owner = currp; - mp->m_next = currp->p_mtxlist; - currp->p_mtxlist = mp; - return TRUE; -} - -/** - * @brief Unlocks the next owned mutex in reverse lock order. - * - * @return The pointer to the unlocked mutex. - */ -Mutex *chMtxUnlock(void) { - Mutex *ump, *mp; - - chSysLock(); - chDbgAssert(currp->p_mtxlist != NULL, - "chMtxUnlock(), #1", - "owned mutexes list empty"); - chDbgAssert(currp->p_mtxlist->m_owner == currp, - "chMtxUnlock(), #2", - "ownership failure"); - /* remove the top Mutex from the Threads's owned mutexes list */ - ump = currp->p_mtxlist; - currp->p_mtxlist = ump->m_next; - /* mark the Mutex as not owned */ - ump->m_owner = NULL; - /* - * If a thread is waiting on the mutex then the hard part begins. - */ - if (chMtxQueueNotEmptyS(ump)) { - /* get the highest priority thread waiting for the unlocked mutex */ - Thread *tp = fifo_remove(&ump->m_queue); - /* - * Recalculates the optimal thread priority by scanning the owned mutexes list. - */ - tprio_t newprio = currp->p_realprio; - /* iterate mp over all the (other) mutexes the current thread still owns */ - mp = currp->p_mtxlist; - while (mp != NULL) { - /* mutex mp has a higher priority thread pending? */ - if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) - /* boost current thread's priority to waiting thread */ - newprio = mp->m_queue.p_next->p_prio; - mp = mp->m_next; - } - /* (possibly) boost the priority of the current thread */ - currp->p_prio = newprio; - /* awaken the highest priority thread waiting for the unlocked mutex */ - chSchWakeupS(tp, RDY_OK); - } - chSysUnlock(); - return ump; -} - -/** - * @brief Unlocks the next owned mutex in reverse lock order. - * - * @return The pointer to the unlocked mutex. - * @note This function must be called within a @p chSysLock() / @p chSysUnlock() - * block. - * @note This function does not reschedule internally. - */ -Mutex *chMtxUnlockS(void) { - Mutex *ump, *mp; - - chDbgAssert(currp->p_mtxlist != NULL, - "chMtxUnlockS(), #1", - "owned mutexes list empty"); - chDbgAssert(currp->p_mtxlist->m_owner == currp, - "chMtxUnlockS(), #2", - "ownership failure"); - - /* - * Removes the top Mutex from the owned mutexes list and marks it as not owned. - */ - ump = currp->p_mtxlist; - currp->p_mtxlist = ump->m_next; - ump->m_owner = NULL; - /* - * If a thread is waiting on the mutex then the hard part begins. - */ - if (chMtxQueueNotEmptyS(ump)) { - Thread *tp = fifo_remove(&ump->m_queue); - /* - * Recalculates the optimal thread priority by scanning the owned mutexes list. - */ - tprio_t newprio = currp->p_realprio; - mp = currp->p_mtxlist; - while (mp != NULL) { - if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) - newprio = mp->m_queue.p_next->p_prio; - mp = mp->m_next; - } - currp->p_prio = newprio; - chSchReadyI(tp); - } - return ump; -} - -/** - * @brief Unlocks all the mutexes owned by the invoking thread. - * @details This function is <b>MUCH MORE</b> efficient than releasing the - * mutexes one by one and not just because the call overhead, - * this function does not have any overhead related to the priority - * inheritance mechanism. - */ -void chMtxUnlockAll(void) { - - chSysLock(); - if (currp->p_mtxlist != NULL) { - do { - Mutex *mp = currp->p_mtxlist; - currp->p_mtxlist = mp->m_next; - mp->m_owner = NULL; - if (chMtxQueueNotEmptyS(mp)) - chSchReadyI(fifo_remove(&mp->m_queue)); - } while (currp->p_mtxlist != NULL); - currp->p_prio = currp->p_realprio; - chSchRescheduleS(); - } - chSysUnlock(); -} - -#endif /* CH_USE_MUTEXES */ - -/** @} */ |