ER_UINT
acre_sem(const T_CSEM *pk_csem)
{
	SEMCB	*p_semcb;
	SEMINIB	*p_seminib;
	ER		ercd;

	LOG_ACRE_SEM_ENTER(pk_csem);
	CHECK_TSKCTX_UNL();
	CHECK_RSATR(pk_csem->sematr, TA_TPRI);
	CHECK_PAR(0 <= pk_csem->isemcnt && pk_csem->isemcnt <= pk_csem->maxsem);
	CHECK_PAR(1 <= pk_csem->maxsem && pk_csem->maxsem <= TMAX_MAXSEM);

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

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

  error_exit:
	LOG_ACRE_SEM_LEAVE(ercd);
	return(ercd);
}
Exemple #2
0
ER_UINT
acre_alm(const T_CALM *pk_calm)
{
	ALMCB	*p_almcb;
	ALMINIB	*p_alminib;
	ER		ercd;

	LOG_ACRE_ALM_ENTER(pk_calm);
	CHECK_TSKCTX_UNL();
	CHECK_RSATR(pk_calm->almatr, TA_NULL);
	CHECK_ALIGN_FUNC(pk_calm->almhdr);
	CHECK_NONNULL_FUNC(pk_calm->almhdr);

	t_lock_cpu();
	if (tnum_alm == 0 || queue_empty(&free_almcb)) {
		ercd = E_NOID;
	}
	else {
		p_almcb = ((ALMCB *)(((char *) queue_delete_next(&free_almcb))
												- offsetof(ALMCB, tmevtb)));
		p_alminib = (ALMINIB *)(p_almcb->p_alminib);
		p_alminib->almatr = pk_calm->almatr;
		p_alminib->exinf = pk_calm->exinf;
		p_alminib->almhdr = pk_calm->almhdr;

		p_almcb->almsta = false;
		ercd = ALMID(p_almcb);
	}
	t_unlock_cpu();

  error_exit:
	LOG_ACRE_ALM_LEAVE(ercd);
	return(ercd);
}
ER_UINT
acre_flg(const T_CFLG *pk_cflg)
{
	FLGCB	*p_flgcb;
	FLGINIB	*p_flginib;
	ER		ercd;

	LOG_ACRE_FLG_ENTER(pk_cflg);
	CHECK_TSKCTX_UNL();
	CHECK_RSATR(pk_cflg->flgatr, TA_TPRI|TA_WMUL|TA_CLR);

	t_lock_cpu();
	if (tnum_flg == 0 || queue_empty(&free_flgcb)) {
		ercd = E_NOID;
	}
	else {
		p_flgcb = ((FLGCB *) queue_delete_next(&free_flgcb));
		p_flginib = (FLGINIB *)(p_flgcb->p_flginib);
		p_flginib->flgatr = pk_cflg->flgatr;
		p_flginib->iflgptn = pk_cflg->iflgptn;

		queue_initialize(&(p_flgcb->wait_queue));
		p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
		ercd = FLGID(p_flgcb);
	}
	t_unlock_cpu();

  error_exit:
	LOG_ACRE_FLG_LEAVE(ercd);
	return(ercd);
}
Exemple #4
0
/*
 * Interrupt handler definition
 */
SYSCALL ER _tk_def_int( UINT dintno, T_DINT *pk_dint )
{
	FP	inthdr;

	CHECK_PAR(dintno < N_INTVEC);

	if ( pk_dint != NULL ) {
		/* Set interrupt handler */
		CHECK_RSATR(pk_dint->intatr, TA_HLNG|TA_ASSPRC);
#if PSR_DI == PSR_I
		CHECK_PAR( !(dintno == EIT_FIQ
				&& (pk_dint->intatr & TA_HLNG) != 0) );
#endif
#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[dintno] = inthdr;
			inthdr = ( dintno == EIT_DEFAULT )? defaulthdr_startup:
				 ( dintno <  IRQVEC_TOP  )? exchdr_startup:
				 ( dintno <= IRQVEC_END  )? inthdr_startup:
				                            exchdr_startup;
		}
		define_inthdr(dintno, inthdr);
		/* Set cpu target */
		if ( (pk_dint->intatr & TA_ASSPRC) != 0 ) {
			SetIntAssprc(dintno, pk_dint->assprc);
		} else {
			SetIntAssprc(dintno, 1 << get_prid());
		}
		END_CRITICAL_NO_DISPATCH;
	} else {
		/* Clear interrupt handler */
		switch ( dintno ) {
		  case VECNO_DEFAULT:	inthdr = SaveMonHdr.default_hdr; break;
		  case VECNO_BREAK:	inthdr = SaveMonHdr.break_hdr;	 break;
		  case VECNO_MONITOR:	inthdr = SaveMonHdr.monitor_hdr; break;
		  default:		inthdr = NULL;
		}

		BEGIN_CRITICAL_SECTION;
		/* Clear cpu target */
		ClrIntAssprc(dintno);
		define_inthdr(dintno, inthdr);
		hll_inthdr[dintno] = NULL;
		END_CRITICAL_NO_DISPATCH;
	}

	return E_OK;
}
Exemple #5
0
/*
 * Create mutex
 */
