uC-OS3
uC-OS3 copied to clipboard
A bug in the OS_TaskChangePrio funciton (os_task.c)
When a task to change its priority is blocked on a mutex, its priority change may affect the priority of the owner of the mutex. Specifically, in this function, if the priority of the task is to be reduced, that is, prio_ new>prio_ Cur, at this time, if the priority of the owner of the mutex is higher than prio_ Cur, which is not handled in this case, that is, the loop should be ended, but this is not done in the function.
case OS_TASK_PEND_ON_MUTEX:
#if (OS_CFG_MUTEX_EN > 0u)
OS_PendListChangePrio(p_tcb);
p_tcb_owner = ((OS_MUTEX *)((void )p_tcb->PendObjPtr))->OwnerTCBPtr;
if (prio_cur > prio_new) { / Are we increasing the priority? /
if (p_tcb_owner->Prio <= prio_new) { / Yes, do we need to give this prio to the owner? */
p_tcb_owner = (OS_TCB )0;
} else {
/ Block is empty when trace is disabled. /
OS_TRACE_MUTEX_TASK_PRIO_INHERIT(p_tcb_owner, prio_new);
}
} else {
if (p_tcb_owner->Prio == prio_cur) { / No, is it required to check for a lower prio? */
prio_new = OS_MutexGrpPrioFindHighest(p_tcb_owner);
prio_new = (prio_new > p_tcb_owner->BasePrio) ? p_tcb_owner->BasePrio : prio_new;
if (prio_new == p_tcb_owner->Prio) {
p_tcb_owner = (OS_TCB )0;
} else {
/ Block is empty when trace is disabled. */
OS_TRACE_MUTEX_TASK_PRIO_DISINHERIT(p_tcb_owner, prio_new);
}
}
A condition to end the loop is missing here
}
#endif
break;
I think it should be: case OS_TASK_PEND_ON_MUTEX: #if (OS_CFG_MUTEX_EN > 0u) OS_PendListChangePrio(p_tcb); p_tcb_owner = ((OS_MUTEX *)((void )p_tcb->PendObjPtr))->OwnerTCBPtr; if (prio_cur > prio_new) { / Are we increasing the priority? / if (p_tcb_owner->Prio <= prio_new) { / Yes, do we need to give this prio to the owner? */ p_tcb_owner = (OS_TCB )0; } else { / Block is empty when trace is disabled. / OS_TRACE_MUTEX_TASK_PRIO_INHERIT(p_tcb_owner, prio_new); } } else { if (p_tcb_owner->Prio == prio_cur) { / No, is it required to check for a lower prio? */ prio_new = OS_MutexGrpPrioFindHighest(p_tcb_owner); prio_new = (prio_new > p_tcb_owner->BasePrio) ? p_tcb_owner->BasePrio : prio_new; if (prio_new == p_tcb_owner->Prio) { p_tcb_owner = (OS_TCB )0; } else { / Block is empty when trace is disabled. */ OS_TRACE_MUTEX_TASK_PRIO_DISINHERIT(p_tcb_owner, prio_new); } }else{ p_tcb_owner = (OS_TCB )0; } } #endif break;
Thank you for the report. I can confirm that this is an issue. We will add a fix in the next release.
Seeing as Cesium 3/08.03 incorporates this change, when will the official Micrium release be made that will incorporate this change.
Our team typically plans for one Open-Source update per year. We accumulate the community changes and bug fixes we've made to the Cesium stacks and push them to the uC stacks.