gonzui


Format: Advanced Search

mtkernel_3/kernel/tkernel/task_sync.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:  *      task_sync.c
   16:  *      Task with Synchronize Function
   17:  */
   18: 
   19: #include "kernel.h"
   20: #include "wait.h"
   21: #include "check.h"
   22: #include "limits.h"
   23: 
   24: #ifdef USE_FUNC_TK_SUS_TSK
   25: /*
   26:  * Suspend task
   27:  */
   28: SYSCALL ER tk_sus_tsk( ID tskid )
   29: {
   30:         TCB    *tcb;
   31:         TSTAT  state;
   32:         ER     ercd = E_OK;
   33: 
   34:         CHECK_TSKID(tskid);
   35:         CHECK_NONSELF(tskid);
   36: 
   37:         tcb = get_tcb(tskid);
   38: 
   39:         BEGIN_CRITICAL_SECTION;
   40:         state = (TSTAT)tcb->state;
   41:         if ( !knl_task_alive(state) ) {
   42:                 ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ;
   43:                 goto error_exit;
   44:         }
   45:         if ( tcb == knl_ctxtsk && knl_dispatch_disabled >= DDS_DISABLE ) {
   46:                 ercd = E_CTX;
   47:                 goto error_exit;
   48:         }
   49:         if ( tcb->suscnt == INT_MAX ) {
   50:                 ercd = E_QOVR;
   51:                 goto error_exit;
   52:         }
   53: 
   54:         /* Update suspend request count */
   55:         ++tcb->suscnt;
   56: 
   57:         /* Move to forced wait state */
   58:         if ( state == TS_READY ) {
   59:                 knl_make_non_ready(tcb);
   60:                 tcb->state = TS_SUSPEND;
   61: 
   62:         } else if ( state == TS_WAIT ) {
   63:                 tcb->state = TS_WAITSUS;
   64:         }
   65: 
   66:     error_exit:
   67:         END_CRITICAL_SECTION;
   68: 
   69:         return ercd;
   70: }
   71: #endif /* USE_FUNC_TK_SUS_TSK */
   72: 
   73: #ifdef USE_FUNC_TK_RSM_TSK
   74: /*
   75:  * Resume task
   76:  */
   77: SYSCALL ER tk_rsm_tsk( ID tskid )
   78: {
   79:         TCB    *tcb;
   80:         ER     ercd = E_OK;
   81: 
   82:         CHECK_TSKID(tskid);
   83:         CHECK_NONSELF(tskid);
   84: 
   85:         tcb = get_tcb(tskid);
   86: 
   87:         BEGIN_CRITICAL_SECTION;
   88:         switch ( tcb->state ) {
   89:           case TS_NONEXIST:
   90:                 ercd = E_NOEXS;
   91:                 break;
   92: 
   93:           case TS_DORMANT:
   94:           case TS_READY:
   95:           case TS_WAIT:
   96:                 ercd = E_OBJ;
   97:                 break;
   98: 
   99:           case TS_SUSPEND:
  100:                 if ( --tcb->suscnt == 0 ) {
  101:                         knl_make_ready(tcb);
  102:                 }
  103:                 break;
  104:           case TS_WAITSUS:
  105:                 if ( --tcb->suscnt == 0 ) {
  106:                         tcb->state = TS_WAIT;
  107:                 }
  108:                 break;
  109: 
  110:           default:
  111:                 ercd = E_SYS;
  112:                 break;
  113:         }
  114:         END_CRITICAL_SECTION;
  115: 
  116:         return ercd;
  117: }
  118: #endif /* USE_FUNC_TK_RSM_TSK */
  119: 
  120: #ifdef USE_FUNC_TK_FRSM_TSK
  121: /*
  122:  * Force resume task
  123:  */
  124: SYSCALL ER tk_frsm_tsk( ID tskid )
  125: {
  126:         TCB    *tcb;
  127:         ER     ercd = E_OK;
  128: 
  129:         CHECK_TSKID(tskid);
  130:         CHECK_NONSELF(tskid);
  131: 
  132:         tcb = get_tcb(tskid);
  133: 
  134:         BEGIN_CRITICAL_SECTION;
  135:         switch ( tcb->state ) {
  136:           case TS_NONEXIST:
  137:                 ercd = E_NOEXS;
  138:                 break;
  139: 
  140:           case TS_DORMANT:
  141:           case TS_READY:
  142:           case TS_WAIT:
  143:                 ercd = E_OBJ;
  144:                 break;
  145: 
  146:           case TS_SUSPEND:
  147:                 tcb->suscnt = 0;
  148:                 knl_make_ready(tcb);
  149:                 break;
  150:           case TS_WAITSUS:
  151:                 tcb->suscnt = 0;
  152:                 tcb->state = TS_WAIT;
  153:                 break;
  154: 
  155:           default:
  156:                 ercd = E_SYS;
  157:                 break;
  158:         }
  159:         END_CRITICAL_SECTION;
  160: 
  161:         return ercd;
  162: }
  163: #endif /* USE_FUNC_TK_FRSM_TSK */
  164: 
  165: /* ------------------------------------------------------------------------ */
  166: 
  167: /*
  168:  * Definition of task wait specification
  169:  */
  170: LOCAL CONST WSPEC knl_wspec_slp = { TTW_SLP, NULL, NULL };
  171: 
  172: #ifdef USE_FUNC_TK_SLP_TSK
  173: /*
  174:  * Move its own task state to wait state
  175:  */
  176: SYSCALL ER tk_slp_tsk( TMO tmout )
  177: {
  178:         ER     ercd = E_OK;
  179: 
  180:         CHECK_TMOUT(tmout);
  181:         CHECK_DISPATCH();
  182: 
  183:         BEGIN_CRITICAL_SECTION;
  184: 
  185:         if ( knl_ctxtsk->wupcnt > 0 ) {
  186:                 knl_ctxtsk->wupcnt--;
  187:         } else {
  188:                 ercd = E_TMOUT;
  189:                 if ( tmout != TMO_POL ) {
  190:                         knl_ctxtsk->wspec = &knl_wspec_slp;
  191:                         knl_ctxtsk->wid = 0;
  192:                         knl_ctxtsk->wercd = &ercd;
  193:                         knl_make_wait(tmout, TA_NULL);
  194:                         QueInit(&knl_ctxtsk->tskque);
  195:                 }
  196:         }
  197: 
  198:         END_CRITICAL_SECTION;
  199: 
  200:         return ercd;
  201: }
  202: #endif /* USE_FUNC_TK_SLP_TSK */
  203: 
  204: #ifdef USE_FUNC_TK_WUP_TSK
  205: /*
  206:  * Wakeup task
  207:  */
  208: SYSCALL ER tk_wup_tsk( ID tskid )
  209: {
  210:         TCB    *tcb;
  211:         TSTAT  state;
  212:         ER     ercd = E_OK;
  213: 
  214:         CHECK_TSKID(tskid);
  215:         CHECK_NONSELF(tskid);
  216: 
  217:         tcb = get_tcb(tskid);
  218: 
  219:         BEGIN_CRITICAL_SECTION;
  220:         state = (TSTAT)tcb->state;
  221:         if ( !knl_task_alive(state) ) {
  222:                 ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ;
  223: 
  224:         } else if ( (state & TS_WAIT) != 0 && tcb->wspec == &knl_wspec_slp ) {
  225:                 knl_wait_release_ok(tcb);
  226: 
  227:         } else if ( tcb->wupcnt == INT_MAX ) {
  228:                 ercd = E_QOVR;
  229:         } else {
  230:                 ++tcb->wupcnt;
  231:         }
  232:         END_CRITICAL_SECTION;
  233: 
  234:         return ercd;
  235: }
  236: #endif /* USE_FUNC_TK_WUP_TSK */
  237: 
  238: #ifdef USE_FUNC_TK_CAN_WUP
  239: /*
  240:  * Cancel wakeup request
  241:  */
  242: SYSCALL INT tk_can_wup( ID tskid )
  243: {
  244:         TCB    *tcb;
  245:         ER     ercd = E_OK;
  246: 
  247:         CHECK_TSKID_SELF(tskid);
  248: 
  249:         tcb = get_tcb_self(tskid);
  250: 
  251:         BEGIN_CRITICAL_SECTION;
  252:         switch ( tcb->state ) {
  253:           case TS_NONEXIST:
  254:                 ercd = E_NOEXS;
  255:                 break;
  256:           case TS_DORMANT:
  257:                 ercd = E_OBJ;
  258:                 break;
  259: 
  260:           default:
  261:                 ercd = tcb->wupcnt;
  262:                 tcb->wupcnt = 0;
  263:         }
  264:         END_CRITICAL_SECTION;
  265: 
  266:         return ercd;
  267: }
  268: #endif /* USE_FUNC_TK_CAN_WUP */
  269: 
  270: #ifdef USE_FUNC_TK_DLY_TSK
  271: /*
  272:  * Definition of task delay wait specification
  273:  */
  274: LOCAL CONST WSPEC knl_wspec_dly = { TTW_DLY, NULL, NULL };
  275: 
  276: /*
  277:  * Task delay
  278:  */
  279: SYSCALL ER tk_dly_tsk( RELTIM dlytim )
  280: {
  281:         ER     ercd = E_OK;
  282: 
  283:         CHECK_RELTIM(dlytim);
  284: 
  285:         CHECK_DISPATCH();
  286: 
  287:         if ( dlytim > 0 ) {
  288:                 BEGIN_CRITICAL_SECTION;
  289:                 knl_ctxtsk->wspec = &knl_wspec_dly;
  290:                 knl_ctxtsk->wid = 0;
  291:                 knl_ctxtsk->wercd = &ercd;
  292:                 knl_make_wait_reltim(dlytim, TA_NULL);
  293:                 QueInit(&knl_ctxtsk->tskque);
  294:                 END_CRITICAL_SECTION;
  295:         }
  296: 
  297:         return ercd;
  298: }
  299: #endif /* USE_FUNC_TK_DLY_TSK */
  300: