コード例 #1
0
ファイル: rendezvous.c プロジェクト: yuki74w/TRON
SYSCALL INT _tk_cal_por_u( ID porid, UINT calptn, void *msg, INT cmsgsz, TMO_U tmout )
{
	PORCB	*porcb;
	TCB	*tcb;
	QUEUE	*queue;
	RNO	rdvno;
	INT	rmsgsz;
	ER	ercd = E_OK;

	CHECK_PORID(porid);
	CHECK_PAR(calptn != 0);
	CHECK_PAR(cmsgsz >= 0);
	CHECK_TMOUT(tmout);
	CHECK_DISPATCH();

	porcb = get_porcb(porid);

	BEGIN_CRITICAL_SECTION;
	if ( porcb->porid == 0 ) {
		ercd = E_NOEXS;
		goto error_exit;
	}
#if CHK_PAR
	if ( cmsgsz > porcb->maxcmsz ) {
		ercd = E_PAR;
		goto error_exit;
	}
#endif

	/* Search accept wait task */
	queue = porcb->accept_queue.next;
	while ( queue != &porcb->accept_queue ) {
		tcb = (TCB*)queue;
		queue = queue->next;
		if ( (calptn & tcb->winfo.acp.acpptn) == 0 ) {
			continue;
		}

		/* Check rendezvous call wait disable */
		if ( is_diswai((GCB*)porcb, ctxtsk, TTW_CAL) ) {
			ercd = E_DISWAI;
			goto error_exit;
		}

		/* Send message */
		rdvno = gen_rdvno(ctxtsk);
		if ( cmsgsz > 0 ) {
			memcpy(tcb->winfo.acp.msg, msg, (UINT)cmsgsz);
		}
		*tcb->winfo.acp.p_rdvno = rdvno;
		*tcb->winfo.acp.p_cmsgsz = cmsgsz;
		wait_release_ok(tcb);

		/* Check rendezvous end wait disable */
		if ( is_diswai((GCB*)porcb, ctxtsk, TTW_RDV) ) {
			ercd = E_DISWAI;
			goto error_exit;
		}

		/* Ready for rendezvous end wait */
		ercd = E_TMOUT;
		ctxtsk->wspec = &wspec_rdv;
		ctxtsk->wid = 0;
		ctxtsk->wercd = &ercd;
		ctxtsk->winfo.rdv.rdvno = rdvno;
		ctxtsk->winfo.rdv.msg = msg;
		ctxtsk->winfo.rdv.maxrmsz = porcb->maxrmsz;
		ctxtsk->winfo.rdv.p_rmsgsz = &rmsgsz;
		make_wait(TMO_FEVR, porcb->poratr);
		QueInit(&ctxtsk->tskque);

		goto error_exit;
	}

	/* Ready for rendezvous call wait */
	ctxtsk->wspec = ( (porcb->poratr & TA_TPRI) != 0 )?
					&wspec_cal_tpri: &wspec_cal_tfifo;
	ctxtsk->wercd = &ercd;
	ctxtsk->winfo.cal.calptn = calptn;
	ctxtsk->winfo.cal.msg = msg;
	ctxtsk->winfo.cal.cmsgsz = cmsgsz;
	ctxtsk->winfo.cal.p_rmsgsz = &rmsgsz;
	gcb_make_wait_with_diswai((GCB*)porcb, tmout);

    error_exit:
	END_CRITICAL_SECTION;

	return ( ercd < E_OK )? ercd: rmsgsz;
}
コード例 #2
0
ファイル: rendezvous.c プロジェクト: yuki74w/TRON
SYSCALL INT _tk_acp_por_u( ID porid, UINT acpptn, RNO *p_rdvno, void *msg, TMO_U tmout )
{
	PORCB	*porcb;
	TCB	*tcb;
	QUEUE	*queue;
	RNO	rdvno;
	INT	cmsgsz;
	ER	ercd = E_OK;

	CHECK_PORID(porid);
	CHECK_PAR(acpptn != 0);
	CHECK_TMOUT(tmout);
	CHECK_DISPATCH();

	porcb = get_porcb(porid);
 
	BEGIN_CRITICAL_SECTION;
	if ( porcb->porid == 0 ) {
		ercd = E_NOEXS;
		goto error_exit;
	}

	/* Search call wait task */
	queue = porcb->call_queue.next;
	while ( queue != &porcb->call_queue ) {
		tcb = (TCB*)queue;
		queue = queue->next;
		if ( (acpptn & tcb->winfo.cal.calptn) == 0 ) {
			continue;
		}

		/* Check rendezvous accept wait disable */
		if ( is_diswai((GCB*)porcb, ctxtsk, TTW_ACP) ) {
			ercd = E_DISWAI;
			goto error_exit;
		}

		/* Receive message */
		*p_rdvno = rdvno = gen_rdvno(tcb);
		cmsgsz = tcb->winfo.cal.cmsgsz;
		if ( cmsgsz > 0 ) {
			memcpy(msg, tcb->winfo.cal.msg, (UINT)cmsgsz);
		}

		/* Check rendezvous end wait disable */
		if ( is_diswai((GCB*)porcb, tcb, TTW_RDV) ) {
			wait_release_ng(tcb, E_DISWAI);
			goto error_exit;
		}
		wait_cancel(tcb);

		/* Make the other task at rendezvous end wait state */
		tcb->wspec = &wspec_rdv;
		tcb->wid = 0;
		tcb->winfo.rdv.rdvno = rdvno;
		tcb->winfo.rdv.msg = tcb->winfo.cal.msg;
		tcb->winfo.rdv.maxrmsz = porcb->maxrmsz;
		tcb->winfo.rdv.p_rmsgsz = tcb->winfo.cal.p_rmsgsz;
		timer_insert(&tcb->wtmeb, TMO_FEVR,
					(CBACK)wait_release_tmout, tcb);
		QueInit(&tcb->tskque);

		goto error_exit;
	}

	/* Check rendezvous accept wait disable */
	if ( is_diswai((GCB*)porcb, ctxtsk, TTW_ACP) ) {
		ercd = E_DISWAI;
		goto error_exit;
	}

	ercd = E_TMOUT;
	if ( tmout != TMO_POL ) {
		/* Ready for rendezvous accept wait */
		ctxtsk->wspec = &wspec_acp;
		ctxtsk->wid = porid;
		ctxtsk->wercd = &ercd;
		ctxtsk->winfo.acp.acpptn = acpptn;
		ctxtsk->winfo.acp.msg = msg;
		ctxtsk->winfo.acp.p_rdvno = p_rdvno;
		ctxtsk->winfo.acp.p_cmsgsz = &cmsgsz;
		make_wait(tmout, porcb->poratr);
		QueInsert(&ctxtsk->tskque, &porcb->accept_queue);
	}

    error_exit:
	END_CRITICAL_SECTION;

	return ( ercd < E_OK )? ercd: cmsgsz;
}
コード例 #3
0
ファイル: mutex.c プロジェクト: ev3rt-git/ev3rt-hrp3
ER_UINT
acre_mtx(const T_CMTX *pk_cmtx)
{
	MTXCB			*p_mtxcb;
	MTXINIB			*p_mtxinib;
	ATR				mtxatr;
	PRI				ceilpri;
	ID				domid;
	const DOMINIB	*p_dominib;
	ACPTN			acptn;
	ER				ercd;

	LOG_ACRE_MTX_ENTER(pk_cmtx);
	CHECK_TSKCTX_UNL();
	CHECK_MACV_READ(pk_cmtx, T_CMTX);

	mtxatr = pk_cmtx->mtxatr;
	ceilpri = pk_cmtx->ceilpri;

	if ((mtxatr & MTXPROTO_MASK) == TA_CEILING) {
		CHECK_VALIDATR(mtxatr, TA_CEILING|TA_DOMMASK);
		CHECK_PAR(VALID_TPRI(ceilpri));
	}
	else {
		CHECK_VALIDATR(pk_cmtx->mtxatr, TA_TPRI|TA_DOMMASK);
	}
	domid = get_atrdomid(mtxatr);
	if (domid == TDOM_SELF) {
		if (rundom == TACP_KERNEL) {
			domid = TDOM_KERNEL;
		}
		else {
			domid = p_runtsk->p_tinib->domid;
		}
		mtxatr = set_atrdomid(mtxatr, domid);
	}
	switch (domid) {
	case TDOM_KERNEL:
		p_dominib = &dominib_kernel;
		break;
	case TDOM_NONE:
		p_dominib = &dominib_none;
		break;
	default:
		CHECK_RSATR(VALID_DOMID(domid));
		p_dominib = get_dominib(domid);
		break;
	}
	CHECK_ACPTN(p_dominib->acvct.acptn1);

	lock_cpu();
	if (tnum_mtx == 0 || queue_empty(&(p_dominib->p_domcb->free_mtxcb))) {
		ercd = E_NOID;
	}
	else {
		p_mtxcb = (MTXCB *)
					queue_delete_next(&(p_dominib->p_domcb->free_mtxcb));
		p_mtxinib = (MTXINIB *)(p_mtxcb->p_mtxinib);
		p_mtxinib->mtxatr = mtxatr;
		p_mtxinib->ceilpri = INT_PRIORITY(ceilpri);

		acptn = default_acptn(domid);
		p_mtxinib->acvct.acptn1 = acptn;
		p_mtxinib->acvct.acptn2 = acptn;
		p_mtxinib->acvct.acptn3 = p_dominib->acvct.acptn1;
		p_mtxinib->acvct.acptn4 = acptn;

		queue_initialize(&(p_mtxcb->wait_queue));
		p_mtxcb->p_loctsk = NULL;
		ercd = MTXID(p_mtxcb);
	}
	unlock_cpu();

  error_exit:
	LOG_ACRE_MTX_LEAVE(ercd);
	return(ercd);
}
コード例 #4
0
ファイル: task_manage.c プロジェクト: imgtec/t-kernel
/*
 * 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;
}
コード例 #5
0
ファイル: messagebuf.c プロジェクト: ev3rt-git/ev3rt-hrp3
ER_UINT
acre_mbf(const T_CMBF *pk_cmbf)
{
	MBFCB			*p_mbfcb;
	MBFINIB			*p_mbfinib;
	ATR				mbfatr;
	uint_t			maxmsz;
	size_t			mbfsz;
	void			*mbfmb;
	ID				domid;
	const DOMINIB	*p_dominib;
	ACPTN			acptn;
	ER				ercd;

	LOG_ACRE_MBF_ENTER(pk_cmbf);
	CHECK_TSKCTX_UNL();
	CHECK_MACV_READ(pk_cmbf, T_CMBF);

	mbfatr = pk_cmbf->mbfatr;
	maxmsz = pk_cmbf->maxmsz;
	mbfsz = pk_cmbf->mbfsz;
	mbfmb = pk_cmbf->mbfmb;

	CHECK_VALIDATR(mbfatr, TA_TPRI|TA_DOMMASK);
	if (mbfmb != NULL) {
		CHECK_PAR(MB_ALIGN(mbfmb));
		CHECK_OBJ(valid_memobj_kernel(mbfmb, mbfsz));
	}
	domid = get_atrdomid(mbfatr);
	if (domid == TDOM_SELF) {
		if (rundom == TACP_KERNEL) {
			domid = TDOM_KERNEL;
		}
		else {
			domid = p_runtsk->p_tinib->domid;
		}
		mbfatr = set_atrdomid(mbfatr, domid);
	}
	switch (domid) {
	case TDOM_KERNEL:
		p_dominib = &dominib_kernel;
		break;
	case TDOM_NONE:
		p_dominib = &dominib_none;
		break;
	default:
		CHECK_RSATR(VALID_DOMID(domid));
		p_dominib = get_dominib(domid);
		break;
	}
	CHECK_ACPTN(p_dominib->acvct.acptn1);

	lock_cpu();
	if (tnum_mbf == 0 || queue_empty(&(p_dominib->p_domcb->free_mbfcb))) {
		ercd = E_NOID;
	}
	else {
		if (mbfsz != 0 && mbfmb == NULL) {
			mbfmb = malloc_mpk(mbfsz, p_dominib);
			mbfatr |= TA_MBALLOC;
		}
		if (mbfsz != 0 && mbfmb == NULL) {
			ercd = E_NOMEM;
		}
		else {
			p_mbfcb = (MBFCB *)
						queue_delete_next(&(p_dominib->p_domcb->free_mbfcb));
			p_mbfinib = (MBFINIB *)(p_mbfcb->p_mbfinib);
			p_mbfinib->mbfatr = mbfatr;
			p_mbfinib->maxmsz = maxmsz;
			p_mbfinib->mbfsz = mbfsz;
			p_mbfinib->mbfmb = mbfmb;

			acptn = default_acptn(domid);
			p_mbfinib->acvct.acptn1 = acptn;
			p_mbfinib->acvct.acptn2 = acptn;
			p_mbfinib->acvct.acptn3 = p_dominib->acvct.acptn1;
			p_mbfinib->acvct.acptn4 = acptn;

			queue_initialize(&(p_mbfcb->swait_queue));
			queue_initialize(&(p_mbfcb->rwait_queue));
			p_mbfcb->fmbfsz = mbfsz;
			p_mbfcb->head = 0U;
			p_mbfcb->tail = 0U;
			p_mbfcb->smbfcnt = 0U;
			ercd = MBFID(p_mbfcb);
		}
	}
	unlock_cpu();

  error_exit:
	LOG_ACRE_MBF_LEAVE(ercd);
	return(ercd);
}
コード例 #6
0
ファイル: mempool.c プロジェクト: yuki74w/TRON
/*
 * Create variable size memory pool
 */
SYSCALL ID _tk_cre_mpl( CONST T_CMPL *pk_cmpl )
{
#if CHK_RSATR
	const ATR VALID_MPLATR = {
		 TA_TPRI
		|TA_RNG3
		|TA_NODISWAI
#if USE_OBJECT_NAME
		|TA_DSNAME
#endif
	};
#endif
	MPLCB	*mplcb;
	ID	mplid;
	INT	mplsz;
	void	*mempool;
	ER	ercd;

	CHECK_RSATR(pk_cmpl->mplatr, VALID_MPLATR);
	CHECK_PAR(pk_cmpl->mplsz > 0 && pk_cmpl->mplsz <= MAX_ALLOCATE);
	CHECK_DISPATCH();

	mplsz = roundSize(pk_cmpl->mplsz);

	/* Allocate memory for memory pool */
	mempool = IAmalloc((UINT)mplsz + sizeof(QUEUE)*2, pk_cmpl->mplatr);
	if ( mempool == NULL ) {
		return E_NOMEM;
	}

	BEGIN_CRITICAL_SECTION;
	/* Get control block from FreeQue */
	mplcb = (MPLCB*)QueRemoveNext(&free_mplcb);
	if ( mplcb == NULL ) {
		ercd = E_LIMIT;
	} else {
		mplid = ID_MPL(mplcb - mplcb_table);

		/* Initialize control block */
		QueInit(&mplcb->wait_queue);
		mplcb->mplid  = mplid;
		mplcb->exinf  = pk_cmpl->exinf;
		mplcb->mplatr = pk_cmpl->mplatr;
		mplcb->mplsz  = mplsz;
#if USE_OBJECT_NAME
		if ( (pk_cmpl->mplatr & TA_DSNAME) != 0 ) {
			strncpy((char*)mplcb->name, (char*)pk_cmpl->dsname, OBJECT_NAME_LENGTH);
		}
#endif
		/* Initialize memory pool */
		init_mempool(mplcb, mempool, mplsz + (INT)sizeof(QUEUE)*2);

		ercd = mplid;
	}
	END_CRITICAL_SECTION;

	if ( ercd < E_OK ) {
		IAfree(mempool, pk_cmpl->mplatr);
	}

	return ercd;
}
コード例 #7
0
ER_UINT
acre_mpf(const T_CMPF *pk_cmpf)
{
	MPFCB	*p_mpfcb;
	MPFINIB	*p_mpfinib;
	ATR		mpfatr;
	void	*mpf;
	MPFMB	*p_mpfmb;
	ER		ercd;

	LOG_ACRE_MPF_ENTER(pk_cmpf);
	CHECK_TSKCTX_UNL();
	CHECK_RSATR(pk_cmpf->mpfatr, TA_TPRI);
	CHECK_PAR(pk_cmpf->blkcnt != 0);
	CHECK_PAR(pk_cmpf->blksz != 0);
	if (pk_cmpf->mpf != NULL) {
		CHECK_PAR(MPF_ALIGN(pk_cmpf->mpf));
	}
	if (pk_cmpf->mpfmb != NULL) {
		CHECK_PAR(MB_ALIGN(pk_cmpf->mpfmb));
	}
	mpfatr = pk_cmpf->mpfatr;
	mpf = pk_cmpf->mpf;
	p_mpfmb = pk_cmpf->mpfmb;

	lock_cpu();
	if (tnum_mpf == 0 || queue_empty(&free_mpfcb)) {
		ercd = E_NOID;
	}
	else {
		if (mpf == NULL) {
			mpf = kernel_malloc(ROUND_MPF_T(pk_cmpf->blksz) * pk_cmpf->blkcnt);
			mpfatr |= TA_MEMALLOC;
		}
		if (mpf == NULL) {
			ercd = E_NOMEM;
		}
		else {
			if (p_mpfmb == NULL) {
				p_mpfmb = kernel_malloc(sizeof(MPFMB) * pk_cmpf->blkcnt);
				mpfatr |= TA_MBALLOC;
			}
			if (p_mpfmb == NULL) {
				if (pk_cmpf->mpf == NULL) {
					kernel_free(mpf);
				}
				ercd = E_NOMEM;
			}
			else {
				p_mpfcb = ((MPFCB *) queue_delete_next(&free_mpfcb));
				p_mpfinib = (MPFINIB *)(p_mpfcb->p_mpfinib);
				p_mpfinib->mpfatr = mpfatr;
				p_mpfinib->blkcnt = pk_cmpf->blkcnt;
				p_mpfinib->blksz = ROUND_MPF_T(pk_cmpf->blksz);
				p_mpfinib->mpf = mpf;
				p_mpfinib->p_mpfmb = p_mpfmb;

				queue_initialize(&(p_mpfcb->wait_queue));
				p_mpfcb->fblkcnt = p_mpfcb->p_mpfinib->blkcnt;
				p_mpfcb->unused = 0U;
				p_mpfcb->freelist = INDEX_NULL;
				ercd = MPFID(p_mpfcb);
			}
		}
	}
	unlock_cpu();

  error_exit:
	LOG_ACRE_MPF_LEAVE(ercd);
	return(ercd);
}
コード例 #8
0
ファイル: task_manage.c プロジェクト: PizzaFactory/hrp2ev3
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);
}
コード例 #9
0
ER_UINT
acre_tsk(const T_CTSK *pk_ctsk)
{
	TCB		*p_tcb;
	TINIB	*p_tinib;
	ATR		tskatr;
	TASK	task;
	PRI		itskpri;
	size_t	stksz;
	STK_T	*stk;
	ER		ercd;

	LOG_ACRE_TSK_ENTER(pk_ctsk);
	CHECK_TSKCTX_UNL();

	tskatr = pk_ctsk->tskatr;
	task = pk_ctsk->task;
	itskpri = pk_ctsk->itskpri;
	stksz = pk_ctsk->stksz;
	stk = pk_ctsk->stk;

	CHECK_RSATR(tskatr, TA_ACT|TA_NOACTQUE|TARGET_TSKATR);
	CHECK_PAR(FUNC_ALIGN(task));
	CHECK_PAR(FUNC_NONNULL(task));
	CHECK_PAR(VALID_TPRI(itskpri));
	CHECK_PAR(stksz >= TARGET_MIN_STKSZ);
	if (stk != NULL) {
		CHECK_PAR(STKSZ_ALIGN(stksz));
		CHECK_PAR(STACK_ALIGN(stk));
	}

	lock_cpu();
	if (queue_empty(&free_tcb)) {
		ercd = E_NOID;
	}
	else {
		if (stk == NULL) {
			stk = kernel_malloc(ROUND_STK_T(stksz));
			tskatr |= TA_MEMALLOC;
		}
		if (stk == NULL) {
			ercd = E_NOMEM;
		}
		else {
			p_tcb = ((TCB *) queue_delete_next(&free_tcb));
			p_tinib = (TINIB *)(p_tcb->p_tinib);
			p_tinib->tskatr = tskatr;
			p_tinib->exinf = pk_ctsk->exinf;
			p_tinib->task = task;
			p_tinib->ipriority = INT_PRIORITY(itskpri);
#ifdef USE_TSKINICTXB
			init_tskinictxb(&(p_tinib->tskinictxb), stksz, stk);
#else /* USE_TSKINICTXB */
			p_tinib->stksz = stksz;
			p_tinib->stk = stk;
#endif /* USE_TSKINICTXB */

			p_tcb->actque = false;
			make_dormant(p_tcb);
			if ((p_tcb->p_tinib->tskatr & TA_ACT) != 0U) {
				make_active(p_tcb);
			}
			ercd = TSKID(p_tcb);
		}
	}
	unlock_cpu();

  error_exit:
	LOG_ACRE_TSK_LEAVE(ercd);
	return(ercd);
}
コード例 #10
0
ファイル: mempfix.c プロジェクト: paduc77/gainos
/*
 * Create fixed size memory pool
 */
