gonzui


Format: Advanced Search

mtkernel_3/kernel/tkernel/task.cbare sourcepermlink (0.05 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    micro T-Kernel 3.00.01
    4:  *
    5:  *    Copyright (C) 2006-2020 by Ken Sakamura.
    6:  *    This software is distributed under the T-License 2.2.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by TRON Forum(http://www.tron.org) at 2020/05/29.
   10:  *
   11:  *----------------------------------------------------------------------
   12:  */
   13: 
   14: /*
   15:  *      task.c
   16:  *      Task Control
   17:  */
   18: 
   19: #include "kernel.h"
   20: #include "task.h"
   21: #include "ready_queue.h"
   22: #include "wait.h"
   23: #include "check.h"
   24: 
   25: #include "../sysdepend/cpu_task.h"
   26: 
   27: /*
   28:  * Task dispatch disable state
   29:  */
   30: Noinit(EXPORT INT       knl_dispatch_disabled);       /* DDS_XXX see task.h */
   31: 
   32: /*
   33:  * Task execution control 
   34:  */
   35: Noinit(EXPORT TCB       *knl_ctxtsk); /* Task in execution */
   36: Noinit(EXPORT TCB       *knl_schedtsk);       /* Task which should be executed */
   37: 
   38: Noinit(EXPORT RDYQUE    knl_ready_queue);  /* Ready queue */
   39: 
   40: /*
   41:  * Task control information
   42:  */
   43: Noinit(EXPORT TCB       knl_tcb_table[NUM_TSKID]);    /* Task control block */
   44: Noinit(EXPORT QUEUE     knl_free_tcb);      /* FreeQue */
   45: 
   46: /*
   47:  * TCB Initialization
   48:  */
   49: EXPORT ER knl_task_initialize( void )
   50: {
   51:         INT    i;
   52:         TCB    *tcb;
   53:         ID     tskid;
   54: 
   55:         /* Get system information */
   56:         if ( NUM_TSKID < 1 ) {
   57:                 return E_SYS;
   58:         }
   59: 
   60:         /* Initialize task execution control information */
   61:         knl_ctxtsk = knl_schedtsk = NULL;
   62:         knl_ready_queue_initialize(&knl_ready_queue);
   63:         knl_dispatch_disabled = DDS_ENABLE;
   64: 
   65:         /* Register all TCBs onto FreeQue */
   66:         QueInit(&knl_free_tcb);
   67:         for ( tcb = knl_tcb_table, i = 0; i < NUM_TSKID; tcb++, i++ ) {
   68:                 tskid = ID_TSK(i);
   69:                 tcb->tskid = tskid;
   70:                 tcb->state = TS_NONEXIST;
   71: #if USE_LEGACY_API && USE_RENDEZVOUS
   72:                 tcb->wrdvno = tskid;
   73: #endif
   74: 
   75:                 QueInsert(&tcb->tskque, &knl_free_tcb);
   76:         }
   77: 
   78:         return E_OK;
   79: }
   80: 
   81: /*
   82:  * Prepare task execution.
   83:  */
   84: EXPORT void knl_make_dormant( TCB *tcb )
   85: {
   86:         /* Initialize variables which should be reset at DORMANT state */
   87:         tcb->state     = TS_DORMANT;
   88:         tcb->priority  = tcb->bpriority = tcb->ipriority;
   89:         tcb->sysmode   = tcb->isysmode;
   90:         tcb->wupcnt    = 0;
   91:         tcb->suscnt    = 0;
   92: 
   93:         tcb->klockwait = FALSE;
   94:         tcb->klocked   = FALSE;
   95: 
   96: #if USE_DBGSPT && defined(USE_FUNC_TD_INF_TSK)
   97:         tcb->stime     = 0;
   98:         tcb->utime     = 0;
   99: #endif
  100: 
  101:         tcb->wercd = NULL;
  102: 
  103: #if USE_MUTEX == 1
  104:         tcb->mtxlist   = NULL;
  105: #endif
  106: 
  107:         /* Set context to start task */
  108:         knl_setup_context(tcb);
  109: }
  110: 
  111: /* ------------------------------------------------------------------------ */
  112: 
  113: /*
  114:  * Set task to READY state.
  115:  *      Update the task state and insert in the ready queue. If necessary, 
  116:  *      update 'knl_schedtsk' and request to start task dispatcher. 
  117:  */
  118: EXPORT void knl_make_ready( TCB *tcb )
  119: {
  120:         tcb->state = TS_READY;
  121:         if ( knl_ready_queue_insert(&knl_ready_queue, tcb) ) {
  122:                 knl_schedtsk = tcb;
  123:         }
  124: }
  125: 
  126: /*
  127:  * Set task to non-executable state.
  128:  *      Delete the task from the ready queue.
  129:  *      If the deleted task is 'knl_schedtsk', set 'knl_schedtsk' to the
  130:  *      highest priority task in the ready queue. 
  131:  *      'tcb' task must be READY.
  132:  */
  133: EXPORT void knl_make_non_ready( TCB *tcb )
  134: {
  135:         knl_ready_queue_delete(&knl_ready_queue, tcb);
  136:         if ( knl_schedtsk == tcb ) {
  137:                 knl_schedtsk = knl_ready_queue_top(&knl_ready_queue);
  138:         }
  139: }
  140: 
  141: /*
  142:  * Change task priority.
  143:  */
  144: EXPORT void knl_change_task_priority( TCB *tcb, INT priority )
  145: {
  146:         INT    oldpri;
  147: 
  148:         if ( tcb->state == TS_READY ) {
  149:                 /*
  150:                  * When deleting a task from the ready queue, 
  151:                  * a value in the 'priority' field in TCB is needed. 
  152:                  * Therefore you need to delete the task from the
  153:                  * ready queue before changing 'tcb->priority.'
  154:                  */
  155:                 knl_ready_queue_delete(&knl_ready_queue, tcb);
  156:                 tcb->priority = (UB)priority;
  157:                 knl_ready_queue_insert(&knl_ready_queue, tcb);
  158:                 knl_reschedule();
  159:         } else {
  160:                 oldpri = tcb->priority;
  161:                 tcb->priority = (UB)priority;
  162: 
  163:                 /* If the hook routine at the task priority change is defined,
  164:                    execute it */
  165:                 if ( (tcb->state & TS_WAIT) != 0 && tcb->wspec->chg_pri_hook) {
  166:                         (*tcb->wspec->chg_pri_hook)(tcb, oldpri);
  167:                 }
  168:         }
  169: }
  170: 
  171: /*
  172:  * Rotate ready queue.
  173:  */
  174: EXPORT void knl_rotate_ready_queue( INT priority )
  175: {
  176:         knl_ready_queue_rotate(&knl_ready_queue, priority);
  177:         knl_reschedule();
  178: }
  179: 
  180: /*
  181:  * Rotate the ready queue including the highest priority task.
  182:  */
  183: EXPORT void knl_rotate_ready_queue_run( void )
  184: {
  185:         if ( knl_schedtsk != NULL ) {
  186:                 knl_ready_queue_rotate(&knl_ready_queue,
  187:                                 knl_ready_queue_top_priority(&knl_ready_queue));
  188:                 knl_reschedule();
  189:         }
  190: }
  191: 
  192: /* ------------------------------------------------------------------------ */
  193: /*
  194:  *      Debug support function
  195:  */
  196: #if USE_DBGSPT
  197: 
  198: #ifdef USE_FUNC_TD_RDY_QUE
  199: /*
  200:  * Refer ready queue
  201:  */
  202: SYSCALL INT td_rdy_que( PRI pri, ID list[], INT nent )
  203: {
  204:         QUEUE  *q, *tskque;
  205:         INT    n = 0;
  206: 
  207:         CHECK_PRI(pri);
  208: 
  209:         BEGIN_DISABLE_INTERRUPT;
  210:         tskque = &knl_ready_queue.tskque[int_priority(pri)];
  211:         for ( q = tskque->next; q != tskque; q = q->next ) {
  212:                 if ( n++ < nent ) {
  213:                         *(list++) = ((TCB*)q)->tskid;
  214:                 }
  215:         }
  216:         END_DISABLE_INTERRUPT;
  217: 
  218:         return n;
  219: }
  220: #endif /* USE_FUNC_TD_RDY_QUE */
  221: 
  222: #endif /* USE_DBGSPT */