Friday, September 04, 2015

Task Management: Change Task priority

① Change Task's base priority

There three kinds of priorities.

1) Initial priority - Assigned when Task is created through Task creation structure. Once taks is created, this will be base priority.
2) Base priority - Priority changed on runtime through chg_pri
3) Running priority - Unless otherwise Mutexes are locked, this will be same as base priority. But, when Mutexes are locked, running priority is changed according to priority inheritence algorithm.

When priority is changed, all operations which are based on priority needs to be realigned. Whether it is get_mpl, snd_mbf or waiting for mutex or locked mutex. Please note that the task needs to yield, if the current running priotiy is same as of it.

② uITRON Implementation of chg_pri()

ER chg_pri(ID tskid, PRI tskpri)
{
        if (TSK_SELF is specified as Task ID)
                Set tskid as ReadyQueue[0]
        Enter critical section
        Sanity check on arguments
        /* Dormant task, Timer tasks(idle tasks) cannot be target */
        /* ISR cannot specify TSK_SELF */
        Take TCB of target task ID
        if (target priority == TPRI_INI)
                take task priority from initialization structure
        yesmtx = check if target task has locked mutex or waiting for mutex

        /* Just changing the Base priority; Not running priority */
        /* When mutex is locked/waited, but target pri is lower than running pri */
        if (yesmtx) {
                if (target priority is higher than running priority) {
                        /* Whether the target pri is valid or not? */
                        for (all mutexes locked by target task) {
                                if (CEILING priority &&
                                        target pri is higher than ceiling pri) {
                                        return E_ILUSE;
                                }
                                MaxLocked = Get Maximum of Inherited&Ceiling pri of locked mutexes
                        }
                        /* Is the running not equal to Maximum of locked mutex priorites ????. So, I guess following will be false forever */
                        if (Target pri is lower than MaxLocked)
                                goto Just_exit
                }
                else (target pri is lower than running pri) {
Just_exit:              I cannot change running pri as mutex make running pri as higher
                        So, I just change base priority and leaving now.
                        Mutex functions will adjust the running further based on the base pri.
                }
        }

        /* Changing the Running priority too */
        Take back up of target task's current running pri;
        Assign target priority to both base as well as running priority
        If (Task is ReadyToRun and not suspended) {
                move the position of Task in the ReadyQueue
                if (task is running task and target pri is lesser/equal
                                 priority of current user task priority) {
                        OR
                (task is not Running and target pri is higher/equal priority of
                                current user task priority) {
                        /* if you are equal, I will dispatch */
                        /* if you are waiting and higher, then dispatch */
                        /* if you are running and become lower, then dispatch */
                        return dispatch();
                }
                /* I am still running after changing the priority */
                /* then update current running priority and current application priority */
                current running priority = target priority;
                if (current running priority != 0) { /* Reverse is not possible as system task cannot be target ??? */
                        current application priority = current running priority;
                }
                return;
        }

        /* No, the target guy is waiting for something */
        if (waiting for Resource) {
                Adjust the position in the queue if it is priority based queue
                (Not FIFO)
                if (waiting for Mutex) {
                        get the Mutex ID waiting for
                        if (Mutex is INHERITENCE based) {
                                Mutex priority should be equal to Top priority
                                task in the waiting queue
                                if (this is not true) /* above position adjustment caused this */
                                        realign the task priority of holding the mutex
                        }
                }
        } else if (waiting for Message buffer) {
                Check the change in position caused any advantage
                if (caused advantage)
                        return dispatch;
        } else if (waiting for Memory Pool) {
                Check the change in position caused any advantage
                if (caused advantage)
                        return dispatch;
        }
        exit critical section;
        return;
}

Changing priority - Adjusting the foundation..

1 comment:

Unknown said...

nice post and site, good work! This article is well written and quite informative. More articles should be written and you have just found a follower.and more visit
sas training in hyderabad