gonzui


Format: Advanced Search

tkernel_2/kernel/tkernel/src/wait.cbare sourcepermlink (0.01 seconds)

Search this content:

    1: /*
    2:  *----------------------------------------------------------------------
    3:  *    T-Kernel 2.0 Software Package
    4:  *
    5:  *    Copyright 2011 by Ken Sakamura.
    6:  *    This software is distributed under the latest version of T-License 2.x.
    7:  *----------------------------------------------------------------------
    8:  *
    9:  *    Released by T-Engine Forum(http://www.t-engine.org/) at 2011/05/17.
   10:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
   11:  *
   12:  *----------------------------------------------------------------------
   13:  */
   14: 
   15: /*
   16:  *      wait.c (T-Kernel/OS)
   17:  *      Common Routine for Synchronization
   18:  */
   19: 
   20: #include "kernel.h"
   21: #include "task.h"
   22: #include "wait.h"
   23: 
   24: /*
   25:  * Update the task state to release wait. When it becomes ready state,
   26:  * connect to the ready queue.
   27:  * Call when the task is in the wait state (including double wait).
   28:  */
   29: Inline void make_non_wait( TCB *tcb )
   30: {
   31:         if ( tcb->state == TS_WAIT ) {
   32:                 make_ready(tcb);
   33:         } else {
   34:                 tcb->state = TS_SUSPEND;
   35:         }
   36: }
   37: 
   38: /*
   39:  * Release wait state of the task.
   40:  */
   41: Inline void wait_release( TCB *tcb )
   42: {
   43:         timer_delete(&tcb->wtmeb);
   44:         QueRemove(&tcb->tskque);
   45:         make_non_wait(tcb);
   46: }
   47: 
   48: EXPORT void wait_release_ok( TCB *tcb )
   49: {
   50:         wait_release(tcb);
   51:         *tcb->wercd = E_OK;
   52: }
   53: 
   54: EXPORT void wait_release_ok_ercd( TCB *tcb, ER ercd )
   55: {
   56:         wait_release(tcb);
   57:         *tcb->wercd = ercd;
   58: }
   59: 
   60: EXPORT void wait_release_ng( TCB *tcb, ER ercd )
   61: {
   62:         wait_release(tcb);
   63:         if ( tcb->wspec->rel_wai_hook != NULL ) {
   64:                 (*tcb->wspec->rel_wai_hook)(tcb);
   65:         }
   66:         *tcb->wercd = ercd;
   67: }
   68: 
   69: EXPORT void wait_release_tmout( TCB *tcb )
   70: {
   71:         QueRemove(&tcb->tskque);
   72:         make_non_wait(tcb);
   73:         if ( tcb->wspec->rel_wai_hook != NULL ) {
   74:                 (*tcb->wspec->rel_wai_hook)(tcb);
   75:         }
   76: }
   77: 
   78: /*
   79:  * Change the active task state to wait state and connect to the
   80:  * timer event queue.
   81:  *      Normally, 'ctxtsk' is in the RUN state, but when an interrupt
   82:  *      occurs during executing system call, 'ctxtsk' may become the
   83:  *      other state by system call called in the interrupt handler.
   84:  *      However, it does not be in WAIT state.
   85:  *
   86:  *      "include/tk/typedef.h"
   87:  *      typedef      INT          TMO;
   88:  *      typedef UINT         RELTIM;
   89:  *      #define TMO_FEVR     (-1)
   90:  */
   91: EXPORT void make_wait( TMO_U tmout, ATR atr )
   92: {
   93:         switch ( ctxtsk->state ) {
   94:           case TS_READY:
   95:                 make_non_ready(ctxtsk);
   96:                 ctxtsk->state = TS_WAIT;
   97:                 break;
   98:           case TS_SUSPEND:
   99:                 ctxtsk->state = TS_WAITSUS;
  100:                 break;
  101:         }
  102:         ctxtsk->nodiswai = ( (atr & TA_NODISWAI) != 0 )? TRUE: FALSE;
  103:         timer_insert(&ctxtsk->wtmeb, tmout, (CBACK)wait_release_tmout, ctxtsk);
  104: }
  105: 
  106: EXPORT void make_wait_reltim( RELTIM_U tmout, ATR atr )
  107: {
  108:         switch ( ctxtsk->state ) {
  109:           case TS_READY:
  110:                 make_non_ready(ctxtsk);
  111:                 ctxtsk->state = TS_WAIT;
  112:                 break;
  113:           case TS_SUSPEND:
  114:                 ctxtsk->state = TS_WAITSUS;
  115:                 break;
  116:         }
  117:         ctxtsk->nodiswai = ( (atr & TA_NODISWAI) != 0 )? TRUE: FALSE;
  118:         timer_insert_reltim(&ctxtsk->wtmeb, tmout, (CBACK)wait_release_tmout, ctxtsk);
  119: }
  120: 
  121: /*
  122:  * Release all tasks connected to the wait queue, and define it
  123:  * as E_DLT error.
  124:  */
  125: EXPORT void wait_delete( QUEUE *wait_queue )
  126: {
  127:         TCB    *tcb;
  128: 
  129:         while ( !isQueEmpty(wait_queue) ) {
  130:                 tcb = (TCB*)wait_queue->next;
  131:                 wait_release(tcb);
  132:                 *tcb->wercd = E_DLT;
  133:         }
  134: }
  135: 
  136: /*
  137:  * Get ID of the head task in the wait queue.
  138:  */
  139: EXPORT ID wait_tskid( QUEUE *wait_queue )
  140: {
  141:         if ( isQueEmpty(wait_queue) ) {
  142:                 return 0;
  143:         }
  144: 
  145:         return ((TCB*)wait_queue->next)->tskid;
  146: }
  147: 
  148: /*
  149:  * Change the active task state to wait state and connect to the timer wait
  150:  * queue and the object wait queue. Also set 'wid' in 'ctxtsk'.
  151:  */
  152: EXPORT void gcb_make_wait( GCB *gcb, TMO_U tmout )
  153: {
  154:         ctxtsk->wid = gcb->objid;
  155:         make_wait(tmout, gcb->objatr);
  156:         if ( (gcb->objatr & TA_TPRI) != 0 ) {
  157:                 queue_insert_tpri(ctxtsk, &gcb->wait_queue);
  158:         } else {
  159:                 QueInsert(&ctxtsk->tskque, &gcb->wait_queue);
  160:         }
  161: }
  162: 
  163: /*
  164:  * 'gcb_make_wait' with wait disable check function
  165:  */
  166: EXPORT void gcb_make_wait_with_diswai( GCB *gcb, TMO_U tmout )
  167: {
  168:         if ( is_diswai(gcb, ctxtsk, ctxtsk->wspec->tskwait) ) {
  169:                 *ctxtsk->wercd = E_DISWAI;
  170:         } else {
  171:                 *ctxtsk->wercd = E_TMOUT;
  172:                 if ( tmout != TMO_POL ) {
  173:                         gcb_make_wait(gcb, tmout);
  174:                 }
  175:         }
  176: }
  177: 
  178: /*
  179:  * When the task priority changes, adjust the task position at the wait queue.
  180:  * It is called only if the object attribute TA_TPRI is specified.
  181:  *
  182:  */
  183: EXPORT void gcb_change_priority( GCB *gcb, TCB *tcb )
  184: {
  185:         QueRemove(&tcb->tskque);
  186:         queue_insert_tpri(tcb, &gcb->wait_queue);
  187: }
  188: 
  189: /*
  190:  * Search the first task of wait queue include "tcb" with target.
  191:  * (Not insert "tcb" into wait queue.)
  192:  *
  193:  */
  194: EXPORT TCB* gcb_top_of_wait_queue( GCB *gcb, TCB *tcb )
  195: {
  196:         TCB    *q;
  197: 
  198:         if ( isQueEmpty(&gcb->wait_queue) ) {
  199:                 return tcb;
  200:         }
  201: 
  202:         q = (TCB*)gcb->wait_queue.next;
  203:         if ( (gcb->objatr & TA_TPRI) == 0 ) {
  204:                 return q;
  205:         }
  206: 
  207:         return ( tcb->priority < q->priority )? tcb: q;
  208: }