SYSCALL ID _tk_cre_mtx( CONST T_CMTX *pk_cmtx )
{
#if CHK_RSATR
	const ATR VALID_MTXATR = {
		 TA_CEILING
		|TA_NODISWAI
#if USE_OBJECT_NAME
		|TA_DSNAME
#endif
	};
#endif
	MTXCB	*mtxcb;
	ID	mtxid;
	INT	ceilpri;
	ER	ercd;

	CHECK_RSATR(pk_cmtx->mtxatr, VALID_MTXATR);

	if ( (pk_cmtx->mtxatr & TA_CEILING) == TA_CEILING ) {
		CHECK_PRI(pk_cmtx->ceilpri);
		ceilpri = int_priority(pk_cmtx->ceilpri);
	} else {
		ceilpri = 0;
	}

	BEGIN_CRITICAL_SECTION;
	/* Get control block from FreeQue */
	mtxcb = (MTXCB*)QueRemoveNext(&free_mtxcb);
	if ( mtxcb == NULL ) {
		ercd = E_LIMIT;
	} else {
		mtxid = ID_MTX(mtxcb - mtxcb_table);

		/* Initialize control block */
		QueInit(&mtxcb->wait_queue);
		mtxcb->mtxid   = mtxid;
		mtxcb->exinf   = pk_cmtx->exinf;
		mtxcb->mtxatr  = pk_cmtx->mtxatr;
		mtxcb->ceilpri = ceilpri;
		mtxcb->mtxtsk  = NULL;
		mtxcb->mtxlist = NULL;
#if USE_OBJECT_NAME
		if ( (pk_cmtx->mtxatr & TA_DSNAME) != 0 ) {
			strncpy((char*)mtxcb->name, (char*)pk_cmtx->dsname,
				(UINT)OBJECT_NAME_LENGTH);
		}
#endif
		ercd = mtxid;
	}
	END_CRITICAL_SECTION;

	return ercd;
}
Exemple #6
0
ER_UINT
acre_pdq(const T_CPDQ *pk_cpdq)
{
    PDQCB	*p_pdqcb;
    PDQINIB	*p_pdqinib;
    ATR		pdqatr;
    PDQMB	*p_pdqmb;
    ER		ercd;

    LOG_ACRE_PDQ_ENTER(pk_cpdq);
    CHECK_TSKCTX_UNL();
    CHECK_RSATR(pk_cpdq->pdqatr, TA_TPRI);
    CHECK_DPRI(pk_cpdq->maxdpri);
    pdqatr = pk_cpdq->pdqatr;
    p_pdqmb = pk_cpdq->pdqmb;

    t_lock_cpu();
    if (queue_empty(&free_pdqcb)) {
        ercd = E_NOID;
    }
    else {
        if (pk_cpdq->pdqcnt != 0 && p_pdqmb == NULL) {
            p_pdqmb = kernel_malloc(sizeof(PDQMB) * pk_cpdq->pdqcnt);
            pdqatr |= TA_MBALLOC;
        }
        if (pk_cpdq->pdqcnt != 0 && p_pdqmb == NULL) {
            ercd = E_NOMEM;
        }
        else {
            p_pdqcb = ((PDQCB *) queue_delete_next(&free_pdqcb));
            p_pdqinib = (PDQINIB *)(p_pdqcb->p_pdqinib);
            p_pdqinib->pdqatr = pdqatr;
            p_pdqinib->pdqcnt = pk_cpdq->pdqcnt;
            p_pdqinib->maxdpri = pk_cpdq->maxdpri;
            p_pdqinib->p_pdqmb = p_pdqmb;

            queue_initialize(&(p_pdqcb->swait_queue));
            queue_initialize(&(p_pdqcb->rwait_queue));
            p_pdqcb->count = 0U;
            p_pdqcb->p_head = NULL;
            p_pdqcb->unused = 0U;
            p_pdqcb->p_freelist = NULL;
            ercd = PDQID(p_pdqcb);
        }
    }
    t_unlock_cpu();

error_exit:
    LOG_ACRE_PDQ_LEAVE(ercd);
    return(ercd);
}
Exemple #7
0
ER_UINT
acre_isr(const T_CISR *pk_cisr)
{
	ISRCB	*p_isrcb;
	ISRINIB	*p_isrinib;
	QUEUE	*p_isr_queue;
	ER		ercd;

	LOG_ACRE_ISR_ENTER(pk_cisr);
	CHECK_TSKCTX_UNL();
	CHECK_MACV_READ(pk_cisr, T_CISR);
	CHECK_RSATR(pk_cisr->isratr, TARGET_ISRATR|TA_DOMMASK);
	CHECK_ATRDOMID_KERNEL(get_atrdomid(pk_cisr->isratr));
	CHECK_INTNO_CREISR(pk_cisr->intno);
	CHECK_ALIGN_FUNC(pk_cisr->isr);
	CHECK_NONNULL_FUNC(pk_cisr->isr);
	CHECK_ISRPRI(pk_cisr->isrpri);
	CHECK_ACPTN(sysstat_acvct.acptn3);

	p_isr_queue = search_isr_queue(pk_cisr->intno);
	CHECK_OBJ(p_isr_queue != NULL);

	t_lock_cpu();
	if (tnum_isr == 0 || queue_empty(&free_isrcb)) {
		ercd = E_NOID;
	}
	else {
		p_isrcb = ((ISRCB *) queue_delete_next(&free_isrcb));
		p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
		p_isrinib->isratr = pk_cisr->isratr;
		p_isrinib->exinf = pk_cisr->exinf;
		p_isrinib->intno = pk_cisr->intno;
		p_isrinib->p_isr_queue = p_isr_queue;
		p_isrinib->isr = pk_cisr->isr;
		p_isrinib->isrpri = pk_cisr->isrpri;

		p_isrinib->acvct.acptn1 = TACP_KERNEL;
		p_isrinib->acvct.acptn2 = TACP_KERNEL;
		p_isrinib->acvct.acptn3 = TACP_KERNEL | rundom;
		p_isrinib->acvct.acptn4 = TACP_KERNEL;

		enqueue_isr(p_isr_queue, p_isrcb);
		ercd = ISRID(p_isrcb);
	}
	t_unlock_cpu();

  error_exit:
	LOG_ACRE_ISR_LEAVE(ercd);
	return(ercd);
}
Exemple #8
0
ER_UINT
acre_dtq(const T_CDTQ *pk_cdtq)
{
	DTQCB		*p_dtqcb;
	DTQINIB		*p_dtqinib;
	ATR			dtqatr;
	DTQMB		*p_dtqmb;
	ER			ercd;

	LOG_ACRE_DTQ_ENTER(pk_cdtq);
	CHECK_TSKCTX_UNL();
	CHECK_RSATR(pk_cdtq->dtqatr, TA_TPRI);
	dtqatr = pk_cdtq->dtqatr;
	p_dtqmb = pk_cdtq->dtqmb;

	t_lock_cpu();
	if (queue_empty(&free_dtqcb)) {
		ercd = E_NOID;
	}
	else {
		if (pk_cdtq->dtqcnt != 0 && p_dtqmb == NULL) {
			p_dtqmb = kernel_malloc(sizeof(DTQMB) * pk_cdtq->dtqcnt);
			dtqatr |= TA_MBALLOC;
		}
		if (pk_cdtq->dtqcnt != 0 && p_dtqmb == NULL) {
			ercd = E_NOMEM;
		}
		else {
			p_dtqcb = ((DTQCB *) queue_delete_next(&free_dtqcb));
			p_dtqinib = (DTQINIB *)(p_dtqcb->p_dtqinib);
			p_dtqinib->dtqatr = dtqatr;
			p_dtqinib->dtqcnt = pk_cdtq->dtqcnt;
			p_dtqinib->p_dtqmb = p_dtqmb;

			queue_initialize(&(p_dtqcb->swait_queue));
			queue_initialize(&(p_dtqcb->rwait_queue));
			p_dtqcb->count = 0U;
			p_dtqcb->head = 0U;
			p_dtqcb->tail = 0U;
			ercd = DTQID(p_dtqcb);
		}
	}
	t_unlock_cpu();

  error_exit:
	LOG_ACRE_DTQ_LEAVE(ercd);
	return(ercd);
}
Exemple #9
0
/*
 * Create rendezvous port
 */
SYSCALL ID _tk_cre_por( CONST T_CPOR *pk_cpor )
{
#if CHK_RSATR
	const ATR VALID_PORATR = {
		 TA_TPRI
		|TA_NODISWAI
#if USE_OBJECT_NAME
		|TA_DSNAME
#endif
	};
#endif
	PORCB	*porcb;
	ID	porid;
	ER	ercd;

	CHECK_RSATR(pk_cpor->poratr, VALID_PORATR);
	CHECK_PAR(pk_cpor->maxcmsz >= 0);
	CHECK_PAR(pk_cpor->maxrmsz >= 0);
	CHECK_INTSK();

	BEGIN_CRITICAL_SECTION;
	/* Get control block from FreeQue */
	porcb = (PORCB*)QueRemoveNext(&free_porcb);
	if ( porcb == NULL ) {
		ercd = E_LIMIT;
	} else {
		porid = ID_POR(porcb - porcb_table);

		/* Initialize control block */
		QueInit(&porcb->call_queue);
		porcb->porid = porid;
		porcb->exinf = pk_cpor->exinf;
		porcb->poratr = pk_cpor->poratr;
		QueInit(&porcb->accept_queue);
		porcb->maxcmsz = pk_cpor->maxcmsz;
		porcb->maxrmsz = pk_cpor->maxrmsz;
#if USE_OBJECT_NAME
		if ( (pk_cpor->poratr & TA_DSNAME) != 0 ) {
			strncpy((char*)porcb->name, (char*)pk_cpor->dsname,
				OBJECT_NAME_LENGTH);
		}
#endif
		ercd = porid;
	}
	END_CRITICAL_SECTION;

	return ercd;
}
Exemple #10
0
/*
 * Create semaphore
 */
SYSCALL ID tk_cre_sem_impl( T_CSEM *pk_csem )
{
#if CHK_RSATR
	const ATR VALID_SEMATR = {
		 TA_TPRI
		|TA_CNT
#if USE_OBJECT_NAME
		|TA_DSNAME
#endif
	};
#endif
	SEMCB	*semcb;
	ID	semid;
	ER	ercd;

	CHECK_RSATR(pk_csem->sematr, VALID_SEMATR);
	CHECK_PAR(pk_csem->isemcnt >= 0);
	CHECK_PAR(pk_csem->maxsem > 0);
	CHECK_PAR(pk_csem->maxsem >= pk_csem->isemcnt);

	BEGIN_CRITICAL_SECTION;
	/* Get control block from FreeQue */
	semcb = (SEMCB*)QueRemoveNext(&knl_free_semcb);
	if ( semcb == NULL ) {
		ercd = E_LIMIT;
	} else {
		semid = ID_SEM(semcb - knl_semcb_table);

		/* Initialize control block */
		QueInit(&semcb->wait_queue);
		semcb->semid = semid;
		semcb->exinf = pk_csem->exinf;
		semcb->sematr = pk_csem->sematr;
		semcb->semcnt = pk_csem->isemcnt;
		semcb->maxsem = pk_csem->maxsem;
#if USE_OBJECT_NAME
		if ( (pk_csem->sematr & TA_DSNAME) != 0 ) {
			strncpy((char*)semcb->name, (char*)pk_csem->dsname,
				OBJECT_NAME_LENGTH);
		}
#endif
		ercd = semid;
	}
	END_CRITICAL_SECTION;

	return ercd;
}
Exemple #11
0
ER_UINT
acre_sem(const T_CSEM *pk_csem)
{
    ID		domid;
    SEMCB	*p_semcb;
    SEMINIB	*p_seminib;
    ACPTN	acptn;
    ER		ercd;

    LOG_ACRE_SEM_ENTER(pk_csem);
    CHECK_TSKCTX_UNL();
    CHECK_MACV_READ(pk_csem, T_CSEM);
    CHECK_RSATR(pk_csem->sematr, TA_TPRI|TA_DOMMASK);
    domid = get_atrdomid(pk_csem->sematr);
    CHECK_ATRDOMID_INACTIVE(domid);
    CHECK_PAR(0 <= pk_csem->isemcnt && pk_csem->isemcnt <= pk_csem->maxsem);
    CHECK_PAR(1 <= pk_csem->maxsem && pk_csem->maxsem <= TMAX_MAXSEM);
    CHECK_ACPTN(sysstat_acvct.acptn3);

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

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

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

error_exit:
    LOG_ACRE_SEM_LEAVE(ercd);
    return(ercd);
}
ER_UINT
acre_cyc(const T_CCYC *pk_ccyc)
{
	CYCCB	*p_cyccb;
	CYCINIB	*p_cycinib;
	ER		ercd;

	LOG_ACRE_CYC_ENTER(pk_ccyc);
	CHECK_TSKCTX_UNL();
	CHECK_RSATR(pk_ccyc->cycatr, TA_STA);
	CHECK_ALIGN_FUNC(pk_ccyc->cychdr);
	CHECK_NONNULL_FUNC(pk_ccyc->cychdr);
	CHECK_PAR(0 < pk_ccyc->cyctim && pk_ccyc->cyctim <= TMAX_RELTIM);
	CHECK_PAR(0 <= pk_ccyc->cycphs && pk_ccyc->cycphs <= TMAX_RELTIM);

	t_lock_cpu();
	if (tnum_cyc == 0 || queue_empty(&free_cyccb)) {
		ercd = E_NOID;
	}
	else {
		p_cyccb = ((CYCCB *)(((char *) queue_delete_next(&free_cyccb))
												- offsetof(CYCCB, tmevtb)));
		p_cycinib = (CYCINIB *)(p_cyccb->p_cycinib);
		p_cycinib->cycatr = pk_ccyc->cycatr;
		p_cycinib->exinf = pk_ccyc->exinf;
		p_cycinib->cychdr = pk_ccyc->cychdr;
		p_cycinib->cyctim = pk_ccyc->cyctim;
		p_cycinib->cycphs = pk_ccyc->cycphs;

		if ((p_cyccb->p_cycinib->cycatr & TA_STA) != 0U) {
			p_cyccb->cycsta = true;
			tmevtb_enqueue_cyc(p_cyccb,
								base_time + p_cyccb->p_cycinib->cycphs);
		}
		else {
			p_cyccb->cycsta = false;
		}
		ercd = CYCID(p_cyccb);
	}
	t_unlock_cpu();

  error_exit:
	LOG_ACRE_CYC_LEAVE(ercd);
	return(ercd);
}
ER_UINT
acre_alm(const T_CALM *pk_calm)
{
	ALMCB		*p_almcb;
	ALMINIB		*p_alminib;
	T_NFYINFO	*p_nfyinfo;
	ER			ercd, rercd;

	LOG_ACRE_ALM_ENTER(pk_calm);
	CHECK_TSKCTX_UNL();
	CHECK_RSATR(pk_calm->almatr, TA_NULL);
	rercd = check_nfyinfo(&(pk_calm->nfyinfo));
	if (rercd != E_OK) {
		ercd = rercd;
		goto error_exit;
	}

	lock_cpu();
	if (tnum_alm == 0 || queue_empty(&free_almcb)) {
		ercd = E_NOID;
	}
	else {
		p_almcb = ((ALMCB *)(((char *) queue_delete_next(&free_almcb))
												- offsetof(ALMCB, tmevtb)));
		p_alminib = (ALMINIB *)(p_almcb->p_alminib);
		p_alminib->almatr = pk_calm->almatr;
		if (pk_calm->nfyinfo.nfymode == TNFY_HANDLER) {
			p_alminib->exinf = pk_calm->nfyinfo.nfy.handler.exinf;
			p_alminib->nfyhdr = (NFYHDR)(pk_calm->nfyinfo.nfy.handler.tmehdr);
		}
		else {
			p_nfyinfo = &aalm_nfyinfo_table[p_alminib - aalminib_table];
			*p_nfyinfo = pk_calm->nfyinfo;
			p_alminib->exinf = (intptr_t) p_nfyinfo;
			p_alminib->nfyhdr = notify_handler;
		}
		p_almcb->almsta = false;
		ercd = ALMID(p_almcb);
	}
	unlock_cpu();

  error_exit:
	LOG_ACRE_ALM_LEAVE(ercd);
	return(ercd);
}
/*
 * Interrupt handler definition
 */
SYSCALL ER tk_def_int_impl( UINT dintno, T_DINT *pk_dint )
{
	FP	inthdr;

	CHECK_PAR(dintno < N_INTVEC);
#if !USE_HLL_INTHDR
	CHECK_PAR((pk_dint->intatr & TA_HLNG) == 0);
#endif

	if ( pk_dint != NULL ) {
		/* Set interrupt handler */
		CHECK_RSATR(pk_dint->intatr, TA_HLNG);
#if PSR_DI == PSR_I
		CHECK_PAR( !(dintno == EIT_FIQ
				&& (pk_dint->intatr & TA_HLNG) != 0) );
#endif

		inthdr = pk_dint->inthdr;

		BEGIN_CRITICAL_SECTION;
#if USE_HLL_INTHDR
		if ( (pk_dint->intatr & TA_HLNG) != 0 ) {
			knl_hll_inthdr[dintno] = inthdr;
			inthdr = (dintno < 32) ? knl_inthdr_startup:
									 knl_exchdr_startup; /* SWI handler */
		}
#endif
		knl_define_inthdr(dintno, inthdr);
		END_CRITICAL_SECTION;
	} else {
		/* Clear interrupt handler */
		switch ( dintno ) {
		  default:		inthdr = NULL;
		}

		BEGIN_CRITICAL_SECTION;
		knl_define_inthdr(dintno, inthdr);
#if USE_HLL_INTHDR
		knl_hll_inthdr[dintno] = NULL;
#endif
		END_CRITICAL_SECTION;
	}

	return E_OK;
}
/*
 * Definition of subsystem
 */