SYSCALL ID tk_cre_mpf_impl( T_CMPF *pk_cmpf )
{
#if CHK_RSATR
	const ATR VALID_MPFATR = {
		 TA_TPRI
		|TA_RNG3
		|TA_USERBUF
#if USE_OBJECT_NAME
		|TA_DSNAME
#endif
	};
#endif
	MPFCB	*mpfcb;
	ID	mpfid;
	W	blfsz, mpfsz;
	VP	mempool;

	CHECK_RSATR(pk_cmpf->mpfatr, VALID_MPFATR);
	CHECK_PAR(pk_cmpf->mpfcnt > 0);
	CHECK_PAR(pk_cmpf->blfsz > 0);
#if !USE_IMALLOC
	/* TA_USERBUF must be specified if configured in no Imalloc */
	CHECK_PAR((pk_cmpf->mpfatr & TA_USERBUF) != 0);
#endif
	CHECK_DISPATCH();

	blfsz = (W)MINSZ(pk_cmpf->blfsz);
	mpfsz = blfsz * pk_cmpf->mpfcnt;

#if USE_IMALLOC
	if ( (pk_cmpf->mpfatr & TA_USERBUF) != 0 ) {
		/* Size of user buffer must be multiples of sizeof(FREEL) */
		if ( blfsz != pk_cmpf->blfsz ) {
			return E_PAR;
		}
		/* Use user buffer */
		mempool = pk_cmpf->bufptr;
	} else {
		/* Allocate memory for memory pool */
		mempool = knl_Imalloc((UW)mpfsz);
		if ( mempool == NULL ) {
			return E_NOMEM;
		}
	}
#else
	/* Size of user buffer must be larger than sizeof(FREEL) */
	if ( blfsz != pk_cmpf->blfsz ) {
		return E_PAR;
	}
	/* Use user buffer */
	mempool = pk_cmpf->bufptr;
#endif

	/* Get control block from FreeQue */
	DISABLE_INTERRUPT;
	mpfcb = (MPFCB*)QueRemoveNext(&knl_free_mpfcb);
	ENABLE_INTERRUPT;

	if ( mpfcb == NULL ) {
#if USE_IMALLOC
		if ( (pk_cmpf->mpfatr & TA_USERBUF) == 0 ) {
			knl_Ifree(mempool);
		}
#endif
		return E_LIMIT;
	}

	knl_LockOBJ(&mpfcb->lock);
	mpfid = ID_MPF(mpfcb - knl_mpfcb_table);

	/* Initialize control block */
	QueInit(&mpfcb->wait_queue);
	mpfcb->exinf    = pk_cmpf->exinf;
	mpfcb->mpfatr   = pk_cmpf->mpfatr;
	mpfcb->mpfcnt   = mpfcb->frbcnt = pk_cmpf->mpfcnt;
	mpfcb->blfsz    = blfsz;
	mpfcb->mpfsz    = mpfsz;
	mpfcb->unused   = mpfcb->mempool = mempool;
	mpfcb->freelist = NULL;
#if USE_OBJECT_NAME
	if ( (pk_cmpf->mpfatr & TA_DSNAME) != 0 ) {
		strncpy((char*)mpfcb->name, (char*)pk_cmpf->dsname, OBJECT_NAME_LENGTH);
	}
#endif

	mpfcb->mpfid    = mpfid;  /* Set ID after completion */
	knl_UnlockOBJ(&mpfcb->lock);

	return mpfid;
}
コード例 #11
0
/*
 * Create task
 */
