/// Release Mutex list when owner Thread terminates. /// \param[in] mutex mutex object. /// \return 1 - success, 0 - failure. void osRtxMutexOwnerRelease (os_mutex_t *mutex_list) { os_mutex_t *mutex; os_thread_t *thread; mutex = mutex_list; while (mutex) { mutex_list = mutex->owner_next; // Check if Mutex is Robust if (mutex->attr & osMutexRobust) { // Clear Lock counter mutex->lock = 0U; EvrRtxMutexReleased(mutex, 0U); // Check if Thread is waiting for a Mutex if (mutex->thread_list != NULL) { // Wakeup waiting Thread with highest Priority thread = osRtxThreadListGet((os_object_t*)mutex); osRtxThreadWaitExit(thread, (uint32_t)osOK, false); // Thread is the new Mutex owner mutex->owner_thread = thread; mutex->owner_next = thread->mutex_list; mutex->owner_prev = NULL; thread->mutex_list = mutex; mutex->lock = 1U; EvrRtxMutexAcquired(mutex, 1U); } } mutex = mutex_list; } }
/// Acquire a Mutex or timeout if it is locked. /// \note API identical to osMutexAcquire osStatus_t svcRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) { os_mutex_t *mutex = (os_mutex_t *)mutex_id; os_thread_t *runnig_thread; runnig_thread = osRtxThreadGetRunning(); if (runnig_thread == NULL) { EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning); return osError; } // Check parameters if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) { EvrRtxMutexError(mutex, osErrorParameter); return osErrorParameter; } // Check object state if (mutex->state == osRtxObjectInactive) { EvrRtxMutexError(mutex, osErrorResource); return osErrorResource; } // Check if Mutex is not locked if (mutex->lock == 0U) { // Acquire Mutex mutex->owner_thread = runnig_thread; mutex->owner_next = runnig_thread->mutex_list; mutex->owner_prev = NULL; if (runnig_thread->mutex_list != NULL) { runnig_thread->mutex_list->owner_prev = mutex; } runnig_thread->mutex_list = mutex; mutex->lock = 1U; EvrRtxMutexAcquired(mutex, mutex->lock); return osOK; } // Check if Mutex is recursive and running Thread is the owner if ((mutex->attr & osMutexRecursive) && (mutex->owner_thread == runnig_thread)) { // Increment lock counter if (mutex->lock == osRtxMutexLockLimit) { EvrRtxMutexError(mutex, osRtxErrorMutexLockLimit); return osErrorResource; } mutex->lock++; EvrRtxMutexAcquired(mutex, mutex->lock); return osOK; } // Check if timeout is specified if (timeout != 0U) { // Check if Priority inheritance protocol is enabled if (mutex->attr & osMutexPrioInherit) { // Raise priority of owner Thread if lower than priority of running Thread if (mutex->owner_thread->priority < runnig_thread->priority) { mutex->owner_thread->priority = runnig_thread->priority; osRtxThreadListSort(mutex->owner_thread); } } EvrRtxMutexAcquirePending(mutex, timeout); // Suspend current Thread osRtxThreadListPut((os_object_t*)mutex, runnig_thread); osRtxThreadWaitEnter(osRtxThreadWaitingMutex, timeout); return osErrorTimeout; } // Mutex was not acquired EvrRtxMutexNotAcquired(mutex); return osErrorResource; }
/// Release a Mutex that was acquired by osMutexAcquire. /// \note API identical to osMutexRelease osStatus_t svcRtxMutexRelease (osMutexId_t mutex_id) { os_mutex_t *mutex = (os_mutex_t *)mutex_id; os_mutex_t *mutex0; os_thread_t *thread; os_thread_t *runnig_thread; int8_t priority; runnig_thread = osRtxThreadGetRunning(); if (runnig_thread == NULL) { EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning); return osError; } // Check parameters if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) { EvrRtxMutexError(mutex, osErrorParameter); return osErrorParameter; } // Check object state if (mutex->state == osRtxObjectInactive) { EvrRtxMutexError(mutex, osErrorResource); return osErrorResource; } // Check if running Thread is not the owner if (mutex->owner_thread != runnig_thread) { EvrRtxMutexError(mutex, osRtxErrorMutexNotOwned); return osErrorResource; } // Check if Mutex is not locked if (mutex->lock == 0U) { EvrRtxMutexError(mutex, osRtxErrorMutexNotLocked); return osErrorResource; } // Decrement Lock counter mutex->lock--; EvrRtxMutexReleased(mutex, mutex->lock); // Check Lock counter if (mutex->lock != 0U) { return osOK; } // Remove Mutex from Thread owner list if (mutex->owner_next != NULL) { mutex->owner_next->owner_prev = mutex->owner_prev; } if (mutex->owner_prev != NULL) { mutex->owner_prev->owner_next = mutex->owner_next; } else { runnig_thread->mutex_list = mutex->owner_next; } // Restore running Thread priority if (mutex->attr & osMutexPrioInherit) { priority = runnig_thread->priority_base; mutex0 = runnig_thread->mutex_list; while (mutex0) { // Mutexes owned by running Thread if ((mutex0->thread_list != NULL) && (mutex0->thread_list->priority > priority)) { // Higher priority Thread is waiting for Mutex priority = mutex0->thread_list->priority; } mutex0 = mutex0->owner_next; } runnig_thread->priority = priority; } // Check if Thread is waiting for a Mutex if (mutex->thread_list != NULL) { // Wakeup waiting Thread with highest Priority thread = osRtxThreadListGet((os_object_t*)mutex); osRtxThreadWaitExit(thread, (uint32_t)osOK, false); // Thread is the new Mutex owner mutex->owner_thread = thread; mutex->owner_next = thread->mutex_list; mutex->owner_prev = NULL; thread->mutex_list = mutex; mutex->lock = 1U; EvrRtxMutexAcquired(mutex, 1U); } osRtxThreadDispatch(NULL); return osOK; }
/// Acquire a Mutex or timeout if it is locked. /// \note API identical to osMutexAcquire static osStatus_t svcRtxMutexAcquire (osMutexId_t mutex_id, uint32_t timeout) { os_mutex_t *mutex = osRtxMutexId(mutex_id); os_thread_t *runnig_thread; osStatus_t status; // Check running thread runnig_thread = osRtxThreadGetRunning(); if (runnig_thread == NULL) { EvrRtxMutexError(mutex, osRtxErrorKernelNotRunning); //lint -e{904} "Return statement before end of function" [MISRA Note 1] return osError; } // Check parameters if ((mutex == NULL) || (mutex->id != osRtxIdMutex)) { EvrRtxMutexError(mutex, (int32_t)osErrorParameter); //lint -e{904} "Return statement before end of function" [MISRA Note 1] return osErrorParameter; } // Check if Mutex is not locked if (mutex->lock == 0U) { // Acquire Mutex mutex->owner_thread = runnig_thread; mutex->owner_next = runnig_thread->mutex_list; mutex->owner_prev = NULL; if (runnig_thread->mutex_list != NULL) { runnig_thread->mutex_list->owner_prev = mutex; } runnig_thread->mutex_list = mutex; mutex->lock = 1U; EvrRtxMutexAcquired(mutex, mutex->lock); status = osOK; } else { // Check if Mutex is recursive and running Thread is the owner if (((mutex->attr & osMutexRecursive) != 0U) && (mutex->owner_thread == runnig_thread)) { // Try to increment lock counter if (mutex->lock == osRtxMutexLockLimit) { EvrRtxMutexError(mutex, osRtxErrorMutexLockLimit); status = osErrorResource; } else { mutex->lock++; EvrRtxMutexAcquired(mutex, mutex->lock); status = osOK; } } else { // Check if timeout is specified if (timeout != 0U) { // Check if Priority inheritance protocol is enabled if ((mutex->attr & osMutexPrioInherit) != 0U) { // Raise priority of owner Thread if lower than priority of running Thread if (mutex->owner_thread->priority < runnig_thread->priority) { mutex->owner_thread->priority = runnig_thread->priority; osRtxThreadListSort(mutex->owner_thread); } } EvrRtxMutexAcquirePending(mutex, timeout); // Suspend current Thread if (osRtxThreadWaitEnter(osRtxThreadWaitingMutex, timeout)) { osRtxThreadListPut(osRtxObject(mutex), runnig_thread); } else { EvrRtxMutexAcquireTimeout(mutex); } status = osErrorTimeout; } else { EvrRtxMutexNotAcquired(mutex); status = osErrorResource; } } } return status; }