SYSCALL ER tk_def_ssy_impl P2( ID ssid, T_DSSY *pk_dssy )
{
	SSYCB	*ssycb;
	ER	ercd = E_OK;

	CHECK_SSYID(ssid);
#if CHK_RSATR
	if ( pk_dssy != NULL ) {
		CHECK_RSATR(pk_dssy->ssyatr, TA_NULL|TA_GP);
	}
#endif

	ssycb = get_ssycb(ssid);

	BEGIN_CRITICAL_SECTION;
	if ( pk_dssy != NULL ) {
		/* Register */
		if ( ssycb->svchdr != knl_no_support ) {
			ercd = E_OBJ;  /* Registered */
			goto error_exit;
		}
		ssycb->svchdr    = (SVC)pk_dssy->svchdr;
#if TA_GP
		if ( (pk_dssy->ssyatr & TA_GP) != 0 ) {
			gp = pk_dssy->gp;
		}
		ssycb->gp = gp;
#endif

	} else {
		/* Delete */
		if ( ssycb->svchdr == knl_no_support ) {
			ercd = E_NOEXS;  /* Not registered */
			goto error_exit;
		}

		ssycb->svchdr    = knl_no_support;
	}

    error_exit:
	END_CRITICAL_SECTION;

	return ercd;
}
Exemple #16
0
/*
 * Create mailbox
 */
SYSCALL ID _tk_cre_mbx( CONST T_CMBX *pk_cmbx )
{
#if CHK_RSATR
	const ATR VALID_MBXATR = {
		 TA_MPRI
		|TA_TPRI
		|TA_NODISWAI
#if USE_OBJECT_NAME
		|TA_DSNAME
#endif
	};
#endif
	MBXCB	*mbxcb;
	ID	mbxid;
	ER	ercd;

	CHECK_RSATR(pk_cmbx->mbxatr, VALID_MBXATR);

	BEGIN_CRITICAL_SECTION;
	/* Get control block from FreeQue */
	mbxcb = (MBXCB*)QueRemoveNext(&free_mbxcb);
	if ( mbxcb == NULL ) {
		ercd = E_LIMIT;
	} else {
		mbxid = ID_MBX(mbxcb - mbxcb_table);

		/* Initialize control block */
		QueInit(&mbxcb->wait_queue);
		mbxcb->mbxid  = mbxid;
		mbxcb->exinf  = pk_cmbx->exinf;
		mbxcb->mbxatr = pk_cmbx->mbxatr;
		mbxcb->mq_head.msgque[0] = NULL;
#if USE_OBJECT_NAME
		if ( (pk_cmbx->mbxatr & TA_DSNAME) != 0 ) {
			STRNCPY((char*)mbxcb->name, (char*)pk_cmbx->dsname,
				OBJECT_NAME_LENGTH);
		}
#endif
		ercd = mbxid;
	}
	END_CRITICAL_SECTION;

	return ercd;
}
/*
 * Create event flag
 */