SYSCALL ID tk_cre_tsk_impl P1( T_CTSK *pk_ctsk )
{
#if CHK_RSATR
	const ATR VALID_TSKATR = {	/* Valid value of task attribute */
		 TA_HLNG
		|TA_RNG3
		|TA_USERBUF
		|TA_GP
#if USE_OBJECT_NAME
		|TA_DSNAME
#endif
	};
#endif
	TCB	*tcb;
	W	sstksz;
	VP	stack;
	ER	ercd;

	CHECK_RSATR(pk_ctsk->tskatr, VALID_TSKATR);
#if !USE_IMALLOC
	/* TA_USERBUF must be specified if configured in no Imalloc */
	CHECK_PAR((pk_ctsk->tskatr & TA_USERBUF) != 0);
#endif
	CHECK_PRI(pk_ctsk->itskpri);
	CHECK_PAR(pk_ctsk->stksz >= MIN_SYS_STACK_SIZE);

	/* Adjust stack size by 8 bytes */
	sstksz  = (pk_ctsk->stksz  + 7) / 8 * 8;

#if USE_IMALLOC
	if ( (pk_ctsk->tskatr & TA_USERBUF) != 0 ) {
		/* Size of User buffer must be multiples of 8 */
		if ( sstksz != pk_ctsk->stksz ) {
			return E_PAR;
		}
		/* Use user buffer */
		stack = pk_ctsk->bufptr;
	} else {
		/* Allocate system stack area */
		stack = knl_Imalloc((UW)sstksz);
		if ( stack == NULL ) {
			return E_NOMEM;
		}
	}
#else
	/* Size of User buffer must be multiples of 8 */
	if ( sstksz != pk_ctsk->stksz ) {
		return E_PAR;
	}
	/* Use user buffer */
	stack = pk_ctsk->bufptr;
#endif

	BEGIN_CRITICAL_SECTION;
	/* Get control block from FreeQue */
	tcb = (TCB*)QueRemoveNext(&knl_free_tcb);
	if ( tcb == NULL ) {
		ercd = E_LIMIT;
		goto error_exit;
	}

	/* Initialize control block */
	tcb->exinf     = pk_ctsk->exinf;
	tcb->tskatr    = pk_ctsk->tskatr & ~TA_RNG3; /* handling as TA_RNG0 */
	tcb->task      = pk_ctsk->task;
	tcb->ipriority = (UB)int_priority(pk_ctsk->itskpri);
	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 */
	tcb->isstack = (VB*)stack + sstksz;

	/* Set initial value of task operation mode */
	tcb->isysmode = 1;
	tcb->sysmode  = 1;

	/* make it to DORMANT state */
	knl_make_dormant(tcb);

	ercd = tcb->tskid;

    error_exit:
	END_CRITICAL_SECTION;

#if USE_IMALLOC
	if ( (ercd < E_OK) && ((pk_ctsk->tskatr & TA_USERBUF) == 0) ) {
		knl_Ifree(stack);
	}
#endif

	return ercd;
}
コード例 #12
0
ファイル: cpu_calls.c プロジェクト: kidasan/tkernel
/*
 * Interrupt handler definition
 */
