gonzui


Format: Advanced Search

tkernel_2/kernel/tkernel/src/task_manage.cbare sourcepermlink (0.06 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 T-Engine Forum at 2014/09/10.
   11:  *    Modified by TRON Forum(http://www.tron.org/) at 2015/06/01.
   12:  *
   13:  *----------------------------------------------------------------------
   14:  */
   15: 
   16: /*
   17:  *      task_manage.c (T-Kernel/OS)
   18:  *      Task Management Function
   19:  */
   20: 
   21: #include "kernel.h"
   22: #include "task.h"
   23: #include "wait.h"
   24: #include "check.h"
   25: #include "cpu_task.h"
   26: #include <tm/tmonitor.h>
   27: 
   28: 
   29: /*
   30:  * Create task
   31:  */
   32: SYSCALL ID _tk_cre_tsk P1( CONST T_CTSK *pk_ctsk )
   33: {
   34: #if CHK_RSATR
   35:         const ATR VALID_TSKATR = {     /* Valid value of task attribute */
   36:                  TA_HLNG
   37:                 |TA_SSTKSZ
   38:                 |TA_USERSTACK
   39:                 |TA_TASKSPACE
   40:                 |TA_RESID
   41:                 |TA_RNG3
   42:                 |TA_FPU
   43:                 |TA_COP0
   44:                 |TA_COP1
   45:                 |TA_COP2
   46:                 |TA_COP3
   47:                 |TA_GP
   48: #if USE_OBJECT_NAME
   49:                 |TA_DSNAME
   50: #endif
   51:         };
   52: #endif
   53:         TCB    *tcb;
   54:         INT    stksz, sstksz, sysmode, resid;
   55:         void   *stack = NULL, *sstack;
   56:         ER     ercd;
   57: 
   58:         CHECK_RSATR(pk_ctsk->tskatr, VALID_TSKATR);
   59:         CHECK_PRI(pk_ctsk->itskpri);
   60:         CHECK_NOCOP(pk_ctsk->tskatr);
   61: #if USE_SINGLE_STACK
   62:         CHECK_NOSPT((pk_ctsk->tskatr & TA_USERSTACK) == 0);
   63: #endif
   64: #if CHK_PAR
   65:         if ( (pk_ctsk->tskatr & TA_USERSTACK) != 0 ) {
   66:                 CHECK_PAR((pk_ctsk->tskatr & TA_RNG3) != TA_RNG0);
   67:                 CHECK_PAR(pk_ctsk->stksz == 0);
   68:         } else {
   69:                 CHECK_PAR(pk_ctsk->stksz >= 0);
   70:         }
   71:         if ( (pk_ctsk->tskatr & TA_TASKSPACE) != 0 ) {
   72:                 CHECK_PAR(pk_ctsk->lsid >= 0 && pk_ctsk->lsid <= MAX_LSID);
   73:         }
   74: #endif
   75: 
   76:         if ( (pk_ctsk->tskatr & TA_RESID) != 0 ) {
   77:                 CHECK_RESID(pk_ctsk->resid);
   78:                 resid = pk_ctsk->resid;
   79:         } else {
   80:                 resid = SYS_RESID; /* System resource group */
   81:         }
   82: 
   83:         if ( (pk_ctsk->tskatr & TA_SSTKSZ) != 0 ) {
   84:                 CHECK_PAR(pk_ctsk->sstksz >= MIN_SYS_STACK_SIZE);
   85:                 sstksz = pk_ctsk->sstksz;
   86:         } else {
   87:                 sstksz = default_sstksz;
   88:         }
   89:         if ( (pk_ctsk->tskatr & TA_RNG3) == TA_RNG0 ) {
   90:                 sysmode = 1;
   91:                 sstksz += pk_ctsk->stksz;
   92:                 stksz = 0;
   93:         } else {
   94:                 sysmode = 0;
   95: #if USE_SINGLE_STACK
   96:                 sstksz += pk_ctsk->stksz;
   97:                 stksz = 0;
   98: #else
   99:                 stksz = pk_ctsk->stksz;
  100: #endif
  101:         }
  102: 
  103:         /* Adjust stack size by 8 bytes */
  104:         sstksz = (sstksz + 7) / 8 * 8;
  105:         stksz  = (stksz  + 7) / 8 * 8;
  106: 
  107:         /* Allocate system stack area */
  108:         sstack = IAmalloc((UINT)sstksz, TA_RNG0);
  109:         if ( sstack == NULL ) {
  110:                 return E_NOMEM;
  111:         }
  112: 
  113:         if ( stksz > 0 ) {
  114:                 /* Allocate user stack area */
  115:                 stack = IAmalloc((UINT)stksz, pk_ctsk->tskatr);
  116:                 if ( stack == NULL ) {
  117:                         IAfree(sstack, TA_RNG0);
  118:                         return E_NOMEM;
  119:                 }
  120:         }
  121: 
  122:         BEGIN_CRITICAL_SECTION;
  123:         /* Get control block from FreeQue */
  124:         tcb = (TCB*)QueRemoveNext(&free_tcb);
  125:         if ( tcb == NULL ) {
  126:                 ercd = E_LIMIT;
  127:                 goto error_exit;
  128:         }
  129: 
  130:         /* Initialize control block */
  131:         tcb->exinf     = pk_ctsk->exinf;
  132:         tcb->tskatr    = pk_ctsk->tskatr;
  133:         tcb->task      = pk_ctsk->task;
  134:         tcb->ipriority = (UB)int_priority(pk_ctsk->itskpri);
  135:         tcb->resid     = resid;
  136:         tcb->stksz     = stksz;
  137:         tcb->sstksz    = sstksz;
  138: #if USE_OBJECT_NAME
  139:         if ( (pk_ctsk->tskatr & TA_DSNAME) != 0 ) {
  140:                 STRNCPY((char*)tcb->name, (char*)pk_ctsk->dsname, OBJECT_NAME_LENGTH);
  141:         }
  142: #endif
  143: #if TA_GP
  144:         /* Set global pointer */
  145:         if ( (pk_ctsk->tskatr & TA_GP) != 0 ) {
  146:                 gp = pk_ctsk->gp;
  147:         }
  148:         tcb->gp = gp;
  149: #endif
  150: 
  151:         /* Set stack pointer */
  152:         if ( stksz > 0 ) {
  153:                 tcb->istack = (VB*)stack + stksz;
  154:         } else {
  155:                 tcb->istack = pk_ctsk->stkptr;
  156:         }
  157:         tcb->isstack = (VB*)sstack + sstksz - RESERVE_SSTACK(tcb->tskatr);
  158: 
  159:         /* Set initial value of task operation mode */
  160:         tcb->isysmode = (B)sysmode;
  161:         tcb->sysmode  = (H)sysmode;
  162: 
  163:         /* Set initial value of task space */
  164:         if ( (pk_ctsk->tskatr & TA_TASKSPACE) != 0 ) {
  165:                 tcb->tskctxb.uatb = pk_ctsk->uatb;
  166:                 tcb->tskctxb.lsid = pk_ctsk->lsid;
  167:         } else {
  168:                 tcb->tskctxb.uatb = NULL;
  169:                 tcb->tskctxb.lsid = 0;                /* Task Space */
  170:         }
  171: 
  172:         /* make it to DORMANT state */
  173:         make_dormant(tcb);
  174: 
  175:         ercd = tcb->tskid;
  176: 
  177:     error_exit:
  178:         END_CRITICAL_SECTION;
  179: 
  180:         if ( ercd < E_OK ) {
  181:                 IAfree(sstack, TA_RNG0);
  182:                 if ( stksz > 0 ) {
  183:                         IAfree(stack, pk_ctsk->tskatr);
  184:                 }
  185:         }
  186: 
  187:         return ercd;
  188: }
  189: 
  190: /*
  191:  * Task deletion
  192:  *      Call from critical section
  193:  */
  194: LOCAL void _del_tsk( TCB *tcb )
  195: {
  196:         void   *stack;
  197: 
  198:         /* Free system stack */
  199:         stack = (VB*)tcb->isstack + RESERVE_SSTACK(tcb->tskatr) - tcb->sstksz;
  200:         IAfree(stack, TA_RNG0);
  201: 
  202:         if ( tcb->stksz > 0 ) {
  203:                 /* Free user stack */
  204:                 stack = (VB*)tcb->istack - tcb->stksz;
  205:                 IAfree(stack, tcb->tskatr);
  206:         }
  207: 
  208:         /* Return control block to FreeQue */
  209:         QueInsert(&tcb->tskque, &free_tcb);
  210:         tcb->state = TS_NONEXIST;
  211: }
  212: 
  213: /*
  214:  * Delete task
  215:  */
  216: SYSCALL ER _tk_del_tsk( ID tskid )
  217: {
  218:         TCB    *tcb;
  219:         TSTAT  state;
  220:         ER     ercd = E_OK;
  221: 
  222:         CHECK_TSKID(tskid);
  223:         CHECK_NONSELF(tskid);
  224: 
  225:         tcb = get_tcb(tskid);
  226: 
  227:         BEGIN_CRITICAL_SECTION;
  228:         state = (TSTAT)tcb->state;
  229:         if ( state != TS_DORMANT ) {
  230:                 ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ;
  231:         } else {
  232:                 _del_tsk(tcb);
  233:         }
  234:         END_CRITICAL_SECTION;
  235: 
  236:         return ercd;
  237: }
  238: 
  239: /* ------------------------------------------------------------------------ */
  240: 
  241: /*
  242:  * Start task
  243:  */
  244: SYSCALL ER _tk_sta_tsk( ID tskid, INT stacd )
  245: {
  246:         TCB    *tcb;
  247:         TSTAT  state;
  248:         ER     ercd = E_OK;
  249: 
  250:         CHECK_TSKID(tskid);
  251:         CHECK_NONSELF(tskid);
  252: 
  253:         tcb = get_tcb(tskid);
  254: 
  255:         BEGIN_CRITICAL_SECTION;
  256:         state = (TSTAT)tcb->state;
  257:         if ( state != TS_DORMANT ) {
  258:                 ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ;
  259:         } else {
  260:                 setup_stacd(tcb, stacd);
  261:                 make_ready(tcb);
  262:         }
  263:         END_CRITICAL_SECTION;
  264: 
  265:         return ercd;
  266: }
  267: 
  268: /*
  269:  * Task finalization
  270:  *      Call from critical section
  271:  */
  272: LOCAL void _ter_tsk( TCB *tcb )
  273: {
  274:         TSTAT  state;
  275: 
  276:         if ( tcb->svclocked != NULL ) {
  277:                 /* Unlock all extended SVC locks */
  278:                 AllUnlockSVC(tcb);
  279:         }
  280: 
  281:         state = (TSTAT)tcb->state;
  282:         if ( state == TS_READY ) {
  283:                 make_non_ready(tcb);
  284: 
  285:         } else if ( (state & TS_WAIT) != 0 ) {
  286:                 wait_cancel(tcb);
  287:                 if ( tcb->wspec->rel_wai_hook != NULL ) {
  288:                         (*tcb->wspec->rel_wai_hook)(tcb);
  289:                 }
  290:         }
  291: 
  292: #ifdef NUM_MTXID
  293:         /* signal mutex */
  294:         signal_all_mutex(tcb);
  295: #endif
  296: 
  297:         cleanup_context(tcb);
  298: }
  299: 
  300: /*
  301:  * End its own task
  302:  */
  303: SYSCALL void _tk_ext_tsk( void )
  304: {
  305: #ifdef DORMANT_STACK_SIZE
  306:         /* To avoid destroying stack used in 'make_dormant',
  307:            allocate the dummy area on the stack. */
  308:         volatile VB _dummy[DORMANT_STACK_SIZE];
  309: #endif
  310: 
  311:         /* Check context error */
  312: #if CHK_CTX2
  313:         if ( in_indp() ) {
  314: #if USE_KERNEL_MESSAGE
  315:                 tm_putstring((UB*)"tk_ext_tsk was called in the task independent\n");
  316: #endif
  317:                 tm_monitor(); /* To monitor */
  318:         }
  319: #endif
  320: #if CHK_CTX1
  321:         if ( in_ddsp() ) {
  322: #if USE_KERNEL_MESSAGE
  323:                 tm_putstring((UB*)"tk_ext_tsk was called in the dispatch disabled\n");
  324: #endif
  325:         }
  326: #endif
  327: 
  328:         DISABLE_INTERRUPT;
  329:         _ter_tsk(ctxtsk);
  330:         make_dormant(ctxtsk);
  331: 
  332:         force_dispatch();
  333:         /* No return */
  334: 
  335: #ifdef DORMANT_STACK_SIZE
  336:         /* for WARNING */
  337:         _dummy[0] = 0;
  338: #endif
  339: }
  340: 
  341: /*
  342:  * End and delete its own task
  343:  */
  344: SYSCALL void _tk_exd_tsk( void )
  345: {
  346:         /* Check context error */
  347: #if CHK_CTX2
  348:         if ( in_indp() ) {
  349: #if USE_KERNEL_MESSAGE
  350:                 tm_putstring((UB*)"tk_exd_tsk was called in the task independent\n");
  351: #endif
  352:                 tm_monitor(); /* To monitor */
  353:         }
  354: #endif
  355: #if CHK_CTX1
  356:         if ( in_ddsp() ) {
  357: #if USE_KERNEL_MESSAGE
  358:                 tm_putstring((UB*)"tk_exd_tsk was called in the dispatch disabled\n");
  359: #endif
  360:         }
  361: #endif
  362: 
  363:         DISABLE_INTERRUPT;
  364:         _ter_tsk(ctxtsk);
  365:         _del_tsk(ctxtsk);
  366: 
  367:         force_dispatch();
  368:         /* No return */
  369: }
  370: 
  371: /*
  372:  * Termination of other task
  373:  */
  374: SYSCALL ER _tk_ter_tsk( ID tskid )
  375: {
  376:         TCB    *tcb;
  377:         TSTAT  state;
  378:         ER     ercd = E_OK;
  379: 
  380:         CHECK_TSKID(tskid);
  381:         CHECK_NONSELF(tskid);
  382: 
  383:         tcb = get_tcb(tskid);
  384: 
  385:         BEGIN_CRITICAL_SECTION;
  386:         state = (TSTAT)tcb->state;
  387:         if ( !task_alive(state) ) {
  388:                 ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ;
  389:         } else if ( tcb->klocked ) {
  390:                 /* Normally, it does not become this state.
  391:                  * When the state is page-in wait in the virtual memory
  392:                  * system and when trying to terminate any task,
  393:                  * it becomes this state.
  394:                  */
  395:                 ercd = E_OBJ;
  396:         } else {
  397:                 _ter_tsk(tcb);
  398:                 make_dormant(tcb);
  399:         }
  400:         END_CRITICAL_SECTION;
  401: 
  402:         return ercd;
  403: }
  404: 
  405: /* ------------------------------------------------------------------------ */
  406: 
  407: /*
  408:  * Change task priority
  409:  */
  410: SYSCALL ER _tk_chg_pri( ID tskid, PRI tskpri )
  411: {
  412:         TCB    *tcb;
  413:         INT    priority;
  414:         ER     ercd;
  415: 
  416:         CHECK_TSKID_SELF(tskid);
  417:         CHECK_PRI_INI(tskpri);
  418: 
  419:         tcb = get_tcb_self(tskid);
  420: 
  421:         BEGIN_CRITICAL_SECTION;
  422:         if ( tcb->state == TS_NONEXIST ) {
  423:                 ercd = E_NOEXS;
  424:                 goto error_exit;
  425:         }
  426: 
  427:         /* Conversion priority to internal expression */
  428:         if ( tskpri == TPRI_INI ) {
  429:                 priority = tcb->ipriority;
  430:         } else {
  431:                 priority = int_priority(tskpri);
  432:         }
  433: 
  434: #ifdef NUM_MTXID
  435:         /* Mutex priority change limit */
  436:         ercd = chg_pri_mutex(tcb, priority);
  437:         if ( ercd < E_OK ) {
  438:                 goto error_exit;
  439:         }
  440: 
  441:         tcb->bpriority = (UB)priority;
  442:         priority = ercd;
  443: #else
  444:         tcb->bpriority = priority;
  445: #endif
  446: 
  447:         /* Change priority */
  448:         change_task_priority(tcb, priority);
  449: 
  450:         ercd = E_OK;
  451:     error_exit:
  452:         END_CRITICAL_SECTION;
  453: 
  454:         return ercd;
  455: }
  456: 
  457: /*
  458:  * Rotate ready queue
  459:  */
  460: SYSCALL ER _tk_rot_rdq( PRI tskpri )
  461: {
  462:         CHECK_PRI_RUN(tskpri);
  463: 
  464:         BEGIN_CRITICAL_SECTION;
  465:         if ( tskpri == TPRI_RUN ) {
  466:                 if ( in_indp() ) {
  467:                         rotate_ready_queue_run();
  468:                 } else {
  469:                         rotate_ready_queue(ctxtsk->priority);
  470:                 }
  471:         } else {
  472:                 rotate_ready_queue(int_priority(tskpri));
  473:         }
  474:         END_CRITICAL_SECTION;
  475: 
  476:         return E_OK;
  477: }
  478: 
  479: /*
  480:  * Change slice time
  481:  */
  482: SYSCALL ER _tk_chg_slt( ID tskid, RELTIM slicetime )
  483: {
  484:         return _tk_chg_slt_u(tskid, to_usec(slicetime));
  485: }
  486: 
  487: SYSCALL ER _tk_chg_slt_u( ID tskid, RELTIM_U slicetime )
  488: {
  489:         TCB    *tcb;
  490:         ER     ercd = E_OK;
  491: 
  492:         CHECK_TSKID_SELF(tskid);
  493: 
  494:         tcb = get_tcb_self(tskid);
  495: 
  496:         BEGIN_CRITICAL_SECTION;
  497:         if ( tcb->state == TS_NONEXIST ) {
  498:                 ercd = E_NOEXS;
  499:         } else {
  500:                 tcb->slicetime = slicetime;
  501:         }
  502:         END_CRITICAL_SECTION;
  503: 
  504:         return ercd;
  505: }
  506: 
  507: /* ------------------------------------------------------------------------ */
  508: 
  509: /*
  510:  * Refer task ID at execution
  511:  */
  512: SYSCALL ID _tk_get_tid( void )
  513: {
  514:         return ( ctxtsk == NULL )? 0: ctxtsk->tskid;
  515: }
  516: 
  517: /*
  518:  * Refer task state
  519:  */
  520: SYSCALL ER _tk_ref_tsk( ID tskid, T_RTSK *pk_rtsk )
  521: {
  522:         T_RTSK_U lrtsk;
  523:         ER     ercd;
  524: 
  525:         ercd = _tk_ref_tsk_u(tskid, &lrtsk);
  526: 
  527:         pk_rtsk->exinf    = lrtsk.exinf;
  528:         pk_rtsk->tskpri           = lrtsk.tskpri;
  529:         pk_rtsk->tskbpri   = lrtsk.tskbpri;
  530:         pk_rtsk->tskstat   = lrtsk.tskstat;
  531:         pk_rtsk->tskwait   = lrtsk.tskwait;
  532:         pk_rtsk->wid      = lrtsk.wid;
  533:         pk_rtsk->wupcnt           = lrtsk.wupcnt;
  534:         pk_rtsk->suscnt           = lrtsk.suscnt;
  535:         pk_rtsk->slicetime = to_msec(lrtsk.slicetime_u);
  536:         pk_rtsk->waitmask  = lrtsk.waitmask;
  537:         pk_rtsk->texmask   = lrtsk.texmask;
  538:         pk_rtsk->tskevent  = lrtsk.tskevent;
  539: 
  540:         return ercd;
  541: }
  542: 
  543: SYSCALL ER _tk_ref_tsk_u( ID tskid, T_RTSK_U *pk_rtsk )
  544: {
  545:         TCB    *tcb;
  546:         TSTAT  state;
  547:         ER     ercd = E_OK;
  548: 
  549:         CHECK_TSKID_SELF(tskid);
  550: 
  551:         tcb = get_tcb_self(tskid);
  552: 
  553:         MEMSET(pk_rtsk, 0, sizeof(*pk_rtsk));
  554: 
  555:         BEGIN_CRITICAL_SECTION;
  556:         state = (TSTAT)tcb->state;
  557:         if ( state == TS_NONEXIST ) {
  558:                 ercd = E_NOEXS;
  559:         } else {
  560:                 if ( ( state == TS_READY ) && ( tcb == ctxtsk ) ) {
  561:                         pk_rtsk->tskstat = TTS_RUN;
  562:                 } else {
  563:                         pk_rtsk->tskstat = (UINT)state << 1;
  564:                 }
  565:                 if ( (state & TS_WAIT) != 0 ) {
  566:                         pk_rtsk->tskwait = tcb->wspec->tskwait;
  567:                         pk_rtsk->wid     = tcb->wid;
  568:                         if ( tcb->nodiswai ) {
  569:                                 pk_rtsk->tskstat |= TTS_NODISWAI;
  570:                         }
  571:                 }
  572:                 pk_rtsk->exinf             = tcb->exinf;
  573:                 pk_rtsk->tskpri            = ext_tskpri(tcb->priority);
  574:                 pk_rtsk->tskbpri     = ext_tskpri(tcb->bpriority);
  575:                 pk_rtsk->wupcnt            = tcb->wupcnt;
  576:                 pk_rtsk->suscnt            = tcb->suscnt;
  577:                 pk_rtsk->slicetime_u = tcb->slicetime;
  578:                 pk_rtsk->waitmask    = tcb->waitmask;
  579:                 pk_rtsk->texmask     = tcb->texmask;
  580:                 pk_rtsk->tskevent    = tcb->tskevt;
  581:         }
  582:         END_CRITICAL_SECTION;
  583: 
  584:         return ercd;
  585: }
  586: 
  587: /*
  588:  * Get task statistic information
  589:  */
  590: SYSCALL ER _tk_inf_tsk( ID tskid, T_ITSK *pk_itsk, BOOL clr )
  591: {
  592:         T_ITSK_U litsk;
  593:         ER     ercd;
  594: 
  595:         ercd = _tk_inf_tsk_u(tskid, &litsk, clr);
  596: 
  597:         pk_itsk->stime = to_msec(litsk.stime_u);
  598:         pk_itsk->utime = to_msec(litsk.utime_u);
  599: 
  600:         return ercd;
  601: }
  602: 
  603: SYSCALL ER _tk_inf_tsk_u( ID tskid, T_ITSK_U *pk_itsk, BOOL clr )
  604: {
  605:         TCB    *tcb;
  606:         ER     ercd = E_OK;
  607: 
  608:         CHECK_TSKID_SELF(tskid);
  609: 
  610:         tcb = get_tcb_self(tskid);
  611: 
  612:         BEGIN_CRITICAL_SECTION;
  613:         if ( tcb->state == TS_NONEXIST ) {
  614:                 ercd = E_NOEXS;
  615:         } else {
  616:                 pk_itsk->stime_u = tcb->stime;
  617:                 pk_itsk->utime_u = tcb->utime;
  618:                 if ( clr ) {
  619:                         tcb->stime = 0;
  620:                         tcb->utime = 0;
  621:                 }
  622:         }
  623:         END_CRITICAL_SECTION;
  624: 
  625:         return ercd;
  626: }
  627: 
  628: /* ------------------------------------------------------------------------ */
  629: 
  630: /*
  631:  * Get task resource group
  632:  */
  633: SYSCALL ID _tk_get_rid( ID tskid )
  634: {
  635:         TCB    *tcb;
  636:         ER     ercd;
  637: 
  638:         CHECK_TSKID_SELF(tskid);
  639: 
  640:         tcb = get_tcb_self(tskid);
  641: 
  642:         BEGIN_CRITICAL_SECTION;
  643:         if ( tcb->state == TS_NONEXIST ) {
  644:                 ercd = E_NOEXS;
  645:         } else {
  646:                 ercd = tcb->resid;
  647:         }
  648:         END_CRITICAL_SECTION;
  649: 
  650:         return ercd;
  651: }
  652: 
  653: /*
  654:  * Set task resource group
  655:  */
  656: SYSCALL ID _tk_set_rid( ID tskid, ID resid )
  657: {
  658:         TCB    *tcb;
  659:         ER     ercd;
  660: 
  661:         CHECK_TSKID_SELF(tskid);
  662:         CHECK_RESID(resid);
  663: 
  664:         tcb = get_tcb_self(tskid);
  665: 
  666:         BEGIN_CRITICAL_SECTION;
  667:         if ( tcb->state == TS_NONEXIST ) {
  668:                 ercd = E_NOEXS;
  669:         } else {
  670:                 ercd = tcb->resid;
  671:                 tcb->resid = resid;
  672:         }
  673:         END_CRITICAL_SECTION;
  674: 
  675:         return ercd;
  676: }
  677: 
  678: /* ------------------------------------------------------------------------ */
  679: 
  680: /*
  681:  * Release wait
  682:  */
  683: SYSCALL ER _tk_rel_wai( ID tskid )
  684: {
  685:         TCB    *tcb;
  686:         TSTAT  state;
  687:         ER     ercd = E_OK;
  688: 
  689:         CHECK_TSKID(tskid);
  690: 
  691:         tcb = get_tcb(tskid);
  692: 
  693:         BEGIN_CRITICAL_SECTION;
  694:         state = (TSTAT)tcb->state;
  695:         if ( (state & TS_WAIT) == 0 ) {
  696:                 ercd = ( state == TS_NONEXIST )? E_NOEXS: E_OBJ;
  697:         } else {
  698:                 wait_release_ng(tcb, E_RLWAI);
  699:         }
  700:         END_CRITICAL_SECTION;
  701: 
  702:         return ercd;
  703: }
  704: 
  705: /*
  706:  * Disable task wait
  707:  */
  708: #define WAIT_PATTERN    ( TTW_SLP  | TTW_DLY  | TTW_SEM | TTW_FLG  \
  709:                                               | TTW_MBX | TTW_MTX  \
  710:                         | TTW_SMBF | TTW_RMBF | TTW_CAL | TTW_ACP  \
  711:                         | TTW_RDV  | TTW_MPF  | TTW_MPL            \
  712:                         | TTW_EV1  | TTW_EV2  | TTW_EV3 | TTW_EV4  \
  713:                         | TTW_EV5  | TTW_EV6  | TTW_EV7 | TTW_EV8  \
  714:                         | TTX_SVC )
  715: 
  716: SYSCALL INT _tk_dis_wai( ID tskid, UINT waitmask )
  717: {
  718:         TCB    *tcb;
  719:         UINT   tskwait = 0;
  720:         ER     ercd = E_OK;
  721: 
  722:         CHECK_TSKID_SELF(tskid);
  723:         CHECK_PAR(((waitmask & ~WAIT_PATTERN) == 0)&&((waitmask & WAIT_PATTERN) != 0));
  724: 
  725:         tcb = get_tcb_self(tskid);
  726: 
  727:         BEGIN_CRITICAL_SECTION;
  728:         if ( tcb->state == TS_NONEXIST ) {
  729:                 ercd = E_NOEXS;
  730:                 goto error_exit;
  731:         }
  732: 
  733:         /* Update wait disable mask */
  734:         tcb->waitmask = waitmask;
  735: 
  736:         if ( (tcb->state & TS_WAIT) != 0 ) {
  737:                 tskwait = tcb->wspec->tskwait;
  738:                 if ( (tskwait & waitmask) != 0 && !tcb->nodiswai ) {
  739:                         /* Free wait */
  740:                         wait_release_ng(tcb, E_DISWAI);
  741:                         tskwait = 0;
  742:                 }
  743:         }
  744: 
  745:     error_exit:
  746:         END_CRITICAL_SECTION;
  747: 
  748:         return ( ercd < E_OK )? (INT)ercd: (INT)tskwait;
  749: }
  750: 
  751: /*
  752:  * Enable task wait
  753:  */
  754: SYSCALL ER _tk_ena_wai( ID tskid )
  755: {
  756:         TCB    *tcb;
  757:         ER     ercd = E_OK;
  758: 
  759:         CHECK_TSKID_SELF(tskid);
  760: 
  761:         tcb = get_tcb_self(tskid);
  762: 
  763:         BEGIN_CRITICAL_SECTION;
  764:         if ( tcb->state == TS_NONEXIST ) {
  765:                 ercd = E_NOEXS;
  766:         } else {
  767:                 tcb->waitmask = 0;
  768:         }
  769:         END_CRITICAL_SECTION;
  770: 
  771:         return ercd;
  772: }
  773: 
  774: /* ------------------------------------------------------------------------ */
  775: /*
  776:  *      Debug support function
  777:  */
  778: #if USE_DBGSPT
  779: 
  780: /*
  781:  * Get object name from control block
  782:  */
  783: #if USE_OBJECT_NAME
  784: EXPORT ER task_getname(ID id, UB **name)
  785: {
  786:         TCB    *tcb;
  787:         ER     ercd = E_OK;
  788: 
  789:         CHECK_TSKID_SELF(id);
  790: 
  791:         BEGIN_DISABLE_INTERRUPT;
  792:         tcb = get_tcb_self(id);
  793:         if ( tcb->state == TS_NONEXIST ) {
  794:                 ercd = E_NOEXS;
  795:                 goto error_exit;
  796:         }
  797:         if ( (tcb->tskatr & TA_DSNAME) == 0 ) {
  798:                 ercd = E_OBJ;
  799:                 goto error_exit;
  800:         }
  801:         *name = tcb->name;
  802: 
  803:     error_exit:
  804:         END_DISABLE_INTERRUPT;
  805: 
  806:         return ercd;
  807: }
  808: #endif /* USE_OBJECT_NAME */
  809: 
  810: /*
  811:  * Refer task usage state
  812:  */
  813: SYSCALL INT _td_lst_tsk( ID list[], INT nent )
  814: {
  815:         TCB    *tcb, *end;
  816:         INT    n = 0;
  817: 
  818:         BEGIN_DISABLE_INTERRUPT;
  819:         end = tcb_table + NUM_TSKID;
  820:         for ( tcb = tcb_table; tcb < end; tcb++ ) {
  821:                 if ( tcb->state == TS_NONEXIST ) {
  822:                         continue;
  823:                 }
  824: 
  825:                 if ( n++ < nent ) {
  826:                         *list++ = tcb->tskid;
  827:                 }
  828:         }
  829:         END_DISABLE_INTERRUPT;
  830: 
  831:         return n;
  832: }
  833: 
  834: /*
  835:  * Refer task state
  836:  */
  837: SYSCALL ER _td_ref_tsk( ID tskid, TD_RTSK *pk_rtsk )
  838: {
  839:         TD_RTSK_U      lrtsk;
  840:         ER             ercd;
  841: 
  842:         ercd = _td_ref_tsk_u(tskid, &lrtsk);
  843: 
  844:         pk_rtsk->exinf    = lrtsk.exinf;
  845:         pk_rtsk->tskpri           = lrtsk.tskpri;
  846:         pk_rtsk->tskbpri   = lrtsk.tskbpri;
  847:         pk_rtsk->tskstat   = lrtsk.tskstat;
  848:         pk_rtsk->tskwait   = lrtsk.tskwait;
  849:         pk_rtsk->wid      = lrtsk.wid;
  850:         pk_rtsk->wupcnt           = lrtsk.wupcnt;
  851:         pk_rtsk->suscnt           = lrtsk.suscnt;
  852:         pk_rtsk->slicetime = to_msec(lrtsk.slicetime_u);
  853:         pk_rtsk->waitmask  = lrtsk.waitmask;
  854:         pk_rtsk->texmask   = lrtsk.texmask;
  855:         pk_rtsk->tskevent  = lrtsk.tskevent;
  856:         pk_rtsk->task     = lrtsk.task;
  857:         pk_rtsk->stksz    = lrtsk.stksz;
  858:         pk_rtsk->sstksz           = lrtsk.sstksz;
  859:         pk_rtsk->istack           = lrtsk.istack;
  860:         pk_rtsk->isstack   = lrtsk.isstack;
  861: 
  862:         return ercd;
  863: }
  864: 
  865: SYSCALL ER _td_ref_tsk_u( ID tskid, TD_RTSK_U *pk_rtsk )
  866: {
  867:         TCB    *tcb;
  868:         TSTAT  state;
  869:         ER     ercd = E_OK;
  870: 
  871:         CHECK_TSKID_SELF(tskid);
  872: 
  873:         tcb = get_tcb_self(tskid);
  874: 
  875:         MEMSET(pk_rtsk, 0, sizeof(*pk_rtsk));
  876: 
  877:         BEGIN_DISABLE_INTERRUPT;
  878:         state = (TSTAT)tcb->state;
  879:         if ( state == TS_NONEXIST ) {
  880:                 ercd = E_NOEXS;
  881:         } else {
  882:                 if ( ( state == TS_READY ) && ( tcb == ctxtsk ) ) {
  883:                         pk_rtsk->tskstat = TTS_RUN;
  884:                 } else {
  885:                         pk_rtsk->tskstat = (UINT)state << 1;
  886:                 }
  887:                 if ( (state & TS_WAIT) != 0 ) {
  888:                         pk_rtsk->tskwait = tcb->wspec->tskwait;
  889:                         pk_rtsk->wid     = tcb->wid;
  890:                         if ( ctxtsk->nodiswai ) {
  891:                                 pk_rtsk->tskstat |= TTS_NODISWAI;
  892:                         }
  893:                 }
  894:                 pk_rtsk->exinf             = tcb->exinf;
  895:                 pk_rtsk->tskpri            = ext_tskpri(tcb->priority);
  896:                 pk_rtsk->tskbpri     = ext_tskpri(tcb->bpriority);
  897:                 pk_rtsk->wupcnt            = tcb->wupcnt;
  898:                 pk_rtsk->suscnt            = tcb->suscnt;
  899:                 pk_rtsk->slicetime_u = tcb->slicetime;
  900:                 pk_rtsk->waitmask    = tcb->waitmask;
  901:                 pk_rtsk->texmask     = tcb->texmask;
  902:                 pk_rtsk->tskevent    = tcb->tskevt;
  903: 
  904:                 pk_rtsk->task      = tcb->task;
  905:                 pk_rtsk->stksz     = tcb->stksz;
  906:                 pk_rtsk->sstksz    = tcb->sstksz - RESERVE_SSTACK(tcb->tskatr);
  907:                 pk_rtsk->istack    = tcb->istack;
  908:                 pk_rtsk->isstack   = tcb->isstack;
  909:         }
  910:         END_DISABLE_INTERRUPT;
  911: 
  912:         return ercd;
  913: }
  914: 
  915: /*
  916:  * Get task statistic information
  917:  */
  918: SYSCALL ER _td_inf_tsk( ID tskid, TD_ITSK *pk_itsk, BOOL clr )
  919: {
  920:         TD_ITSK_U      litsk;
  921:         ER             ercd;
  922: 
  923:         ercd = _td_inf_tsk_u(tskid, &litsk, clr);
  924: 
  925:         pk_itsk->stime = to_msec(litsk.stime_u);
  926:         pk_itsk->utime = to_msec(litsk.utime_u);
  927: 
  928:         return ercd;
  929: }
  930: 
  931: SYSCALL ER _td_inf_tsk_u( ID tskid, TD_ITSK_U *pk_itsk, BOOL clr )
  932: {
  933:         TCB    *tcb;
  934:         ER     ercd = E_OK;
  935: 
  936:         CHECK_TSKID_SELF(tskid);
  937: 
  938:         tcb = get_tcb_self(tskid);
  939: 
  940:         BEGIN_DISABLE_INTERRUPT;
  941:         if ( tcb->state == TS_NONEXIST ) {
  942:                 ercd = E_NOEXS;
  943:         } else {
  944:                 pk_itsk->stime_u = tcb->stime;
  945:                 pk_itsk->utime_u = tcb->utime;
  946:                 if ( clr ) {
  947:                         tcb->stime = 0;
  948:                         tcb->utime = 0;
  949:                 }
  950:         }
  951:         END_DISABLE_INTERRUPT;
  952: 
  953:         return ercd;
  954: }
  955: 
  956: #endif /* USE_DBGSPT */