gonzui


Format: Advanced Search

mtkernel_3/kernel/tkernel/wait.cbare sourcepermlink (0.02 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    micro T-Kernel 3.00.00
    4:  *
    5:  *    Copyright (C) 2006-2019 by Ken Sakamura.
    6:  *    This software is distributed under the T-License 2.1.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by TRON Forum(http://www.tron.org) at 2019/12/11.
   10:  *
   11:  *----------------------------------------------------------------------
   12:  */
   13: 
   14: /*
   15:  *      wait.c
   16:  *      Common Routine for Synchronization
   17:  */
   18: 
   19: #include "kernel.h"
   20: #include "wait.h"
   21: 
   22: EXPORT void knl_wait_release_ok( TCB *tcb )
   23: {
   24:         knl_wait_release(tcb);
   25:         *tcb->wercd = E_OK;
   26: }
   27: 
   28: EXPORT void knl_wait_release_ok_ercd( TCB *tcb, ER ercd )
   29: {
   30:         knl_wait_release(tcb);
   31:         *tcb->wercd = ercd;
   32: }
   33: 
   34: EXPORT void knl_wait_release_ng( TCB *tcb, ER ercd )
   35: {
   36:         knl_wait_release(tcb);
   37:         if ( tcb->wspec->rel_wai_hook != NULL ) {
   38:                 (*tcb->wspec->rel_wai_hook)(tcb);
   39:         }
   40:         *tcb->wercd = ercd;
   41: }
   42: 
   43: EXPORT void knl_wait_release_tmout( TCB *tcb )
   44: {
   45:         QueRemove(&tcb->tskque);
   46:         knl_make_non_wait(tcb);
   47:         if ( tcb->wspec->rel_wai_hook != NULL ) {
   48:                 (*tcb->wspec->rel_wai_hook)(tcb);
   49:         }
   50: }
   51: 
   52: /*
   53:  * Change the active task state to wait state and connect to the
   54:  * timer event queue.
   55:  *      Normally, 'knl_ctxtsk' is in the RUN state, but when an interrupt
   56:  *      occurs during executing system call, 'knl_ctxtsk' may become the
   57:  *      other state by system call called in the interrupt handler.
   58:  *      However, it does not be in WAIT state.
   59:  *
   60:  *      "include/tk/typedef.h"
   61:  *      typedef      W            TMO;
   62:  *      typedef UW           RELTIM;
   63:  *      #define TMO_FEVR     (-1)
   64:  */
   65: EXPORT void knl_make_wait( TMO tmout, ATR atr )
   66: {
   67:         switch ( knl_ctxtsk->state ) {
   68:           case TS_READY:
   69:                 knl_make_non_ready(knl_ctxtsk);
   70:                 knl_ctxtsk->state = TS_WAIT;
   71:                 break;
   72:           case TS_SUSPEND:
   73:                 knl_ctxtsk->state = TS_WAITSUS;
   74:                 break;
   75:         }
   76:         knl_timer_insert(&knl_ctxtsk->wtmeb, tmout, (CBACK)knl_wait_release_tmout, knl_ctxtsk);
   77: }
   78: 
   79: EXPORT void knl_make_wait_reltim( RELTIM tmout, ATR atr )
   80: {
   81:         switch ( knl_ctxtsk->state ) {
   82:           case TS_READY:
   83:                 knl_make_non_ready(knl_ctxtsk);
   84:                 knl_ctxtsk->state = TS_WAIT;
   85:                 break;
   86:           case TS_SUSPEND:
   87:                 knl_ctxtsk->state = TS_WAITSUS;
   88:                 break;
   89:         }
   90:         knl_timer_insert_reltim(&knl_ctxtsk->wtmeb, tmout, (CBACK)knl_wait_release_tmout, knl_ctxtsk);
   91: }
   92: 
   93: /*
   94:  * Release all tasks connected to the wait queue, and define it
   95:  * as E_DLT error.
   96:  */
   97: EXPORT void knl_wait_delete( QUEUE *wait_queue )
   98: {
   99:         TCB    *tcb;
  100: 
  101:         while ( !isQueEmpty(wait_queue) ) {
  102:                 tcb = (TCB*)wait_queue->next;
  103:                 knl_wait_release(tcb);
  104:                 *tcb->wercd = E_DLT;
  105:         }
  106: }
  107: 
  108: /*
  109:  * Get ID of the head task in the wait queue.
  110:  */
  111: EXPORT ID knl_wait_tskid( QUEUE *wait_queue )
  112: {
  113:         if ( isQueEmpty(wait_queue) ) {
  114:                 return 0;
  115:         }
  116: 
  117:         return ((TCB*)wait_queue->next)->tskid;
  118: }
  119: 
  120: /*
  121:  * Change the active task state to wait state and connect to the timer wait 
  122:  * queue and the object wait queue. Also set 'wid' in 'knl_ctxtsk'.
  123:  */
  124: EXPORT void knl_gcb_make_wait( GCB *gcb, TMO tmout )
  125: {
  126:         *knl_ctxtsk->wercd = E_TMOUT;
  127:         if ( tmout != TMO_POL ) {
  128:                 knl_ctxtsk->wid = gcb->objid;
  129:                 knl_make_wait(tmout, gcb->objatr);
  130:                 if ( (gcb->objatr & TA_TPRI) != 0 ) {
  131:                         knl_queue_insert_tpri(knl_ctxtsk, &gcb->wait_queue);
  132:                 } else {
  133:                         QueInsert(&knl_ctxtsk->tskque, &gcb->wait_queue);
  134:                 }
  135:         }
  136: }
  137: 
  138: /*
  139:  * When the task priority changes, adjust the task position at the wait queue.
  140:  * It is called only if the object attribute TA_TPRI is specified.
  141:  *
  142:  */
  143: EXPORT void knl_gcb_change_priority( GCB *gcb, TCB *tcb )
  144: {
  145:         QueRemove(&tcb->tskque);
  146:         knl_queue_insert_tpri(tcb, &gcb->wait_queue);
  147: }
  148: 
  149: /*
  150:  * Search the first task of wait queue include "tcb" with target.
  151:  * (Not insert "tcb" into wait queue.)
  152:  *
  153:  */
  154: EXPORT TCB* knl_gcb_top_of_wait_queue( GCB *gcb, TCB *tcb )
  155: {
  156:         TCB    *q;
  157: 
  158:         if ( isQueEmpty(&gcb->wait_queue) ) {
  159:                 return tcb;
  160:         }
  161: 
  162:         q = (TCB*)gcb->wait_queue.next;
  163:         if ( (gcb->objatr & TA_TPRI) == 0 ) {
  164:                 return q;
  165:         }
  166: 
  167:         return ( tcb->priority < q->priority )? tcb: q;
  168: }