From 1ea7355d85e316aadfd90468b3e808bb3dc95ee9 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 16 Aug 2009 13:07:24 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1073 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 299 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 299 insertions(+) create mode 100644 os/kernel/src/chmtx.c (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c new file mode 100644 index 000000000..5fcb6fd5e --- /dev/null +++ b/os/kernel/src/chmtx.c @@ -0,0 +1,299 @@ +/* + 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 . +*/ + +/** + * @file chmtx.c + * @brief Mutexes code. + * @addtogroup Mutexes + * @{ + */ + +#include + +#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 MUCH MORE 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 */ + +/** @} */ -- cgit v1.2.3 From 397ccffac55ffd139d0e3e82add83e51413c1347 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 30 Aug 2009 06:59:43 +0000 Subject: Documentation reorganization. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1133 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 5fcb6fd5e..cc3c91e3e 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -20,7 +20,7 @@ /** * @file chmtx.c * @brief Mutexes code. - * @addtogroup Mutexes + * @addtogroup mutexes * @{ */ -- cgit v1.2.3 From 1f2dd43b3ebca18d849527e1be6f93d473298677 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 6 Sep 2009 16:50:07 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1155 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index cc3c91e3e..9e568c782 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -69,7 +69,7 @@ void chMtxLockS(Mutex *mp) { chDbgCheck(mp != NULL, "chMtxLockS"); - /* the mutex is already locked? */ + /* Ia the mutex already locked? */ if (mp->m_owner != NULL) { /* * Priority inheritance protocol; explores the thread-mutex dependencies @@ -77,50 +77,47 @@ void chMtxLockS(Mutex *mp) { * 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? */ + /* {tp is the thread currently owning the mutex} */ + /* Has the running thread higher priority than tp? */ while (tp->p_prio < currp->p_prio) { - /* make priority of thread tp match the running thread's priority */ + /* 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. */ + /* Re-enqueues 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 */ + /* 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. */ + /* Re-enqueues 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. */ + /* Re-enqueues 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. */ + /* Re-enqueues 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. */ + /* Re-enqueues tp with its new priority on the ready list.*/ chSchReadyI(dequeue(tp)); } break; } - /* sleep on the mutex */ + /* 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"); @@ -201,24 +198,24 @@ Mutex *chMtxUnlock(void) { * 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 */ + /* 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 */ + /* 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? */ + /* Has the mutex mp a higher priority thread pending? */ if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) - /* boost current thread's priority to waiting thread */ + /* Boost the recalculated 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 */ + /* Possibly restores the priority of the current thread.*/ currp->p_prio = newprio; - /* awaken the highest priority thread waiting for the unlocked mutex */ + /* Awaken the highest priority thread waiting for the unlocked mutex.*/ chSchWakeupS(tp, RDY_OK); } chSysUnlock(); -- cgit v1.2.3 From bdb7f4ab20bd3daf261ab93dfe733e0ff11dca0f Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 8 Dec 2009 17:37:49 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1397 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 9e568c782..21ec5b997 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -24,7 +24,7 @@ * @{ */ -#include +#include "ch.h" #if CH_USE_MUTEXES -- cgit v1.2.3 From 7bd8164f8ff6ffd0a9458d44e18097582adae201 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 20 Jan 2010 14:39:34 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1532 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 21ec5b997..962356db8 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -86,31 +86,31 @@ void chMtxLockS(Mutex *mp) { * The following states need priority queues reordering. */ switch (tp->p_state) { - case PRWTMTX: + case THD_STATE_WTMTX: /* Re-enqueues tp with its new priority on the mutex wait queue.*/ - prio_insert(dequeue(tp), &tp->p_wtmtxp->m_queue); + prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp); /* Boost the owner of this mutex if needed.*/ - tp = tp->p_wtmtxp->m_owner; + tp = ((Mutex *)tp->p_u.wtobjp)->m_owner; continue; #if CH_USE_CONDVARS - case PRWTCOND: + case THD_STATE_WTCOND: /* Re-enqueues tp with its new priority on the condvar queue.*/ - prio_insert(dequeue(tp), &tp->p_wtcondp->c_queue); + prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp); break; #endif #if CH_USE_SEMAPHORES_PRIORITY - case PRWTSEM: + case THD_STATE_WTSEM: /* Re-enqueues tp with its new priority on the semaphore queue.*/ - prio_insert(dequeue(tp), &tp->p_wtsemp->s_queue); + prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp); break; #endif #if CH_USE_MESSAGES_PRIORITY - case PRSNDMSG: + case THD_STATE_SNDMSG: /* Re-enqueues tp with its new priority on the server thread queue.*/ - prio_insert(dequeue(tp), &tp->p_wtthdp->p_msgqueue); + prio_insert(dequeue(tp), ((Thread *)tp->p_u.wtobjp)->p_msgqueue); break; #endif - case PRREADY: + case THD_STATE_READY: /* Re-enqueues tp with its new priority on the ready list.*/ chSchReadyI(dequeue(tp)); } @@ -118,8 +118,8 @@ void chMtxLockS(Mutex *mp) { } /* Sleep on the mutex.*/ prio_insert(currp, &mp->m_queue); - currp->p_wtmtxp = mp; - chSchGoSleepS(PRWTMTX); + currp->p_u.wtobjp = mp; + chSchGoSleepS(THD_STATE_WTMTX); chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned"); } /* -- cgit v1.2.3 From 14005a2ffefe28adb2ce2cfdad24be782090c089 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 20 Jan 2010 19:37:07 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1533 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 962356db8..d319b9316 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -88,26 +88,26 @@ void chMtxLockS(Mutex *mp) { switch (tp->p_state) { case THD_STATE_WTMTX: /* Re-enqueues tp with its new priority on the mutex wait queue.*/ - prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp); + prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); /* Boost the owner of this mutex if needed.*/ tp = ((Mutex *)tp->p_u.wtobjp)->m_owner; continue; #if CH_USE_CONDVARS case THD_STATE_WTCOND: /* Re-enqueues tp with its new priority on the condvar queue.*/ - prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp); + prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); break; #endif #if CH_USE_SEMAPHORES_PRIORITY case THD_STATE_WTSEM: /* Re-enqueues tp with its new priority on the semaphore queue.*/ - prio_insert(dequeue(tp), (ThreadsQueue *)&tp->p_u.wtobjp); + prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); break; #endif #if CH_USE_MESSAGES_PRIORITY case THD_STATE_SNDMSG: /* Re-enqueues tp with its new priority on the server thread queue.*/ - prio_insert(dequeue(tp), ((Thread *)tp->p_u.wtobjp)->p_msgqueue); + prio_insert(dequeue(tp), &((Thread *)tp->p_u.wtobjp)->p_msgqueue); break; #endif case THD_STATE_READY: -- cgit v1.2.3 From 85016e2a2622a64719e8baa58dd493b6b99aa793 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 20 Jan 2010 20:45:56 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1534 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index d319b9316..c14db4ad0 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -77,37 +77,30 @@ void chMtxLockS(Mutex *mp) { * of the running thread requesting the mutex. */ Thread *tp = mp->m_owner; - /* {tp is the thread currently owning the mutex} */ - /* Has the running thread higher priority than tp? */ + /* Does the running thread have higher priority than the mutex + * ownning thread? */ 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. - */ + /* The following states need priority queues reordering.*/ switch (tp->p_state) { case THD_STATE_WTMTX: - /* Re-enqueues tp with its new priority on the mutex wait queue.*/ + /* Re-enqueues the mutex owner with its new priority.*/ prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); - /* Boost the owner of this mutex if needed.*/ tp = ((Mutex *)tp->p_u.wtobjp)->m_owner; continue; +#if CH_USE_CONDVARS | CH_USE_SEMAPHORES_PRIORITY | CH_USE_MESSAGES_PRIORITY #if CH_USE_CONDVARS case THD_STATE_WTCOND: - /* Re-enqueues tp with its new priority on the condvar queue.*/ - prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); - break; #endif #if CH_USE_SEMAPHORES_PRIORITY case THD_STATE_WTSEM: - /* Re-enqueues tp with its new priority on the semaphore queue.*/ - prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); - break; #endif #if CH_USE_MESSAGES_PRIORITY case THD_STATE_SNDMSG: - /* Re-enqueues tp with its new priority on the server thread queue.*/ - prio_insert(dequeue(tp), &((Thread *)tp->p_u.wtobjp)->p_msgqueue); +#endif + /* Re-enqueues tp with its new priority on the queue.*/ + prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); break; #endif case THD_STATE_READY: -- cgit v1.2.3 From 6ce39015268cb3a30adc9890a312be39857e1464 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 21 Jan 2010 17:25:57 +0000 Subject: Mutexes optimizations. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1536 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 118 ++++++++++++++++++++++++-------------------------- 1 file changed, 56 insertions(+), 62 deletions(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index c14db4ad0..9d66022c2 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -66,22 +66,21 @@ void chMtxLock(Mutex *mp) { * block. */ void chMtxLockS(Mutex *mp) { + Thread *ctp = currp; chDbgCheck(mp != NULL, "chMtxLockS"); /* Ia the mutex 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. - */ + /* 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; /* Does the running thread have higher priority than the mutex - * ownning thread? */ - while (tp->p_prio < currp->p_prio) { + ownning thread? */ + while (tp->p_prio < ctp->p_prio) { /* Make priority of thread tp match the running thread's priority.*/ - tp->p_prio = currp->p_prio; + tp->p_prio = ctp->p_prio; /* The following states need priority queues reordering.*/ switch (tp->p_state) { case THD_STATE_WTMTX: @@ -110,17 +109,15 @@ void chMtxLockS(Mutex *mp) { break; } /* Sleep on the mutex.*/ - prio_insert(currp, &mp->m_queue); - currp->p_u.wtobjp = 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"); } - /* - * The mutex is now inserted in the owned mutexes list. - */ - mp->m_owner = currp; - mp->m_next = currp->p_mtxlist; - currp->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; } /** @@ -173,43 +170,40 @@ bool_t chMtxTryLockS(Mutex *mp) { * @return The pointer to the unlocked mutex. */ Mutex *chMtxUnlock(void) { + Thread *ctp = currp; Mutex *ump, *mp; chSysLock(); - chDbgAssert(currp->p_mtxlist != NULL, + chDbgAssert(ctp->p_mtxlist != NULL, "chMtxUnlock(), #1", "owned mutexes list empty"); - chDbgAssert(currp->p_mtxlist->m_owner == currp, + chDbgAssert(ctp->p_mtxlist->m_owner == ctp, "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 */ + /* Removes the top Mutex from the Threads's owned mutexes list and matk it + 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 hard part begins. - */ + /* If a thread is waiting on the mutex then the fun 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; + /* Recalculates the optimal thread priority by scanning the owned + mutexes list.*/ + tprio_t newprio = ctp->p_realprio; + mp = ctp->p_mtxlist; while (mp != NULL) { - /* Has the mutex mp a higher priority thread pending? */ + /* If the highest priority thread waiting in the mutexes list has a + greater priority than the current thread base priority then the final + priority will have at least that priority.*/ if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) - /* Boost the recalculated thread's priority to waiting thread.*/ newprio = mp->m_queue.p_next->p_prio; mp = mp->m_next; } - /* Possibly restores the priority of the current thread.*/ - currp->p_prio = newprio; - /* Awaken the highest priority thread waiting for the unlocked mutex.*/ - chSchWakeupS(tp, RDY_OK); + /* 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); } chSysUnlock(); return ump; @@ -224,38 +218,37 @@ Mutex *chMtxUnlock(void) { * @note This function does not reschedule internally. */ Mutex *chMtxUnlockS(void) { + Thread *ctp = currp; Mutex *ump, *mp; - chDbgAssert(currp->p_mtxlist != NULL, + chDbgAssert(ctp->p_mtxlist != NULL, "chMtxUnlockS(), #1", "owned mutexes list empty"); - chDbgAssert(currp->p_mtxlist->m_owner == currp, + chDbgAssert(ctp->p_mtxlist->m_owner == ctp, "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; + /* Removes the top Mutex from the owned mutexes list and marks it 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 hard part begins. - */ + /* If a thread is waiting on the mutex then the fun 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; + /* Recalculates the optimal thread priority by scanning the owned + mutexes list.*/ + tprio_t newprio = ctp->p_realprio; + mp = ctp->p_mtxlist; while (mp != NULL) { + /* If the highest priority thread waiting in the mutexes list has a + greater priority than the current thread base priority then the final + priority will have at least that priority.*/ 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); + ctp->p_prio = newprio; + chSchReadyI(fifo_remove(&ump->m_queue)); } return ump; } @@ -268,17 +261,18 @@ Mutex *chMtxUnlockS(void) { * inheritance mechanism. */ void chMtxUnlockAll(void) { + Thread *ctp = currp; chSysLock(); - if (currp->p_mtxlist != NULL) { + if (ctp->p_mtxlist != NULL) { do { - Mutex *mp = currp->p_mtxlist; - currp->p_mtxlist = mp->m_next; + Mutex *mp = ctp->p_mtxlist; + ctp->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; + } while (ctp->p_mtxlist != NULL); + ctp->p_prio = ctp->p_realprio; chSchRescheduleS(); } chSysUnlock(); -- cgit v1.2.3 From f17db1931e95f5ebb42f557b6eead2bf1320db5a Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 6 Feb 2010 10:55:53 +0000 Subject: Reformatted doxygen tags into the kernel sources to make them more readable. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1567 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 55 ++++++++++++++++++++++----------------------------- 1 file changed, 24 insertions(+), 31 deletions(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 9d66022c2..d5335c0aa 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -18,8 +18,9 @@ */ /** - * @file chmtx.c - * @brief Mutexes code. + * @file chmtx.c + * @brief Mutexes code. + * * @addtogroup mutexes * @{ */ @@ -29,12 +30,9 @@ #if CH_USE_MUTEXES /** - * @brief Initializes s @p Mutex structure. + * @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. + * @param[out] mp pointer to a @p Mutex structure */ void chMtxInit(Mutex *mp) { @@ -45,9 +43,9 @@ void chMtxInit(Mutex *mp) { } /** - * @brief Locks the specified mutex. + * @brief Locks the specified mutex. * - * @param[in] mp pointer to the @p Mutex structure + * @param[in] mp pointer to the @p Mutex structure */ void chMtxLock(Mutex *mp) { @@ -59,11 +57,9 @@ void chMtxLock(Mutex *mp) { } /** - * @brief Locks the specified mutex. + * @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. + * @param[in] mp pointer to the @p Mutex structure */ void chMtxLockS(Mutex *mp) { Thread *ctp = currp; @@ -121,14 +117,14 @@ void chMtxLockS(Mutex *mp) { } /** - * @brief Tries to lock a mutex. + * @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. + * @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; @@ -142,15 +138,14 @@ bool_t chMtxTryLock(Mutex *mp) { } /** - * @brief Tries to lock a mutex. + * @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. + * + * @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 chMtxTryLockS(Mutex *mp) { @@ -165,9 +160,9 @@ bool_t chMtxTryLockS(Mutex *mp) { } /** - * @brief Unlocks the next owned mutex in reverse lock order. + * @brief Unlocks the next owned mutex in reverse lock order. * - * @return The pointer to the unlocked mutex. + * @return The pointer to the unlocked mutex. */ Mutex *chMtxUnlock(void) { Thread *ctp = currp; @@ -210,12 +205,10 @@ Mutex *chMtxUnlock(void) { } /** - * @brief Unlocks the next owned mutex in reverse lock order. + * @brief Unlocks the next owned mutex in reverse lock order. + * @note This function does not reschedule internally. * - * @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. + * @return The pointer to the unlocked mutex. */ Mutex *chMtxUnlockS(void) { Thread *ctp = currp; @@ -254,7 +247,7 @@ Mutex *chMtxUnlockS(void) { } /** - * @brief Unlocks all the mutexes owned by the invoking thread. + * @brief Unlocks all the mutexes owned by the invoking thread. * @details This function is MUCH MORE 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 -- cgit v1.2.3 From 157b6f9695e7f72f2d54b231c19cb4045710ed01 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sun, 21 Feb 2010 07:24:53 +0000 Subject: Updated license dates. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1646 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 552 +++++++++++++++++++++++++------------------------- 1 file changed, 276 insertions(+), 276 deletions(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index d5335c0aa..336df8a6e 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -1,276 +1,276 @@ -/* - 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 . -*/ - -/** - * @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 - */ -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 - */ -void chMtxLockS(Mutex *mp) { - Thread *ctp = currp; - - chDbgCheck(mp != NULL, "chMtxLockS"); - - /* Ia the mutex 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; - /* Does the running thread have higher priority than the mutex - ownning thread? */ - while (tp->p_prio < ctp->p_prio) { - /* Make priority of thread tp match the running thread's priority.*/ - tp->p_prio = ctp->p_prio; - /* The following states need priority queues reordering.*/ - switch (tp->p_state) { - case THD_STATE_WTMTX: - /* Re-enqueues the mutex owner with its new priority.*/ - prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); - tp = ((Mutex *)tp->p_u.wtobjp)->m_owner; - continue; -#if CH_USE_CONDVARS | CH_USE_SEMAPHORES_PRIORITY | CH_USE_MESSAGES_PRIORITY -#if CH_USE_CONDVARS - case THD_STATE_WTCOND: -#endif -#if CH_USE_SEMAPHORES_PRIORITY - case THD_STATE_WTSEM: -#endif -#if CH_USE_MESSAGES_PRIORITY - case THD_STATE_SNDMSG: -#endif - /* Re-enqueues tp with its new priority on the queue.*/ - prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); - break; -#endif - case THD_STATE_READY: - /* Re-enqueues tp with its new priority on the ready list.*/ - chSchReadyI(dequeue(tp)); - } - break; - } - /* Sleep on the mutex.*/ - prio_insert(ctp, &mp->m_queue); - ctp->p_u.wtobjp = mp; - chSchGoSleepS(THD_STATE_WTMTX); - chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned"); - } - /* The mutex is now inserted in the owned mutexes list.*/ - mp->m_owner = ctp; - mp->m_next = ctp->p_mtxlist; - ctp->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. - */ -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) { - Thread *ctp = currp; - Mutex *ump, *mp; - - chSysLock(); - chDbgAssert(ctp->p_mtxlist != NULL, - "chMtxUnlock(), #1", - "owned mutexes list empty"); - chDbgAssert(ctp->p_mtxlist->m_owner == ctp, - "chMtxUnlock(), #2", - "ownership failure"); - /* Removes the top Mutex from the Threads's owned mutexes list and matk it - 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)) { - /* Recalculates the optimal thread priority by scanning the owned - mutexes list.*/ - tprio_t newprio = ctp->p_realprio; - mp = ctp->p_mtxlist; - while (mp != NULL) { - /* If the highest priority thread waiting in the mutexes list has a - greater priority than the current thread base priority then the final - priority will have at least that priority.*/ - if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) - newprio = mp->m_queue.p_next->p_prio; - mp = mp->m_next; - } - /* 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); - } - chSysUnlock(); - return ump; -} - -/** - * @brief Unlocks the next owned mutex in reverse lock order. - * @note This function does not reschedule internally. - * - * @return The pointer to the unlocked mutex. - */ -Mutex *chMtxUnlockS(void) { - Thread *ctp = currp; - Mutex *ump, *mp; - - chDbgAssert(ctp->p_mtxlist != NULL, - "chMtxUnlockS(), #1", - "owned mutexes list empty"); - chDbgAssert(ctp->p_mtxlist->m_owner == ctp, - "chMtxUnlockS(), #2", - "ownership failure"); - - /* Removes the top Mutex from the owned mutexes list and marks it 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)) { - /* Recalculates the optimal thread priority by scanning the owned - mutexes list.*/ - tprio_t newprio = ctp->p_realprio; - mp = ctp->p_mtxlist; - while (mp != NULL) { - /* If the highest priority thread waiting in the mutexes list has a - greater priority than the current thread base priority then the final - priority will have at least that priority.*/ - if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) - newprio = mp->m_queue.p_next->p_prio; - mp = mp->m_next; - } - ctp->p_prio = newprio; - chSchReadyI(fifo_remove(&ump->m_queue)); - } - return ump; -} - -/** - * @brief Unlocks all the mutexes owned by the invoking thread. - * @details This function is MUCH MORE 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) { - Thread *ctp = currp; - - 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)); - } while (ctp->p_mtxlist != NULL); - ctp->p_prio = ctp->p_realprio; - chSchRescheduleS(); - } - chSysUnlock(); -} - -#endif /* CH_USE_MUTEXES */ - -/** @} */ +/* + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 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 . +*/ + +/** + * @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 + */ +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 + */ +void chMtxLockS(Mutex *mp) { + Thread *ctp = currp; + + chDbgCheck(mp != NULL, "chMtxLockS"); + + /* Ia the mutex 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; + /* Does the running thread have higher priority than the mutex + ownning thread? */ + while (tp->p_prio < ctp->p_prio) { + /* Make priority of thread tp match the running thread's priority.*/ + tp->p_prio = ctp->p_prio; + /* The following states need priority queues reordering.*/ + switch (tp->p_state) { + case THD_STATE_WTMTX: + /* Re-enqueues the mutex owner with its new priority.*/ + prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); + tp = ((Mutex *)tp->p_u.wtobjp)->m_owner; + continue; +#if CH_USE_CONDVARS | CH_USE_SEMAPHORES_PRIORITY | CH_USE_MESSAGES_PRIORITY +#if CH_USE_CONDVARS + case THD_STATE_WTCOND: +#endif +#if CH_USE_SEMAPHORES_PRIORITY + case THD_STATE_WTSEM: +#endif +#if CH_USE_MESSAGES_PRIORITY + case THD_STATE_SNDMSG: +#endif + /* Re-enqueues tp with its new priority on the queue.*/ + prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); + break; +#endif + case THD_STATE_READY: + /* Re-enqueues tp with its new priority on the ready list.*/ + chSchReadyI(dequeue(tp)); + } + break; + } + /* Sleep on the mutex.*/ + prio_insert(ctp, &mp->m_queue); + ctp->p_u.wtobjp = mp; + chSchGoSleepS(THD_STATE_WTMTX); + chDbgAssert(mp->m_owner == NULL, "chMtxLockS(), #1", "still owned"); + } + /* The mutex is now inserted in the owned mutexes list.*/ + mp->m_owner = ctp; + mp->m_next = ctp->p_mtxlist; + ctp->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. + */ +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) { + Thread *ctp = currp; + Mutex *ump, *mp; + + chSysLock(); + chDbgAssert(ctp->p_mtxlist != NULL, + "chMtxUnlock(), #1", + "owned mutexes list empty"); + chDbgAssert(ctp->p_mtxlist->m_owner == ctp, + "chMtxUnlock(), #2", + "ownership failure"); + /* Removes the top Mutex from the Threads's owned mutexes list and matk it + 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)) { + /* Recalculates the optimal thread priority by scanning the owned + mutexes list.*/ + tprio_t newprio = ctp->p_realprio; + mp = ctp->p_mtxlist; + while (mp != NULL) { + /* If the highest priority thread waiting in the mutexes list has a + greater priority than the current thread base priority then the final + priority will have at least that priority.*/ + if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) + newprio = mp->m_queue.p_next->p_prio; + mp = mp->m_next; + } + /* 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); + } + chSysUnlock(); + return ump; +} + +/** + * @brief Unlocks the next owned mutex in reverse lock order. + * @note This function does not reschedule internally. + * + * @return The pointer to the unlocked mutex. + */ +Mutex *chMtxUnlockS(void) { + Thread *ctp = currp; + Mutex *ump, *mp; + + chDbgAssert(ctp->p_mtxlist != NULL, + "chMtxUnlockS(), #1", + "owned mutexes list empty"); + chDbgAssert(ctp->p_mtxlist->m_owner == ctp, + "chMtxUnlockS(), #2", + "ownership failure"); + + /* Removes the top Mutex from the owned mutexes list and marks it 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)) { + /* Recalculates the optimal thread priority by scanning the owned + mutexes list.*/ + tprio_t newprio = ctp->p_realprio; + mp = ctp->p_mtxlist; + while (mp != NULL) { + /* If the highest priority thread waiting in the mutexes list has a + greater priority than the current thread base priority then the final + priority will have at least that priority.*/ + if (chMtxQueueNotEmptyS(mp) && (mp->m_queue.p_next->p_prio > newprio)) + newprio = mp->m_queue.p_next->p_prio; + mp = mp->m_next; + } + ctp->p_prio = newprio; + chSchReadyI(fifo_remove(&ump->m_queue)); + } + return ump; +} + +/** + * @brief Unlocks all the mutexes owned by the invoking thread. + * @details This function is MUCH MORE 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) { + Thread *ctp = currp; + + 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)); + } while (ctp->p_mtxlist != NULL); + ctp->p_prio = ctp->p_realprio; + chSchRescheduleS(); + } + chSysUnlock(); +} + +#endif /* CH_USE_MUTEXES */ + +/** @} */ -- cgit v1.2.3 From ad3d21e81592481539a56e93234f5bf1fa2c0504 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 16 Mar 2010 19:36:21 +0000 Subject: Documentation reorganization. Moved the description from kernel.dox into the source code for ease of editing and reference. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1746 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 336df8a6e..cc179eb20 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -22,6 +22,43 @@ * @brief Mutexes code. * * @addtogroup mutexes + * @details Mutexes related APIs and services. + * + *

Operation mode

+ * A mutex is a threads synchronization object that can be in two + * distinct states: + * - Not owned. + * - Owned by a thread. + * . + * Some operations are defined on mutexes: + * - Lock: The mutex is checked, if the mutex is not owned by + * some other thread then it is associated to the locking thread + * else the thread is queued on the mutex in a list ordered by + * priority. + * - Unlock: The mutex is released by the owner and the highest + * priority thread waiting in the queue, if any, is resumed and made + * owner of the mutex. + * . + * In order to use the Mutexes APIs the @p CH_USE_MUTEXES option must + * be enabled in @p chconf.h. + *

Constraints

+ * In ChibiOS/RT the Unlock operations are always performed in + * lock-reverse order. The unlock API does not even have a parameter, + * the mutex to unlock is selected from an internal, per-thread, stack + * of owned mutexes. This both improves the performance and is + * required for an efficient implementation of the priority + * inheritance mechanism. + * + *

The priority inversion problem

+ * The mutexes in ChibiOS/RT implements the full priority + * inheritance mechanism in order handle the priority inversion + * problem.
+ * When a thread is queued on a mutex, any thread, directly or + * indirectly, holding the mutex gains the same priority of the + * waiting thread (if their priority was not already equal or higher). + * The mechanism works with any number of nested mutexes and any + * number of involved threads. The algorithm complexity (worst case) + * is N with N equal to the number of nested mutexes. * @{ */ -- cgit v1.2.3 From 7ae3e3227ee895c3ed5ac3358411b07276c7838e Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 17 Mar 2010 16:24:43 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@1748 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index cc179eb20..c3076163a 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -30,7 +30,7 @@ * - Not owned. * - Owned by a thread. * . - * Some operations are defined on mutexes: + * Operations defined for mutexes: * - Lock: The mutex is checked, if the mutex is not owned by * some other thread then it is associated to the locking thread * else the thread is queued on the mutex in a list ordered by -- cgit v1.2.3 From fe292af06d48b5d42b0dd8fcb594b5a9c4668144 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 21 Jun 2010 16:52:51 +0000 Subject: Fixed bug 3019099. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2027 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 58 ++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 15 deletions(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index c3076163a..88b6f4ecd 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -145,12 +145,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; } /** @@ -216,9 +221,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; @@ -234,9 +240,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; } @@ -262,9 +275,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; @@ -278,8 +292,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; } @@ -296,11 +318,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(); -- cgit v1.2.3 From 1a0fead19b521501ec5b7ff7532d6a7b435fdaa6 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 3 Sep 2010 18:23:37 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2162 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 88b6f4ecd..93943bba0 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -136,7 +136,11 @@ void chMtxLockS(Mutex *mp) { break; #endif case THD_STATE_READY: - /* Re-enqueues tp with its new priority on the ready list.*/ +#if CH_DBG_ENABLE_ASSERTS + /* Prevents an assertion in chSchReadyI().*/ + tp->p_state = THD_STATE_CURRENT; +#endif + /* Re-enqueues tp with its new priority on the ready list.*/ chSchReadyI(dequeue(tp)); } break; -- cgit v1.2.3 From 9ffea7e261ec4016d788abbbf7c4a6d3a78e0a04 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 18 Sep 2010 06:48:56 +0000 Subject: Documentation improvements, renamed some event APIs. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2179 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 61 +++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 17 deletions(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 93943bba0..9698d3cd8 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -27,8 +27,8 @@ *

Operation mode

* A mutex is a threads synchronization object that can be in two * distinct states: - * - Not owned. - * - Owned by a thread. + * - Not owned (unlocked). + * - Owned by a thread (locked). * . * Operations defined for mutexes: * - Lock: The mutex is checked, if the mutex is not owned by @@ -39,8 +39,6 @@ * priority thread waiting in the queue, if any, is resumed and made * owner of the mutex. * . - * In order to use the Mutexes APIs the @p CH_USE_MUTEXES option must - * be enabled in @p chconf.h. *

Constraints

* In ChibiOS/RT the Unlock operations are always performed in * lock-reverse order. The unlock API does not even have a parameter, @@ -59,15 +57,21 @@ * The mechanism works with any number of nested mutexes and any * number of involved threads. The algorithm complexity (worst case) * is N with N equal to the number of nested mutexes. + * @pre In order to use the mutex APIs the @p CH_USE_MUTEXES option + * must be enabled in @p chconf.h. + * @post Enabling mutexes requires 5-12 (depending on the architecture) + * extra bytes in the @p Thread structure. * @{ */ #include "ch.h" -#if CH_USE_MUTEXES +#if CH_USE_MUTEXES || defined(__DOXYGEN__) /** * @brief Initializes s @p Mutex structure. + * @note This function can be invoked before the kernel is initialized + * because it just prepares a @p Mutex structure. * * @param[out] mp pointer to a @p Mutex structure */ @@ -81,6 +85,8 @@ void chMtxInit(Mutex *mp) { /** * @brief Locks the specified mutex. + * @post The mutex is locked and inserted in the per-thread stack of owned + * mutexes. * * @param[in] mp pointer to the @p Mutex structure */ @@ -95,6 +101,8 @@ void chMtxLock(Mutex *mp) { /** * @brief Locks the specified mutex. + * @post The mutex is locked and inserted in the per-thread stack of owned + * mutexes. * * @param[in] mp pointer to the @p Mutex structure */ @@ -164,12 +172,17 @@ void chMtxLockS(Mutex *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. + * @details This function attempts to lock a mutex, if the mutex is already + * locked by another thread then the function exits without waiting. + * @post The mutex is locked and inserted in the per-thread stack of owned + * mutexes. + * @note This function does not have any overhead related to the + * priority inheritance mechanism because it does not try to + * enter a sleep state. * * @param[in] mp pointer to the @p Mutex structure - * @retval TRUE if the mutex was successfully acquired + * @return The operation status. + * @retval TRUE if the mutex has been successfully acquired * @retval FALSE if the lock attempt failed. */ bool_t chMtxTryLock(Mutex *mp) { @@ -185,12 +198,17 @@ bool_t chMtxTryLock(Mutex *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. + * @details This function attempts to lock a mutex, if the mutex is already + * taken by another thread then the function exits without waiting. + * @post The mutex is locked and inserted in the per-thread stack of owned + * mutexes. + * @note This function does not have any overhead related to the + * priority inheritance mechanism because it does not try to + * enter a sleep state. * * @param[in] mp pointer to the @p Mutex structure - * @retval TRUE if the mutex was successfully acquired + * @return The operation status. + * @retval TRUE if the mutex has been successfully acquired * @retval FALSE if the lock attempt failed. */ bool_t chMtxTryLockS(Mutex *mp) { @@ -207,8 +225,11 @@ bool_t chMtxTryLockS(Mutex *mp) { /** * @brief Unlocks the next owned mutex in reverse lock order. + * @pre The invoking thread must have at least one owned mutex. + * @post The mutex is unlocked and removed from the per-thread stack of + * owned mutexes. * - * @return The pointer to the unlocked mutex. + * @return A pointer to the unlocked mutex. */ Mutex *chMtxUnlock(void) { Thread *ctp = currp; @@ -260,9 +281,13 @@ Mutex *chMtxUnlock(void) { /** * @brief Unlocks the next owned mutex in reverse lock order. - * @note This function does not reschedule internally. + * @pre The invoking thread must have at least one owned mutex. + * @post The mutex is unlocked and removed from the per-thread stack of + * owned mutexes. + * @post This function does not reschedule so a call to a rescheduling + * function must be performed before unlocking the kernel. * - * @return The pointer to the unlocked mutex. + * @return A pointer to the unlocked mutex. */ Mutex *chMtxUnlockS(void) { Thread *ctp = currp; @@ -311,7 +336,9 @@ Mutex *chMtxUnlockS(void) { /** * @brief Unlocks all the mutexes owned by the invoking thread. - * @details This function is MUCH MORE efficient than releasing the + * @post The stack of owned mutexes is emptied and all the found + * mutexes are unlocked. + * @note This function is MUCH MORE 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. -- cgit v1.2.3 From 07351222e6d0b6b3dcd4f50ecb18bc09e7402d1c Mon Sep 17 00:00:00 2001 From: gdisirio Date: Tue, 21 Sep 2010 10:22:06 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2184 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 9698d3cd8..b84c4d57e 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -70,10 +70,10 @@ /** * @brief Initializes s @p Mutex structure. - * @note This function can be invoked before the kernel is initialized - * because it just prepares a @p Mutex structure. * * @param[out] mp pointer to a @p Mutex structure + * + * @init */ void chMtxInit(Mutex *mp) { @@ -89,6 +89,8 @@ void chMtxInit(Mutex *mp) { * mutexes. * * @param[in] mp pointer to the @p Mutex structure + * + * @api */ void chMtxLock(Mutex *mp) { @@ -105,6 +107,8 @@ void chMtxLock(Mutex *mp) { * mutexes. * * @param[in] mp pointer to the @p Mutex structure + * + * @sclass */ void chMtxLockS(Mutex *mp) { Thread *ctp = currp; @@ -184,6 +188,8 @@ void chMtxLockS(Mutex *mp) { * @return The operation status. * @retval TRUE if the mutex has been successfully acquired * @retval FALSE if the lock attempt failed. + * + * @api */ bool_t chMtxTryLock(Mutex *mp) { bool_t b; @@ -210,6 +216,8 @@ bool_t chMtxTryLock(Mutex *mp) { * @return The operation status. * @retval TRUE if the mutex has been successfully acquired * @retval FALSE if the lock attempt failed. + * + * @sclass */ bool_t chMtxTryLockS(Mutex *mp) { @@ -230,6 +238,8 @@ bool_t chMtxTryLockS(Mutex *mp) { * owned mutexes. * * @return A pointer to the unlocked mutex. + * + * @api */ Mutex *chMtxUnlock(void) { Thread *ctp = currp; @@ -288,6 +298,8 @@ Mutex *chMtxUnlock(void) { * function must be performed before unlocking the kernel. * * @return A pointer to the unlocked mutex. + * + * @sclass */ Mutex *chMtxUnlockS(void) { Thread *ctp = currp; @@ -342,6 +354,8 @@ Mutex *chMtxUnlockS(void) { * mutexes one by one and not just because the call overhead, * this function does not have any overhead related to the priority * inheritance mechanism. + * + * @api */ void chMtxUnlockAll(void) { Thread *ctp = currp; -- cgit v1.2.3 From 6f6e1a6401eda000dce198150937c7919b4c9855 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 23 Feb 2011 18:59:39 +0000 Subject: Improved messages subsystem. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2759 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index b84c4d57e..826ef27fe 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -141,7 +141,7 @@ void chMtxLockS(Mutex *mp) { case THD_STATE_WTSEM: #endif #if CH_USE_MESSAGES_PRIORITY - case THD_STATE_SNDMSG: + case THD_STATE_SNDMSGQ: #endif /* Re-enqueues tp with its new priority on the queue.*/ prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); -- cgit v1.2.3 From e7e79a6ccb4f3e320b2b8b7bad1b14d65218641d Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 18 Mar 2011 18:38:08 +0000 Subject: License updated. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2827 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 826ef27fe..af2b7f347 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -1,5 +1,6 @@ /* - ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010 Giovanni Di Sirio. + ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, + 2011 Giovanni Di Sirio. This file is part of ChibiOS/RT. -- cgit v1.2.3 From 807c5f1882224c2afd471a44889b83c2adf80589 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 18 May 2011 17:54:55 +0000 Subject: Fixed bug 3303908. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@2972 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index af2b7f347..df71d1cc6 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -134,14 +134,16 @@ void chMtxLockS(Mutex *mp) { prio_insert(dequeue(tp), (ThreadsQueue *)tp->p_u.wtobjp); tp = ((Mutex *)tp->p_u.wtobjp)->m_owner; continue; -#if CH_USE_CONDVARS | CH_USE_SEMAPHORES_PRIORITY | CH_USE_MESSAGES_PRIORITY +#if CH_USE_CONDVARS | \ + (CH_USE_SEMAPHORES && CH_USE_SEMAPHORES_PRIORITY) | \ + (CH_USE_MESSAGES && CH_USE_MESSAGES_PRIORITY) #if CH_USE_CONDVARS case THD_STATE_WTCOND: #endif -#if CH_USE_SEMAPHORES_PRIORITY +#if CH_USE_SEMAPHORES && CH_USE_SEMAPHORES_PRIORITY case THD_STATE_WTSEM: #endif -#if CH_USE_MESSAGES_PRIORITY +#if CH_USE_MESSAGES && CH_USE_MESSAGES_PRIORITY case THD_STATE_SNDMSGQ: #endif /* Re-enqueues tp with its new priority on the queue.*/ -- cgit v1.2.3 From b9933c2089f5f0cd93738ae9081c45fcf3df54b7 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Thu, 11 Aug 2011 17:51:37 +0000 Subject: Implemented system state checker debug option, remove the option CH_USE_NESTED_LOCKS. Documentation improvements and fixes. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3221 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 1 + 1 file changed, 1 insertion(+) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index df71d1cc6..21b92e388 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -157,6 +157,7 @@ void chMtxLockS(Mutex *mp) { #endif /* Re-enqueues tp with its new priority on the ready list.*/ chSchReadyI(dequeue(tp)); + break; } break; } -- cgit v1.2.3 From 43752ee8d132fc57028a9ff15156c5bfcd81c013 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Fri, 12 Aug 2011 11:10:19 +0000 Subject: Extended state check to all kernel I-class and s-class APIs, corrected some test cases where call protocol rules were not strictly observerd. No the whole test suite pass with the state checker enabled. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3223 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 21b92e388..7d5bbe15e 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -114,6 +114,7 @@ void chMtxLock(Mutex *mp) { void chMtxLockS(Mutex *mp) { Thread *ctp = currp; + chDbgCheckClassS(); chDbgCheck(mp != NULL, "chMtxLockS"); /* Ia the mutex already locked? */ @@ -225,6 +226,7 @@ bool_t chMtxTryLock(Mutex *mp) { */ bool_t chMtxTryLockS(Mutex *mp) { + chDbgCheckClassS(); chDbgCheck(mp != NULL, "chMtxTryLockS"); if (mp->m_owner != NULL) @@ -309,6 +311,7 @@ Mutex *chMtxUnlockS(void) { Thread *ctp = currp; Mutex *ump, *mp; + chDbgCheckClassS(); chDbgAssert(ctp->p_mtxlist != NULL, "chMtxUnlockS(), #1", "owned mutexes list empty"); -- cgit v1.2.3 From de5dcbba856524599a8f06d3a9bdbf1b01db44c2 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 21 Jan 2012 14:29:42 +0000 Subject: License text updated with new year. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@3846 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 7d5bbe15e..975a63094 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011 Giovanni Di Sirio. + 2011,2012 Giovanni Di Sirio. This file is part of ChibiOS/RT. -- cgit v1.2.3 From f5a3976c393fffdc95627f27d4c49136fa9ec8ca Mon Sep 17 00:00:00 2001 From: gdisirio Date: Mon, 26 Mar 2012 09:13:37 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4055 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 975a63094..20a4700fe 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -117,14 +117,14 @@ void chMtxLockS(Mutex *mp) { chDbgCheckClassS(); chDbgCheck(mp != NULL, "chMtxLockS"); - /* Ia the mutex already locked? */ + /* Is the mutex 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; /* Does the running thread have higher priority than the mutex - ownning thread? */ + owning thread? */ while (tp->p_prio < ctp->p_prio) { /* Make priority of thread tp match the running thread's priority.*/ tp->p_prio = ctp->p_prio; @@ -258,7 +258,7 @@ Mutex *chMtxUnlock(void) { chDbgAssert(ctp->p_mtxlist->m_owner == ctp, "chMtxUnlock(), #2", "ownership failure"); - /* Removes the top Mutex from the Threads's owned mutexes list and matk it + /* Removes the top Mutex from the Thread's owned mutexes list and matk it as not owned.*/ ump = ctp->p_mtxlist; ctp->p_mtxlist = ump->m_next; -- cgit v1.2.3 From 814b642a0ced73a71ceb3b548c2c570e8631dd58 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Wed, 18 Apr 2012 16:40:15 +0000 Subject: git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@4112 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 20a4700fe..6e32ca439 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -258,7 +258,7 @@ Mutex *chMtxUnlock(void) { chDbgAssert(ctp->p_mtxlist->m_owner == ctp, "chMtxUnlock(), #2", "ownership failure"); - /* Removes the top Mutex from the Thread's owned mutexes list and matk it + /* Removes the top Mutex from the Thread's owned mutexes list and marks it as not owned.*/ ump = ctp->p_mtxlist; ctp->p_mtxlist = ump->m_next; -- cgit v1.2.3 From 184a71345c6a36a9a8664eda8fbcc3ea728267a8 Mon Sep 17 00:00:00 2001 From: gdisirio Date: Sat, 2 Feb 2013 10:58:09 +0000 Subject: Updated license years. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@5102 35acf78f-673a-0410-8e92-d51de3d6d3f4 --- os/kernel/src/chmtx.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'os/kernel/src/chmtx.c') diff --git a/os/kernel/src/chmtx.c b/os/kernel/src/chmtx.c index 6e32ca439..84d7e53a6 100644 --- a/os/kernel/src/chmtx.c +++ b/os/kernel/src/chmtx.c @@ -1,6 +1,6 @@ /* ChibiOS/RT - Copyright (C) 2006,2007,2008,2009,2010, - 2011,2012 Giovanni Di Sirio. + 2011,2012,2013 Giovanni Di Sirio. This file is part of ChibiOS/RT. -- cgit v1.2.3