Esempio n. 1
0
/*
 *  リソースの獲得
 */
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;
}
Esempio n. 2
0
/*
 *  リソースの返却
 */
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;
}
Esempio n. 3
0
/*
 * 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;
}
Esempio n. 4
0
/*
 * 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;
}