SYSCALL ID tk_cre_flg_impl( T_CFLG *pk_cflg )
{
#if CHK_RSATR
	const ATR VALID_FLGATR = {
		 TA_TPRI
		|TA_WMUL
#if USE_OBJECT_NAME
		|TA_DSNAME
#endif
	};
#endif
	FLGCB	*flgcb;
	ID	flgid;
	ER	ercd;

	CHECK_RSATR(pk_cflg->flgatr, VALID_FLGATR);

	BEGIN_CRITICAL_SECTION;
	/* Get control block from FreeQue */
	flgcb = (FLGCB*)QueRemoveNext(&knl_free_flgcb);
	if ( flgcb == NULL ) {
		ercd = E_LIMIT;
	} else {
		flgid = ID_FLG(flgcb - knl_flgcb_table);

		/* Initialize control block */
		QueInit(&flgcb->wait_queue);
		flgcb->flgid = flgid;
		flgcb->exinf = pk_cflg->exinf;
		flgcb->flgatr = pk_cflg->flgatr;
		flgcb->flgptn = pk_cflg->iflgptn;
#if USE_OBJECT_NAME
		if ( (pk_cflg->flgatr & TA_DSNAME) != 0 ) {
			strncpy((char*)flgcb->name, (char*)pk_cflg->dsname,
				OBJECT_NAME_LENGTH);
		}
#endif
		ercd = flgid;
	}
	END_CRITICAL_SECTION;

	return ercd;
}
Exemple #18
0
ER_UINT
acre_flg(const T_CFLG *pk_cflg)
{
    ID		domid;
    FLGCB	*p_flgcb;
    FLGINIB	*p_flginib;
    ACPTN	acptn;
    ER		ercd;

    LOG_ACRE_FLG_ENTER(pk_cflg);
    CHECK_TSKCTX_UNL();
    CHECK_MACV_READ(pk_cflg, T_CFLG);
    CHECK_RSATR(pk_cflg->flgatr, TA_TPRI|TA_WMUL|TA_CLR|TA_DOMMASK);
    domid = get_atrdomid(pk_cflg->flgatr);
    CHECK_ATRDOMID_INACTIVE(domid);
    CHECK_ACPTN(sysstat_acvct.acptn3);

    t_lock_cpu();
    if (tnum_flg == 0 || queue_empty(&free_flgcb)) {
        ercd = E_NOID;
    }
    else {
        p_flgcb = ((FLGCB *) queue_delete_next(&free_flgcb));
        p_flginib = (FLGINIB *)(p_flgcb->p_flginib);
        p_flginib->flgatr = pk_cflg->flgatr;
        p_flginib->iflgptn = pk_cflg->iflgptn;

        acptn = default_acptn(domid);
        p_flginib->acvct.acptn1 = acptn;
        p_flginib->acvct.acptn2 = acptn;
        p_flginib->acvct.acptn3 = acptn | rundom;
        p_flginib->acvct.acptn4 = acptn;

        queue_initialize(&(p_flgcb->wait_queue));
        p_flgcb->flgptn = p_flgcb->p_flginib->iflgptn;
        ercd = FLGID(p_flgcb);
    }
    t_unlock_cpu();

error_exit:
    LOG_ACRE_FLG_LEAVE(ercd);
    return(ercd);
}
Exemple #19
0
ER_UINT
acre_isr(const T_CISR *pk_cisr)
{
	ISRCB	*p_isrcb;
	ISRINIB	*p_isrinib;
	QUEUE	*p_isr_queue;
	ER		ercd;

	LOG_ACRE_ISR_ENTER(pk_cisr);
	CHECK_TSKCTX_UNL();
	CHECK_RSATR(pk_cisr->isratr, TARGET_ISRATR);
	CHECK_INTNO_CREISR(pk_cisr->intno);
	CHECK_ALIGN_FUNC(pk_cisr->isr);
	CHECK_NONNULL_FUNC(pk_cisr->isr);
	CHECK_ISRPRI(pk_cisr->isrpri);

	p_isr_queue = search_isr_queue(pk_cisr->intno);
	CHECK_OBJ(p_isr_queue != NULL);

	t_lock_cpu();
	if (tnum_isr == 0 || queue_empty(&free_isrcb)) {
		ercd = E_NOID;
	}
	else {
		p_isrcb = ((ISRCB *) queue_delete_next(&free_isrcb));
		p_isrinib = (ISRINIB *)(p_isrcb->p_isrinib);
		p_isrinib->isratr = pk_cisr->isratr;
		p_isrinib->exinf = pk_cisr->exinf;
		p_isrinib->intno = pk_cisr->intno;
		p_isrinib->p_isr_queue = p_isr_queue;
		p_isrinib->isr = pk_cisr->isr;
		p_isrinib->isrpri = pk_cisr->isrpri;
		enqueue_isr(p_isr_queue, p_isrcb);
		ercd = ISRID(p_isrcb);
	}
	t_unlock_cpu();

  error_exit:
	LOG_ACRE_ISR_LEAVE(ercd);
	return(ercd);
}
/*
 * 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;
}
Exemple #21
0
/*
 * Create message buffer
 */
