/* * リソースの獲得 */ StatusType GetResource(ResourceType resid) { StatusType ercd = E_OK; Priority ceilpri, curpri; LOG_GETRES_ENTER(resid); CHECK_CALLEVEL(TCL_TASK | TCL_ISR2); CHECK_RESID(resid); ceilpri = resinib_ceilpri[resid]; if (callevel == TCL_TASK) { CHECK_ACCESS(tinib_inipri[runtsk] <= ceilpri); lock_cpu(); D_CHECK_ACCESS(rescb_prevpri[resid] == TPRI_NULL); curpri = tcb_curpri[runtsk]; rescb_prevpri[resid] = curpri; rescb_prevres[resid] = tcb_lastres[runtsk]; tcb_lastres[runtsk] = resid; if (ceilpri > curpri) { tcb_curpri[runtsk] = ceilpri; if (ceilpri >= TPRI_MINISR) { set_ipl(ceilpri - TPRI_MINISR); } } } else { CHECK_ACCESS(isrinib_intpri[runisr] <= ceilpri); lock_cpu(); D_CHECK_ACCESS(rescb_prevpri[resid] == TPRI_NULL); curpri = current_ipl() + TPRI_MINISR; rescb_prevpri[resid] = curpri; rescb_prevres[resid] = isrcb_lastres[runisr]; isrcb_lastres[runisr] = resid; if (ceilpri > curpri) { set_ipl(ceilpri - TPRI_MINISR); } } exit: unlock_cpu(); LOG_GETRES_LEAVE(ercd); return(ercd); error_exit: lock_cpu(); d_error_exit: _errorhook_par1.resid = resid; call_errorhook(ercd, OSServiceId_GetResource); goto exit; }
/* * リソースの返却 */ StatusType ReleaseResource(ResourceType resid) { StatusType ercd = E_OK; LOG_RELRES_ENTER(resid); CHECK_CALLEVEL(TCL_TASK | TCL_ISR2); CHECK_RESID(resid); if (callevel == TCL_TASK) { CHECK_ACCESS(tinib_inipri[runtsk] <= resinib_ceilpri[resid]); CHECK_NOFUNC(tcb_lastres[runtsk] == resid); lock_cpu(); if (rescb_prevpri[resid] >= TPRI_MINISR) { set_ipl(rescb_prevpri[resid] - TPRI_MINISR); } else{ if (tcb_curpri[runtsk] >= TPRI_MINISR) { set_ipl(IPL_ENA_ALL); } } tcb_curpri[runtsk] = rescb_prevpri[resid]; tcb_lastres[runtsk] = rescb_prevres[resid]; rescb_prevpri[resid] = TPRI_NULL; if (tcb_curpri[runtsk] < nextpri) { preempt(); dispatch(); } } else { CHECK_ACCESS(isrinib_intpri[runisr] <= resinib_ceilpri[resid]); CHECK_NOFUNC(isrcb_lastres[runisr] == resid); lock_cpu(); set_ipl(rescb_prevpri[resid] - TPRI_MINISR); isrcb_lastres[runisr] = rescb_prevres[resid]; rescb_prevpri[resid] = TPRI_NULL; } exit: unlock_cpu(); LOG_RELRES_LEAVE(ercd); return(ercd); error_exit: lock_cpu(); _errorhook_par1.resid = resid; call_errorhook(ercd, OSServiceId_ReleaseResource); goto exit; }
/* * Set task resource group */ SYSCALL ID _tk_set_rid( ID tskid, ID resid ) { TCB *tcb; ER ercd; CHECK_TSKID_SELF(tskid); CHECK_RESID(resid); tcb = get_tcb_self(tskid); BEGIN_CRITICAL_SECTION; if ( tcb->state == TS_NONEXIST ) { ercd = E_NOEXS; } else { ercd = tcb->resid; tcb->resid = resid; } END_CRITICAL_SECTION; 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; }