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();
}
Beispiel #2
0
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);
}
Beispiel #3
0
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
                    }
                }
            }