SYSCALL ID _tk_cre_mbf( CONST T_CMBF *pk_cmbf )
{
#if CHK_RSATR
	const ATR VALID_MBFATR = {
		 TA_TPRI
		|TA_NODISWAI
#if USE_OBJECT_NAME
		|TA_DSNAME
#endif
	};
#endif
	MBFCB	*mbfcb;
	ID	mbfid;
	INT	bufsz;
	VB	*msgbuf;
	ER	ercd;

	CHECK_RSATR(pk_cmbf->mbfatr, VALID_MBFATR);
	CHECK_PAR(pk_cmbf->bufsz >= 0);
	CHECK_PAR(pk_cmbf->maxmsz > 0);
	bufsz = (INT)ROUNDSZ(pk_cmbf->bufsz);

	if ( bufsz > 0 ) {
		msgbuf = Imalloc((UINT)bufsz);
		if ( msgbuf == NULL ) {
			return E_NOMEM;
		}
	} else {
		msgbuf = NULL;
	}

	BEGIN_CRITICAL_SECTION;
	/* Get control block from FreeQue */
	mbfcb = (MBFCB*)QueRemoveNext(&free_mbfcb);
	if ( mbfcb == NULL ) {
		ercd = E_LIMIT;
	} else {
		mbfid = ID_MBF(mbfcb - mbfcb_table);

		/* Initialize control block */
		QueInit(&mbfcb->send_queue);
		mbfcb->mbfid = mbfid;
		mbfcb->exinf = pk_cmbf->exinf;
		mbfcb->mbfatr = pk_cmbf->mbfatr;
		QueInit(&mbfcb->recv_queue);
		mbfcb->buffer = msgbuf;
		mbfcb->bufsz = mbfcb->frbufsz = bufsz;
		mbfcb->maxmsz = pk_cmbf->maxmsz;
		mbfcb->head = mbfcb->tail = 0;
#if USE_OBJECT_NAME
		if ( (pk_cmbf->mbfatr & TA_DSNAME) != 0 ) {
			strncpy((char*)mbfcb->name, (char*)pk_cmbf->dsname,
				OBJECT_NAME_LENGTH);
		}
#endif
		ercd = mbfid;
	}
	END_CRITICAL_SECTION;

	if ( ercd < E_OK && msgbuf != NULL ) {
		Ifree(msgbuf);
	}

	return ercd;
}
Exemple #22
0
/*
 * 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;
}
Exemple #23
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;
}
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);
}
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);
}
Exemple #26
0
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);
}
Exemple #27
0
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);
}
Exemple #28
0
/*
 * 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;
}
Exemple #29
0
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);
}
Exemple #30
0
ER_UINT
acre_pdq(const T_CPDQ *pk_cpdq)
{
	ID		domid;
	PDQCB	*p_pdqcb;
	PDQINIB	*p_pdqinib;
	ATR		pdqatr;
	PDQMB	*p_pdqmb;
	ACPTN	acptn;
	ER		ercd;

	LOG_ACRE_PDQ_ENTER(pk_cpdq);
	CHECK_TSKCTX_UNL();
	CHECK_MACV_READ(pk_cpdq, T_CPDQ);
	CHECK_RSATR(pk_cpdq->pdqatr, TA_TPRI|TA_DOMMASK);
	domid = get_atrdomid(pk_cpdq->pdqatr);
	CHECK_ATRDOMID_INACTIVE(domid);
	CHECK_DPRI(pk_cpdq->maxdpri);
	if (pk_cpdq->pdqmb != NULL) {
		CHECK_ALIGN_MB(pk_cpdq->pdqmb);
		CHECK_OBJ(valid_memobj_kernel(pk_cpdq->pdqmb,
									sizeof(PDQMB) * pk_cpdq->pdqcnt));
	}
	CHECK_ACPTN(sysstat_acvct.acptn3);
	pdqatr = pk_cpdq->pdqatr;
	p_pdqmb = pk_cpdq->pdqmb;

	t_lock_cpu();
	if (tnum_pdq == 0 || queue_empty(&free_pdqcb)) {
		ercd = E_NOID;
	}
	else {
		if (pk_cpdq->pdqcnt != 0 && p_pdqmb == NULL) {
			p_pdqmb = kernel_malloc(sizeof(PDQMB) * pk_cpdq->pdqcnt);
			pdqatr |= TA_MBALLOC;
		}
		if (pk_cpdq->pdqcnt != 0 && p_pdqmb == NULL) {
			ercd = E_NOMEM;
		}
		else {
			p_pdqcb = ((PDQCB *) queue_delete_next(&free_pdqcb));
			p_pdqinib = (PDQINIB *)(p_pdqcb->p_pdqinib);
			p_pdqinib->pdqatr = pdqatr;
			p_pdqinib->pdqcnt = pk_cpdq->pdqcnt;
			p_pdqinib->maxdpri = pk_cpdq->maxdpri;
			p_pdqinib->p_pdqmb = p_pdqmb;

			acptn = default_acptn(domid);
			p_pdqinib->acvct.acptn1 = acptn;
			p_pdqinib->acvct.acptn2 = acptn;
			p_pdqinib->acvct.acptn3 = acptn | rundom;
			p_pdqinib->acvct.acptn4 = acptn;

			queue_initialize(&(p_pdqcb->swait_queue));
			queue_initialize(&(p_pdqcb->rwait_queue));
			p_pdqcb->count = 0U;
			p_pdqcb->p_head = NULL;
			p_pdqcb->unused = 0U;
			p_pdqcb->p_freelist = NULL;
			ercd = PDQID(p_pdqcb);
		}
	}
	t_unlock_cpu();

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