ER_UINT can_wup(ID tskid) { TCB *p_tcb; ER_UINT ercd; LOG_CAN_WUP_ENTER(tskid); CHECK_TSKCTX_UNL(); if (tskid == TSK_SELF) { p_tcb = p_runtsk; } else { CHECK_ID(VALID_TSKID(tskid)); p_tcb = get_tcb(tskid); } CHECK_NOSPT((p_tcb->p_tinib->tskatr & TA_RSTR) == 0U); /*[NGKI1279]*/ lock_cpu(); if (TSTAT_DORMANT(p_tcb->tstat)) { ercd = E_OBJ; } else { ercd = p_tcb->wupque ? 1 : 0; p_tcb->wupque = false; } unlock_cpu(); error_exit: LOG_CAN_WUP_LEAVE(ercd); return(ercd); }
ER sus_tsk(ID tskid) { TCB *p_tcb; ER ercd; LOG_SUS_TSK_ENTER(tskid); CHECK_TSKCTX_UNL(); /*[NGKI1299][NGKI1300]*/ if (tskid == TSK_SELF) { p_tcb = p_runtsk; /*[NGKI1310]*/ } else { CHECK_ID(VALID_TSKID(tskid)); /*[NGKI1302]*/ p_tcb = get_tcb(tskid); } CHECK_NOSPT((p_tcb->p_tinib->tskatr & TA_RSTR) == 0U); /*[NGKI1301]*/ lock_cpu(); if (p_tcb == p_runtsk && !dspflg) { /*[NGKI1311][NGKI3604]*/ ercd = E_CTX; } else if (TSTAT_DORMANT(p_tcb->tstat)) { ercd = E_OBJ; /*[NGKI1305]*/ } else if (p_tcb->raster) { ercd = E_RASTER; /*[NGKI3605]*/ } else if (TSTAT_RUNNABLE(p_tcb->tstat)) { /* * 実行できる状態から強制待ち状態への遷移[NGKI1307] */ p_tcb->tstat = TS_SUSPENDED; LOG_TSKSTAT(p_tcb); make_non_runnable(p_tcb); if (p_runtsk != p_schedtsk) { dispatch(); } ercd = E_OK; } else if (TSTAT_SUSPENDED(p_tcb->tstat)) { ercd = E_QOVR; /*[NGKI1306]*/ } else { /* * 待ち状態から二重待ち状態への遷移[NGKI1308] */ p_tcb->tstat |= TS_SUSPENDED; LOG_TSKSTAT(p_tcb); ercd = E_OK; } unlock_cpu(); error_exit: LOG_SUS_TSK_LEAVE(ercd); return(ercd); }
ER wup_tsk(ID tskid) { TCB *p_tcb; ER ercd; LOG_WUP_TSK_ENTER(tskid); CHECK_UNL(); if (tskid == TSK_SELF && !sense_context()) { p_tcb = p_runtsk; } else { CHECK_ID(VALID_TSKID(tskid)); p_tcb = get_tcb(tskid); } CHECK_NOSPT((p_tcb->p_tinib->tskatr & TA_RSTR) == 0U); /*[NGKI1266]*/ lock_cpu(); if (TSTAT_DORMANT(p_tcb->tstat)) { ercd = E_OBJ; } else if (TSTAT_WAIT_SLP(p_tcb->tstat)) { wait_complete(p_tcb); if (p_runtsk != p_schedtsk) { if (!sense_context()) { dispatch(); } else { request_dispatch(); } } ercd = E_OK; } else if (!(p_tcb->wupque)) { p_tcb->wupque = true; ercd = E_OK; } else { ercd = E_QOVR; } unlock_cpu(); error_exit: LOG_WUP_TSK_LEAVE(ercd); return(ercd); }
ER rsm_tsk(ID tskid) { TCB *p_tcb; ER ercd; LOG_RSM_TSK_ENTER(tskid); CHECK_TSKCTX_UNL(); CHECK_ID(VALID_TSKID(tskid)); p_tcb = get_tcb(tskid); CHECK_NOSPT((p_tcb->p_tinib->tskatr & TA_RSTR) == 0U); /*[NGKI1315]*/ lock_cpu(); if (!TSTAT_SUSPENDED(p_tcb->tstat)) { ercd = E_OBJ; } else if (!TSTAT_WAITING(p_tcb->tstat)) { /* * 強制待ち状態から実行できる状態への遷移 */ p_tcb->tstat = TS_RUNNABLE; LOG_TSKSTAT(p_tcb); make_runnable(p_tcb); if (p_runtsk != p_schedtsk) { dispatch(); } ercd = E_OK; } else { /* * 二重待ち状態から待ち状態への遷移 */ p_tcb->tstat &= ~TS_SUSPENDED; LOG_TSKSTAT(p_tcb); ercd = E_OK; } unlock_cpu(); error_exit: LOG_RSM_TSK_LEAVE(ercd); return(ercd); }
ER rel_wai(ID tskid) { TCB *p_tcb; ER ercd; LOG_REL_WAI_ENTER(tskid); CHECK_UNL(); CHECK_ID(VALID_TSKID(tskid)); p_tcb = get_tcb(tskid); CHECK_NOSPT((p_tcb->p_tinib->tskatr & TA_RSTR) == 0U); /*[NGKI1291]*/ lock_cpu(); if (!TSTAT_WAITING(p_tcb->tstat)) { ercd = E_OBJ; } else { wait_dequeue_wobj(p_tcb); wait_dequeue_tmevtb(p_tcb); p_tcb->p_winfo->wercd = E_RLWAI; make_non_wait(p_tcb); if (p_runtsk != p_schedtsk) { if (!sense_context()) { dispatch(); } else { request_dispatch(); } } ercd = E_OK; } unlock_cpu(); error_exit: LOG_REL_WAI_LEAVE(ercd); return(ercd); }
/* * Create task */ SYSCALL ID _tk_cre_tsk P1( CONST T_CTSK *pk_ctsk ) { #if CHK_RSATR const ATR VALID_TSKATR = { /* Valid value of task attribute */ TA_HLNG |TA_SSTKSZ |TA_USERSTACK |TA_TASKSPACE |TA_RESID |TA_RNG3 |TA_FPU |TA_COP0 |TA_COP1 |TA_COP2 |TA_COP3 |TA_GP #if USE_OBJECT_NAME |TA_DSNAME #endif }; #endif TCB *tcb; INT stksz, sstksz, sysmode, resid; void *stack = NULL, *sstack; ER ercd; CHECK_RSATR(pk_ctsk->tskatr, VALID_TSKATR); CHECK_PRI(pk_ctsk->itskpri); CHECK_NOCOP(pk_ctsk->tskatr); #if USE_SINGLE_STACK CHECK_NOSPT((pk_ctsk->tskatr & TA_USERSTACK) == 0); #endif #if CHK_PAR if ( (pk_ctsk->tskatr & TA_USERSTACK) != 0 ) { CHECK_PAR((pk_ctsk->tskatr & TA_RNG3) != TA_RNG0); CHECK_PAR(pk_ctsk->stksz == 0); } else { CHECK_PAR(pk_ctsk->stksz >= 0); } if ( (pk_ctsk->tskatr & TA_TASKSPACE) != 0 ) { CHECK_PAR(pk_ctsk->lsid >= 0 && pk_ctsk->lsid <= MAX_LSID); } #endif if ( (pk_ctsk->tskatr & TA_RESID) != 0 ) { CHECK_RESID(pk_ctsk->resid); resid = pk_ctsk->resid; } else { resid = SYS_RESID; /* System resource group */ } if ( (pk_ctsk->tskatr & TA_SSTKSZ) != 0 ) { CHECK_PAR(pk_ctsk->sstksz >= MIN_SYS_STACK_SIZE); sstksz = pk_ctsk->sstksz; } else { sstksz = default_sstksz; } if ( (pk_ctsk->tskatr & TA_RNG3) == TA_RNG0 ) { sysmode = 1; sstksz += pk_ctsk->stksz; stksz = 0; } else { sysmode = 0; #if USE_SINGLE_STACK sstksz += pk_ctsk->stksz; stksz = 0; #else stksz = pk_ctsk->stksz; #endif } /* Adjust stack size by 8 bytes */ sstksz = (sstksz + 7) / 8 * 8; stksz = (stksz + 7) / 8 * 8; /* Allocate system stack area */ sstack = IAmalloc((UINT)sstksz, TA_RNG0); if ( sstack == NULL ) { return E_NOMEM; } if ( stksz > 0 ) { /* Allocate user stack area */ stack = IAmalloc((UINT)stksz, pk_ctsk->tskatr); if ( stack == NULL ) { IAfree(sstack, TA_RNG0); return E_NOMEM; } } BEGIN_CRITICAL_SECTION; /* Get control block from FreeQue */ tcb = (TCB*)QueRemoveNext(&free_tcb); if ( tcb == NULL ) { ercd = E_LIMIT; goto error_exit; } /* Initialize control block */ tcb->exinf = pk_ctsk->exinf; tcb->tskatr = pk_ctsk->tskatr; tcb->task = pk_ctsk->task; tcb->ipriority = (UB)int_priority(pk_ctsk->itskpri); tcb->resid = resid; tcb->stksz = stksz; tcb->sstksz = sstksz; #if USE_OBJECT_NAME if ( (pk_ctsk->tskatr & TA_DSNAME) != 0 ) { STRNCPY((char*)tcb->name, (char*)pk_ctsk->dsname, OBJECT_NAME_LENGTH); } #endif #if TA_GP /* Set global pointer */ if ( (pk_ctsk->tskatr & TA_GP) != 0 ) { gp = pk_ctsk->gp; } tcb->gp = gp; #endif /* Set stack pointer */ if ( stksz > 0 ) { tcb->istack = (VB*)stack + stksz; } else { tcb->istack = pk_ctsk->stkptr; } tcb->isstack = (VB*)sstack + sstksz - RESERVE_SSTACK(tcb->tskatr); /* Set initial value of task operation mode */ tcb->isysmode = (B)sysmode; tcb->sysmode = (H)sysmode; /* Set initial value of task space */ if ( (pk_ctsk->tskatr & TA_TASKSPACE) != 0 ) { tcb->tskctxb.uatb = pk_ctsk->uatb; tcb->tskctxb.lsid = pk_ctsk->lsid; } else { tcb->tskctxb.uatb = NULL; tcb->tskctxb.lsid = 0; /* Task Space */ } /* make it to DORMANT state */ make_dormant(tcb); ercd = tcb->tskid; error_exit: END_CRITICAL_SECTION; if ( ercd < E_OK ) { IAfree(sstack, TA_RNG0); if ( stksz > 0 ) { IAfree(stack, pk_ctsk->tskatr); } } return ercd; }
ER_UINT acre_tsk(const T_CTSK *pk_ctsk) { ID domid; const DOMINIB *p_dominib; TCB *p_tcb; TINIB *p_tinib; ATR tskatr; SIZE sstksz, ustksz; void *sstk, *ustk; ACPTN acptn; ER ercd; LOG_ACRE_TSK_ENTER(pk_ctsk); CHECK_TSKCTX_UNL(); CHECK_MACV_READ(pk_ctsk, T_CTSK); CHECK_RSATR(pk_ctsk->tskatr, TA_ACT|TARGET_TSKATR|TA_DOMMASK); domid = get_atrdomid(pk_ctsk->tskatr); CHECK_ATRDOMID_ACTIVE(domid); CHECK_ALIGN_FUNC(pk_ctsk->task); CHECK_NONNULL_FUNC(pk_ctsk->task); CHECK_TPRI(pk_ctsk->itskpri); p_dominib = (domid == TDOM_SELF) ? p_runtsk->p_tinib->p_dominib : (domid == TDOM_KERNEL) ? &dominib_kernel : get_dominib(domid); if (p_dominib == &dominib_kernel) { /* * システムタスクの場合 */ ustksz = 0U; ustk = NULL; CHECK_PAR(pk_ctsk->sstk == NULL); CHECK_PAR(pk_ctsk->stksz > 0U); sstksz = pk_ctsk->stksz; sstk = pk_ctsk->stk; if (sstk != NULL) { CHECK_PAR(pk_ctsk->sstksz == 0U); } else { sstksz += pk_ctsk->sstksz; } } else { /* * ユーザタスクの場合 */ ustksz = pk_ctsk->stksz; ustk = pk_ctsk->stk; CHECK_PAR(ustksz >= TARGET_MIN_USTKSZ); CHECK_NOSPT(ustk != NULL); CHECK_TARGET_USTACK(ustksz, ustk, p_dominib); sstksz = pk_ctsk->sstksz; sstk = pk_ctsk->sstk; } CHECK_PAR(sstksz >= TARGET_MIN_SSTKSZ); if (sstk != NULL) { CHECK_ALIGN_STKSZ(sstksz); CHECK_ALIGN_STACK(sstk); } CHECK_ACPTN(sysstat_acvct.acptn3); tskatr = pk_ctsk->tskatr; t_lock_cpu(); if (queue_empty(&free_tcb)) { ercd = E_NOID; } else { if (sstk == NULL) { sstk = kernel_malloc(ROUND_STK_T(sstksz)); tskatr |= TA_MEMALLOC; } if (sstk == NULL) { ercd = E_NOMEM; } else { p_tcb = ((TCB *) queue_delete_next(&free_tcb)); p_tinib = (TINIB *)(p_tcb->p_tinib); p_tinib->p_dominib = p_dominib; p_tinib->tskatr = tskatr; p_tinib->exinf = pk_ctsk->exinf; p_tinib->task = pk_ctsk->task; p_tinib->ipriority = INT_PRIORITY(pk_ctsk->itskpri); #ifdef USE_TSKINICTXB init_tskinictxb(&(p_tinib->tskinictxb), p_dominib, sstksz, sstk, utsksz, ustk, pk_ctsk); #else /* USE_TSKINICTXB */ p_tinib->sstksz = sstksz; p_tinib->sstk = sstk; p_tinib->ustksz = ustksz; p_tinib->ustk = ustk; #endif /* USE_TSKINICTXB */ p_tinib->texatr = TA_NULL; p_tinib->texrtn = NULL; acptn = default_acptn(domid); p_tinib->acvct.acptn1 = acptn; p_tinib->acvct.acptn2 = acptn; p_tinib->acvct.acptn3 = acptn | rundom; p_tinib->acvct.acptn4 = acptn; p_tcb->actque = false; make_dormant(p_tcb); queue_initialize(&(p_tcb->mutex_queue)); if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) { make_active(p_tcb); } ercd = TSKID(p_tcb); } } t_unlock_cpu(); error_exit: LOG_ACRE_TSK_LEAVE(ercd); return(ercd); }