SYSCALL ER _tk_def_int( UINT dintno, T_DINT *pk_dint )
{
	FP	inthdr;
	INT	vecno = dintno >> 5;
	INTMASKTBL	*ptr;

	CHECK_PAR(vecno < MAX_INTVEC);

	if ( pk_dint != NULL ) {
		/* Set interrupt handler */
		if ( vecno == VECNO_TLBMISS ) {
			CHECK_RSATR(pk_dint->intatr, 0);
		} else {
			CHECK_RSATR(pk_dint->intatr, TA_HLNG | TA_ASSPRC);
		}
#if CHK_PAR
		if ( (pk_dint->intatr & TA_ASSPRC) != 0 ) {
			if ( !chk_assprc(pk_dint->assprc) ) {
				return E_PAR;
			}
		}
#endif

		inthdr = pk_dint->inthdr;

		BEGIN_CRITICAL_SECTION;
		if ( (pk_dint->intatr & TA_HLNG) != 0 ) {
			hll_inthdr[vecno] = inthdr;
			inthdr = ( vecno == VECNO_DEFAULT )?
					defaulthdr_startup: inthdr_startup;
		}
		define_inthdr(vecno, inthdr);

		if ( (pk_dint->intatr & TA_ASSPRC) != 0 ) {
			if ( vecno < N_INTVEC) {
				ptr = &intmasktable[vecno];
				if ( ptr->mask != 0) {
					if ( pk_dint->assprc & TP_PRC1 ) {
						out_w(ptr->maskaddr[1], in_w(ptr->maskaddr[1]) | ptr->mask);
						out_w(clraddr(ptr->maskaddr[0]), ptr->mask);
					}
					else if ( pk_dint->assprc & TP_PRC2 ) {
						out_w(ptr->maskaddr[0], in_w(ptr->maskaddr[0]) | ptr->mask);
						out_w(clraddr(ptr->maskaddr[1]), ptr->mask);
					}
				}
			}
		}
		END_CRITICAL_NO_DISPATCH;
	} else {
		/* Free interrupt handler */
		switch ( vecno ) {
		  case VECNO_TRAPA:	inthdr = SaveMonHdr.trapa_hdr;	 break;
		  case VECNO_BREAK:	inthdr = SaveMonHdr.break_hdr;	 break;
		  case VECNO_MONITOR:	inthdr = SaveMonHdr.monitor_hdr; break;
		  case VECNO_DEFAULT:	inthdr = SaveMonHdr.default_hdr; break;
		  case VECNO_TLBMISS:	inthdr = SaveMonHdr.tlbmiss_hdr; break;
		  default:		inthdr = NULL;
		}

		BEGIN_CRITICAL_SECTION;
		define_inthdr(vecno, inthdr);
		if ( vecno < MAX_INTVEC ) {
			hll_inthdr[vecno] = NULL;
		}
		if ( vecno < N_INTVEC) {
			ptr = &intmasktable[vecno];
			if ( ptr->mask != 0) {
				out_w(ptr->maskaddr[0], in_w(ptr->maskaddr[0]) | ptr->mask);
				out_w(ptr->maskaddr[1], in_w(ptr->maskaddr[1]) | ptr->mask);
			}
		}
		END_CRITICAL_NO_DISPATCH;
	}

	return E_OK;
}
コード例 #13
0
ファイル: semaphore.c プロジェクト: ev3rt-git/ev3rt-hrp3
ER_UINT
acre_sem(const T_CSEM *pk_csem)
{
	SEMCB			*p_semcb;
	SEMINIB			*p_seminib;
	ATR				sematr;
	uint_t			isemcnt, maxsem;
	ID				domid;
	const DOMINIB	*p_dominib;
	ACPTN			acptn;
	ER				ercd;

	LOG_ACRE_SEM_ENTER(pk_csem);
	CHECK_TSKCTX_UNL();
	CHECK_MACV_READ(pk_csem, T_CSEM);

	sematr = pk_csem->sematr;
	isemcnt = pk_csem->isemcnt;
	maxsem = pk_csem->maxsem;

	CHECK_VALIDATR(sematr, TA_TPRI|TA_DOMMASK);
	CHECK_PAR(0 <= isemcnt && isemcnt <= maxsem);
	CHECK_PAR(1 <= maxsem && maxsem <= TMAX_MAXSEM);
	domid = get_atrdomid(sematr);
	if (domid == TDOM_SELF) {
		if (rundom == TACP_KERNEL) {
			domid = TDOM_KERNEL;
		}
		else {
			domid = p_runtsk->p_tinib->domid;
		}
		sematr = set_atrdomid(sematr, domid);
	}
	switch (domid) {
	case TDOM_KERNEL:
		p_dominib = &dominib_kernel;
		break;
	case TDOM_NONE:
		p_dominib = &dominib_none;
		break;
	default:
		CHECK_RSATR(VALID_DOMID(domid));
		p_dominib = get_dominib(domid);
		break;
	}
	CHECK_ACPTN(p_dominib->acvct.acptn1);

	lock_cpu();
	if (tnum_sem == 0 || queue_empty(&(p_dominib->p_domcb->free_semcb))) {
		ercd = E_NOID;
	}
	else {
		p_semcb = (SEMCB *)
					queue_delete_next(&(p_dominib->p_domcb->free_semcb));
		p_seminib = (SEMINIB *)(p_semcb->p_seminib);
		p_seminib->sematr = sematr;
		p_seminib->isemcnt = isemcnt;
		p_seminib->maxsem = maxsem;

		acptn = default_acptn(domid);
		p_seminib->acvct.acptn1 = acptn;
		p_seminib->acvct.acptn2 = acptn;
		p_seminib->acvct.acptn3 = p_dominib->acvct.acptn1;
		p_seminib->acvct.acptn4 = acptn;

		queue_initialize(&(p_semcb->wait_queue));
		p_semcb->semcnt = isemcnt;
		ercd = SEMID(p_semcb);
	}
	unlock_cpu();

  error_exit:
	LOG_ACRE_SEM_LEAVE(ercd);
	return(ercd);
}