void OS_TickListUpdate (void) { CPU_BOOLEAN done; OS_TICK_SPOKE *p_spoke; OS_TCB *p_tcb; OS_TCB *p_tcb_next; OS_TICK_SPOKE_IX spoke; CPU_TS ts_start; CPU_TS ts_end; CPU_SR_ALLOC(); OS_CRITICAL_ENTER(); ts_start = OS_TS_GET(); OSTickCtr++; /* Keep track of the number of ticks */ spoke = (OS_TICK_SPOKE_IX)(OSTickCtr % OSCfg_TickWheelSize); p_spoke = &OSCfg_TickWheel[spoke]; p_tcb = p_spoke->FirstPtr; done = DEF_FALSE; while (done == DEF_FALSE) { if (p_tcb != (OS_TCB *)0) { p_tcb_next = p_tcb->TickNextPtr; /* Point to next TCB to update */ switch (p_tcb->TaskState) { case OS_TASK_STATE_RDY: case OS_TASK_STATE_PEND: case OS_TASK_STATE_SUSPENDED: case OS_TASK_STATE_PEND_SUSPENDED: break; case OS_TASK_STATE_DLY: p_tcb->TickRemain = p_tcb->TickCtrMatch /* Compute time remaining of current TCB */ - OSTickCtr; if (OSTickCtr == p_tcb->TickCtrMatch) { /* Process each TCB that expires */ p_tcb->TaskState = OS_TASK_STATE_RDY; OS_TaskRdy(p_tcb); /* Make task ready to run */ } else { done = DEF_TRUE; /* Don't find a match, we're done! */ } break; case OS_TASK_STATE_PEND_TIMEOUT: p_tcb->TickRemain = p_tcb->TickCtrMatch /* Compute time remaining of current TCB */ - OSTickCtr; if (OSTickCtr == p_tcb->TickCtrMatch) { /* Process each TCB that expires */ #if (OS_MSG_EN > 0u) p_tcb->MsgPtr = (void *)0; p_tcb->MsgSize = (OS_MSG_SIZE)0u; #endif p_tcb->TS = OS_TS_GET(); OS_PendListRemove(p_tcb); /* Remove from wait list */ OS_TaskRdy(p_tcb); p_tcb->TaskState = OS_TASK_STATE_RDY; p_tcb->PendStatus = OS_STATUS_PEND_TIMEOUT; /* Indicate pend timed out */ p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */ } else { done = DEF_TRUE; /* Don't find a match, we're done! */ } break; case OS_TASK_STATE_DLY_SUSPENDED: p_tcb->TickRemain = p_tcb->TickCtrMatch /* Compute time remaining of current TCB */ - OSTickCtr; if (OSTickCtr == p_tcb->TickCtrMatch) { /* Process each TCB that expires */ p_tcb->TaskState = OS_TASK_STATE_SUSPENDED; OS_TickListRemove(p_tcb); /* Remove from current wheel spoke */ } else { done = DEF_TRUE; /* Don't find a match, we're done! */ } break; case OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED: p_tcb->TickRemain = p_tcb->TickCtrMatch /* Compute time remaining of current TCB */ - OSTickCtr; if (OSTickCtr == p_tcb->TickCtrMatch) { /* Process each TCB that expires */ #if (OS_MSG_EN > 0u) p_tcb->MsgPtr = (void *)0; p_tcb->MsgSize = (OS_MSG_SIZE)0u; #endif p_tcb->TS = OS_TS_GET(); OS_PendListRemove(p_tcb); /* Remove from wait list */ OS_TickListRemove(p_tcb); /* Remove from current wheel spoke */ p_tcb->TaskState = OS_TASK_STATE_SUSPENDED; p_tcb->PendStatus = OS_STATUS_PEND_TIMEOUT; /* Indicate pend timed out */ p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */ } else { done = DEF_TRUE; /* Don't find a match, we're done! */ } break; default: break; } p_tcb = p_tcb_next; } else { done = DEF_TRUE; } } ts_end = OS_TS_GET() - ts_start; /* Measure execution time of tick task */ if (ts_end > OSTickTaskTimeMax) { OSTickTaskTimeMax = ts_end; } OS_CRITICAL_EXIT(); }
static CPU_TS OS_TickListUpdateTimeout (void) { OS_TCB *p_tcb; OS_TICK_LIST *p_list; CPU_TS ts_start; CPU_TS ts_delta_timeout; #if OS_CFG_DBG_EN > 0u OS_OBJ_QTY nbr_updated; #endif CPU_SR_ALLOC(); OS_CRITICAL_ENTER(); /* ======= UPDATE TASKS WAITING WITH TIMEOUT ======= */ ts_start = OS_TS_GET(); #if OS_CFG_DBG_EN > 0u nbr_updated = (OS_OBJ_QTY)0u; #endif p_list = &OSTickListTimeout; p_tcb = p_list->TCB_Ptr; if (p_tcb != (OS_TCB *)0) { p_tcb->TickRemain--; while (p_tcb->TickRemain == 0u) { #if OS_CFG_DBG_EN > 0u nbr_updated++; #endif if (p_tcb->TaskState == OS_TASK_STATE_PEND_TIMEOUT) { #if (OS_MSG_EN > 0u) p_tcb->MsgPtr = (void *)0; p_tcb->MsgSize = (OS_MSG_SIZE)0u; #endif p_tcb->TS = OS_TS_GET(); OS_PendListRemove(p_tcb); /* Remove from wait list */ OS_RdyListInsert(p_tcb); /* Insert the task in the ready list */ p_tcb->TaskState = OS_TASK_STATE_RDY; p_tcb->PendStatus = OS_STATUS_PEND_TIMEOUT; /* Indicate pend timed out */ p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */ } else if (p_tcb->TaskState == OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED) { #if (OS_MSG_EN > 0u) p_tcb->MsgPtr = (void *)0; p_tcb->MsgSize = (OS_MSG_SIZE)0u; #endif p_tcb->TS = OS_TS_GET(); OS_PendListRemove(p_tcb); /* Remove from wait list */ p_tcb->TaskState = OS_TASK_STATE_SUSPENDED; p_tcb->PendStatus = OS_STATUS_PEND_TIMEOUT; /* Indicate pend timed out */ p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */ } p_list->TCB_Ptr = p_tcb->TickNextPtr; p_tcb = p_list->TCB_Ptr; /* Get 'p_tcb' again for loop */ if (p_tcb == (OS_TCB *)0) { #if OS_CFG_DBG_EN > 0u p_list->NbrEntries = (OS_OBJ_QTY)0u; #endif break; } else { #if OS_CFG_DBG_EN > 0u p_list->NbrEntries--; #endif p_tcb->TickPrevPtr = (OS_TCB *)0; } } } #if OS_CFG_DBG_EN > 0u p_list->NbrUpdated = nbr_updated; #endif ts_delta_timeout = OS_TS_GET() - ts_start; /* Measure execution time of the update */ OS_CRITICAL_EXIT(); /* ------------------------------------------------- */ return (ts_delta_timeout); }
static CPU_TS OS_TickListUpdateTimeout (void) { OS_TCB *p_tcb; OS_TICK_LIST *p_list; CPU_TS ts_start; CPU_TS ts_delta_timeout; #if OS_CFG_DBG_EN > 0u OS_OBJ_QTY nbr_updated; #endif #if OS_CFG_MUTEX_EN > 0u OS_TCB *p_tcb_owner; OS_PRIO prio_new; #endif CPU_SR_ALLOC(); OS_CRITICAL_ENTER(); /* ======= UPDATE TASKS WAITING WITH TIMEOUT ======= */ ts_start = OS_TS_GET(); #if OS_CFG_DBG_EN > 0u nbr_updated = (OS_OBJ_QTY)0u; #endif p_list = &OSTickListTimeout; p_tcb = p_list->TCB_Ptr; if (p_tcb != (OS_TCB *)0) { p_tcb->TickRemain--; while (p_tcb->TickRemain == 0u) { #if OS_CFG_DBG_EN > 0u nbr_updated++; #endif #if OS_CFG_MUTEX_EN > 0u p_tcb_owner = (OS_TCB *)0; if (p_tcb->PendOn == OS_TASK_PEND_ON_MUTEX) { p_tcb_owner = ((OS_MUTEX *)p_tcb->PendDataTblPtr->PendObjPtr)->OwnerTCBPtr; } #endif #if (OS_MSG_EN > 0u) p_tcb->MsgPtr = (void *)0; p_tcb->MsgSize = (OS_MSG_SIZE)0u; #endif p_tcb->TS = OS_TS_GET(); OS_PendListRemove(p_tcb); /* Remove from wait list */ if (p_tcb->TaskState == OS_TASK_STATE_PEND_TIMEOUT) { OS_RdyListInsert(p_tcb); /* Insert the task in the ready list */ p_tcb->TaskState = OS_TASK_STATE_RDY; } else if (p_tcb->TaskState == OS_TASK_STATE_PEND_TIMEOUT_SUSPENDED) { p_tcb->TaskState = OS_TASK_STATE_SUSPENDED; } p_tcb->PendStatus = OS_STATUS_PEND_TIMEOUT; /* Indicate pend timed out */ p_tcb->PendOn = OS_TASK_PEND_ON_NOTHING; /* Indicate no longer pending */ #if OS_CFG_MUTEX_EN > 0u if(p_tcb_owner != (OS_TCB *)0) { if ((p_tcb_owner->Prio != p_tcb_owner->BasePrio) && (p_tcb_owner->Prio == p_tcb->Prio)) { /* Has the owner inherited a priority? */ 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) { OS_TaskChangePrio(p_tcb_owner, prio_new); #if (defined(TRACE_CFG_EN) && (TRACE_CFG_EN > 0u)) TRACE_OS_MUTEX_TASK_PRIO_DISINHERIT(p_tcb_owner, p_tcb_owner->Prio) #endif } } }