예제 #1
0
ER
slp_tsk(void)
{
	WINFO	winfo;
	ER		ercd;

	LOG_SLP_TSK_ENTER();
	CHECK_DISPATCH();

	t_lock_cpu();
	if (p_runtsk->wupque) {
		p_runtsk->wupque = false;
		ercd = E_OK;
	}
	else {
		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP);
		make_wait(&winfo);
		LOG_TSKSTAT(p_runtsk);
		dispatch();
		ercd = winfo.wercd;
	}
	t_unlock_cpu();

  error_exit:
	LOG_SLP_TSK_LEAVE(ercd);
	return(ercd);
}
예제 #2
0
JSP_L1_CODE
SYSCALL ER
twai_sem(ID semid, TMO tmout)
{
	SEMCB	*semcb;
	WINFO_WOBJ winfo;
	TMEVTB	tmevtb;
	ER	ercd;

	LOG_TWAI_SEM_ENTER(semid, tmout);
	CHECK_DISPATCH();
	CHECK_SEMID(semid);
	CHECK_TMOUT(tmout);
	semcb = get_semcb(semid);

	t_lock_cpu();
	if (semcb->semcnt >= 1) {
		semcb->semcnt -= 1;
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		wobj_make_wait_tmout((WOBJCB *) semcb, &winfo, &tmevtb, tmout);
		dispatch();
		ercd = winfo.winfo.wercd;
	}
	t_unlock_cpu();

    exit:
	LOG_TWAI_SEM_LEAVE(ercd);
	return(ercd);
}
예제 #3
0
ER
tslp_tsk(TMO tmout)
{
	WINFO	winfo;
	TMEVTB	tmevtb;
	ER		ercd;

	LOG_TSLP_TSK_ENTER(tmout);
	CHECK_DISPATCH();
	CHECK_TMOUT(tmout);

	t_lock_cpu();
	if (p_runtsk->wupque) {
		p_runtsk->wupque = false;
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP);
		make_wait_tmout(&winfo, &tmevtb, tmout);
		LOG_TSKSTAT(p_runtsk);
		dispatch();
		ercd = winfo.wercd;
	}
	t_unlock_cpu();

  error_exit:
	LOG_TSLP_TSK_LEAVE(ercd);
	return(ercd);
}
예제 #4
0
ER
dly_tsk(RELTIM dlytim)
{
	WINFO	winfo;
	TMEVTB	tmevtb;
	ER		ercd;

	LOG_DLY_TSK_ENTER(dlytim);
	CHECK_DISPATCH();
	CHECK_PAR(dlytim <= TMAX_RELTIM);

	t_lock_cpu();
	p_runtsk->tstat = (TS_WAITING | TS_WAIT_DLY);
	(void) make_non_runnable(p_runtsk);
	p_runtsk->p_winfo = &winfo;
	winfo.p_tmevtb = &tmevtb;
	tmevtb_enqueue(&tmevtb, dlytim, (CBACK) wait_tmout_ok, (void *) p_runtsk);
	LOG_TSKSTAT(p_runtsk);
	dispatch();
	ercd = winfo.wercd;
	t_unlock_cpu();

  error_exit:
	LOG_DLY_TSK_LEAVE(ercd);
	return(ercd);
}
예제 #5
0
SYSCALL ER
i_vtrcv_tmb(T_MSG **ppk_msg, TMO tmout)
	{
	ER	ercd = E_OK;
    
	CHECK_TMOUT(tmout);
	CHECK_DISPATCH();

	BEGIN_CRITICAL_SECTION;
	if ( ctxtsk->tmq_head ) 
		{
		*ppk_msg = ctxtsk->tmq_head;
		ctxtsk->tmq_head = nextmsg(*ppk_msg);
		}
	else 
		{
		ercd = E_TMOUT;
		if ( tmout != TMO_POL ) 
			{
			ctxtsk->wspec = &wspec_tmb_tfifo;
			ctxtsk->wgcb = (GCB *) 0;
			ctxtsk->wercd = &ercd;
			ctxtsk->winfo.tmb.ppk_msg = ppk_msg;
			make_wait(tmout);
			queue_initialize(&(ctxtsk->tskque));
			}
		}
	END_CRITICAL_SECTION;
	return(ercd);
	}
예제 #6
0
JSP_L1_CODE
SYSCALL ER
wai_sem(ID semid)
{
	SEMCB	*semcb;
	WINFO_WOBJ winfo;
	ER	ercd;

	LOG_WAI_SEM_ENTER(semid);
	CHECK_DISPATCH();
	CHECK_SEMID(semid);
	semcb = get_semcb(semid);

	t_lock_cpu();
	if (semcb->semcnt >= 1) {
		semcb->semcnt -= 1;
		ercd = E_OK;
	}
	else {
		wobj_make_wait((WOBJCB *) semcb, &winfo);
		dispatch();
		ercd = winfo.winfo.wercd;
	}
	t_unlock_cpu();

    exit:
	LOG_WAI_SEM_LEAVE(ercd);
	return(ercd);
}
예제 #7
0
파일: mailbox.c 프로젝트: Ashatta/tools
SYSCALL ER
rcv_mbx(ID mbxid, T_MSG **ppk_msg)
{
	MBXCB	*mbxcb;
	WINFO_MBX winfo;
	ER	ercd;
    
	LOG_RCV_MBX_ENTER(mbxid, ppk_msg);
	CHECK_DISPATCH();
	CHECK_MBXID(mbxid);
	mbxcb = get_mbxcb(mbxid);
    
	t_lock_cpu();
	if (mbxcb->head != NULL) {
		*ppk_msg = mbxcb->head;
		mbxcb->head = (*ppk_msg)->next;
		ercd = E_OK;
	}
	else {
		wobj_make_wait((WOBJCB *) mbxcb, (WINFO_WOBJ *) &winfo);
		dispatch();
		ercd = winfo.winfo.wercd;
		if (ercd == E_OK) {
			*ppk_msg = winfo.pk_msg;
		}
	}
	t_unlock_cpu();

    exit:
	LOG_RCV_MBX_LEAVE(ercd, *ppk_msg);
	return(ercd);
}
예제 #8
0
SYSCALL INT _tk_rcv_mbf_u( ID mbfid, void *msg, TMO_U tmout )
{
	MBFCB	*mbfcb;
	TCB	*tcb;
	INT	rcvsz;
	ER	ercd = E_OK;

	CHECK_MBFID(mbfid);
	CHECK_TMOUT(tmout);
	CHECK_DISPATCH();

	mbfcb = get_mbfcb(mbfid);

	BEGIN_CRITICAL_SECTION;
	if (mbfcb->mbfid == 0) {
		ercd = E_NOEXS;
		goto error_exit;
	}

	/* Check receive wait disable */
	if ( is_diswai((GCB*)mbfcb, ctxtsk, TTW_RMBF) ) {
		ercd = E_DISWAI;
		goto error_exit;
	}

	if ( !mbf_empty(mbfcb) ) {
		/* Read from message buffer */
		rcvsz = mbf_to_msg(mbfcb, msg);

		/* Accept message from sending task(s) */
		mbf_wakeup(mbfcb);

	} else if ( !isQueEmpty(&mbfcb->send_queue) ) {
		/* Receive directly from send wait task */
		tcb = (TCB*)mbfcb->send_queue.next;
		rcvsz = tcb->winfo.smbf.msgsz;
		memcpy(msg, tcb->winfo.smbf.msg, (UINT)rcvsz);
		wait_release_ok(tcb);
		mbf_wakeup(mbfcb);
	} else {
		ercd = E_TMOUT;
		if ( tmout != TMO_POL ) {
			/* Ready for receive wait */
			ctxtsk->wspec = &wspec_rmbf;
			ctxtsk->wid = mbfid;
			ctxtsk->wercd = &ercd;
			ctxtsk->winfo.rmbf.msg = msg;
			ctxtsk->winfo.rmbf.p_msgsz = &rcvsz;
			make_wait(tmout, mbfcb->mbfatr);
			QueInsert(&ctxtsk->tskque, &mbfcb->recv_queue);
		}
	}

    error_exit:
	END_CRITICAL_SECTION;

	return ( ercd < E_OK )? ercd: rcvsz;
}
예제 #9
0
ER
trcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri, TMO tmout)
{
	PDQCB	*p_pdqcb;
	WINFO_PDQ winfo_pdq;
	TMEVTB	tmevtb;
	bool_t	dspreq;
	ER		ercd;

	LOG_TRCV_PDQ_ENTER(pdqid, p_data, p_datapri, tmout);
	CHECK_DISPATCH();
	CHECK_PDQID(pdqid);
	CHECK_MACV_WRITE(p_data, intptr_t);
	CHECK_MACV_WRITE(p_datapri, PRI);
	CHECK_TMOUT(tmout);
	p_pdqcb = get_pdqcb(pdqid);


	t_lock_cpu();
	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else if (VIOLATE_ACPTN(p_pdqcb->p_pdqinib->acvct.acptn2)) {
		ercd = E_OACV;
	}
	else if (receive_pridata(p_pdqcb, p_data, p_datapri, &dspreq)) {
		if (dspreq) {
			dispatch();
		}
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else if (p_runtsk->waifbd) {
		ercd = E_RLWAI;
	}
	else {
		p_runtsk->tstat = (TS_WAITING | TS_WAIT_RPDQ);
		make_wait_tmout(&(winfo_pdq.winfo), &tmevtb, tmout);
		queue_insert_prev(&(p_pdqcb->rwait_queue), &(p_runtsk->task_queue));
		winfo_pdq.p_pdqcb = p_pdqcb;
		LOG_TSKSTAT(p_runtsk);
		dispatch();
		ercd = winfo_pdq.winfo.wercd;
		if (ercd == E_OK) {
			*p_data = winfo_pdq.data;
			*p_datapri = winfo_pdq.datapri;
		}
	}
	t_unlock_cpu();

  error_exit:
	LOG_TRCV_PDQ_LEAVE(ercd, *p_data, *p_datapri);
	return(ercd);
}
예제 #10
0
ER
loc_mtx(ID mtxid)
{
	MTXCB		*p_mtxcb;
	WINFO_MTX	winfo_mtx;
	ER			ercd;

	LOG_LOC_MTX_ENTER(mtxid);
	CHECK_DISPATCH();
	CHECK_ID(VALID_MTXID(mtxid));
	p_mtxcb = get_mtxcb(mtxid);

	lock_cpu_dsp();
	if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else if (VIOLATE_ACPTN(p_mtxcb->p_mtxinib->acvct.acptn1)) {
		ercd = E_OACV;
	}
	else if (MTX_CEILING(p_mtxcb)
			&& p_mtxcb->p_mtxinib->ceilpri < p_runtsk->p_dominib->minpriority
			&& VIOLATE_ACPTN(p_runtsk->p_dominib->acvct.acptn2)) {
		ercd = E_OACV;									/*[NGKI5124]*/
	}
	else if (p_runtsk->raster) {
		ercd = E_RASTER;
	}
	else if (MTX_CEILING(p_mtxcb)
				&& p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
		ercd = E_ILUSE;
	}
	else if (p_mtxcb->p_loctsk == NULL) {
		mutex_acquire(p_runtsk, p_mtxcb);
		/*
		 *  優先度上限ミューテックスをロックした場合,p_runtskの優先度
		 *  が上がる可能性があるが,ディスパッチが必要になることはない.
		 */
		assert(p_runtsk == p_schedtsk);
		ercd = E_OK;
	}
	else if (p_mtxcb->p_loctsk == p_runtsk) {
		ercd = E_OBJ;
	}
	else {
		wobj_make_wait((WOBJCB *) p_mtxcb, TS_WAITING_MTX,
											(WINFO_WOBJ *) &winfo_mtx);
		dispatch();
		ercd = winfo_mtx.winfo.wercd;
	}
	unlock_cpu_dsp();

  error_exit:
	LOG_LOC_MTX_LEAVE(ercd);
	return(ercd);
}
예제 #11
0
ER
twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
{
    FLGCB	*p_flgcb;
    WINFO_FLG winfo_flg;
    TMEVTB	tmevtb;
    ER		ercd;

    LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout);
    CHECK_DISPATCH();
    CHECK_FLGID(flgid);
    CHECK_PAR(waiptn != 0U);
    CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
    CHECK_MACV_WRITE(p_flgptn, FLGPTN);
    CHECK_TMOUT(tmout);
    p_flgcb = get_flgcb(flgid);

    t_lock_cpu();
    if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
        ercd = E_NOEXS;
    }
    else if (VIOLATE_ACPTN(p_flgcb->p_flginib->acvct.acptn2)) {
        ercd = E_OACV;
    }
    else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
             && !queue_empty(&(p_flgcb->wait_queue))) {
        ercd = E_ILUSE;
    }
    else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
        ercd = E_OK;
    }
    else if (tmout == TMO_POL) {
        ercd = E_TMOUT;
    }
    else if (p_runtsk->waifbd) {
        ercd = E_RLWAI;
    }
    else {
        winfo_flg.waiptn = waiptn;
        winfo_flg.wfmode = wfmode;
        p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
        wobj_make_wait_tmout((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg,
                             &tmevtb, tmout);
        dispatch();
        ercd = winfo_flg.winfo.wercd;
        if (ercd == E_OK) {
            *p_flgptn = winfo_flg.flgptn;
        }
    }
    t_unlock_cpu();

error_exit:
    LOG_TWAI_FLG_LEAVE(ercd, *p_flgptn);
    return(ercd);
}
예제 #12
0
ER
tsnd_pdq(ID pdqid, intptr_t data, PRI datapri, TMO tmout)
{
	PDQCB	*p_pdqcb;
	WINFO_PDQ winfo_pdq;
	TMEVTB	tmevtb;
	bool_t	dspreq;
	ER		ercd;

	LOG_TSND_PDQ_ENTER(pdqid, data, datapri, tmout);
	CHECK_DISPATCH();
	CHECK_PDQID(pdqid);
	CHECK_PAR(TMIN_DPRI <= datapri);
	CHECK_TMOUT(tmout);
	p_pdqcb = get_pdqcb(pdqid);

	t_lock_cpu();
	if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else if (VIOLATE_ACPTN(p_pdqcb->p_pdqinib->acvct.acptn1)) {
		ercd = E_OACV;
	}
	else if (!(datapri <= p_pdqcb->p_pdqinib->maxdpri)) {
		ercd = E_PAR;
	}
	else if (send_pridata(p_pdqcb, data, datapri, &dspreq)) {
		if (dspreq) {
			dispatch();
		}
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else if (p_runtsk->waifbd) {
		ercd = E_RLWAI;
	}
	else {
		winfo_pdq.data = data;
		winfo_pdq.datapri = datapri;
		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SPDQ);
		wobj_make_wait_tmout((WOBJCB *) p_pdqcb, (WINFO_WOBJ *) &winfo_pdq,
														&tmevtb, tmout);
		dispatch();
		ercd = winfo_pdq.winfo.wercd;
	}
	t_unlock_cpu();

  error_exit:
	LOG_TSND_PDQ_LEAVE(ercd);
	return(ercd);
}
예제 #13
0
파일: mempfix.c 프로젝트: paduc77/gainos
/*
 * Get fixed size memory block 
 */
SYSCALL ER tk_get_mpf_impl( ID mpfid, VP *p_blf, TMO tmout )
{
	MPFCB	*mpfcb;
	FREEL	*free;
	ER	ercd = E_OK;

	CHECK_MPFID(mpfid);
	CHECK_TMOUT(tmout);
	CHECK_DISPATCH();

	mpfcb = get_mpfcb(mpfid);

	knl_LockOBJ(&mpfcb->lock);
	if ( mpfcb->mpfid == 0 ) {
		ercd = E_NOEXS;
		goto error_exit;
	}

	/* If there is no space, ready for wait */
	if ( mpfcb->frbcnt <= 0 ) {
		goto wait_mpf;
	} else {
		/* Get memory block */
		if ( mpfcb->freelist != NULL ) {
			free = mpfcb->freelist;
			mpfcb->freelist = free->next;
			*p_blf = free;
		} else {
			*p_blf = mpfcb->unused;
			mpfcb->unused = (VB*)mpfcb->unused + mpfcb->blfsz;
		}
		mpfcb->frbcnt--;
	}

    error_exit:
	knl_UnlockOBJ(&mpfcb->lock);

	return ercd;

wait_mpf:
	/* Ready for wait */
	BEGIN_CRITICAL_SECTION;
	knl_ctxtsk->wspec = ( (mpfcb->mpfatr & TA_TPRI) != 0 )?
				&knl_wspec_mpf_tpri: &knl_wspec_mpf_tfifo;
	knl_ctxtsk->wercd = &ercd;
	knl_ctxtsk->winfo.mpf.p_blf = p_blf;
	knl_gcb_make_wait((GCB*)mpfcb, tmout);

	knl_UnlockOBJ(&mpfcb->lock);
	END_CRITICAL_SECTION;

	return ercd;
}
예제 #14
0
ER
trcv_mbf(ID mbfid, void *msg, TMO tmout)
{
	MBFCB		*p_mbfcb;
	WINFO_RMBF	winfo_rmbf;
	TMEVTB		tmevtb;
	uint_t		msgsz;
	ER_UINT		ercd;

	LOG_TRCV_MBF_ENTER(mbfid, msg, tmout);
	CHECK_DISPATCH();
	CHECK_ID(VALID_MBFID(mbfid));
	CHECK_PAR(VALID_TMOUT(tmout));
	p_mbfcb = get_mbfcb(mbfid);

	lock_cpu_dsp();
	if (p_mbfcb->p_mbfinib->mbfatr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else if (VIOLATE_ACPTN(p_mbfcb->p_mbfinib->acvct.acptn2)) {
		ercd = E_OACV;
	}
	else if (!KERNEL_PROBE_BUF_WRITE(msg, p_mbfcb->p_mbfinib->maxmsz)) {
		ercd = E_MACV;
	}
	else if (p_runtsk->raster) {
		ercd = E_RASTER;
	}
	else if ((msgsz = receive_message(p_mbfcb, msg)) > 0U) {
		if (p_runtsk != p_schedtsk) {
			dispatch();
		}
		ercd = (ER_UINT) msgsz;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		make_wait_tmout(TS_WAITING_RMBF, &(winfo_rmbf.winfo), &tmevtb, tmout);
		queue_insert_prev(&(p_mbfcb->rwait_queue), &(p_runtsk->task_queue));
		winfo_rmbf.p_mbfcb = p_mbfcb;
		winfo_rmbf.msg = msg;
		LOG_TSKSTAT(p_runtsk);
		dispatch();
		ercd = winfo_rmbf.winfo.wercd;
	}
	unlock_cpu_dsp();

  error_exit:
	LOG_TRCV_MBF_LEAVE(ercd, msg);
	return(ercd);
}
예제 #15
0
파일: mempool.c 프로젝트: yuki74w/TRON
SYSCALL ER _tk_get_mpl_u( ID mplid, INT blksz, void **p_blk, TMO_U tmout )
{
	MPLCB	*mplcb;
	void	*blk = NULL;
	ER	ercd = E_OK;

	CHECK_MPLID(mplid);
	CHECK_PAR(blksz > 0 && blksz <= MAX_ALLOCATE);
	CHECK_TMOUT(tmout);
	CHECK_DISPATCH();

	mplcb = get_mplcb(mplid);
	blksz = roundSize(blksz);

	BEGIN_CRITICAL_SECTION;
	if ( mplcb->mplid == 0 ) {
		ercd = E_NOEXS;
		goto error_exit;
	}

#if CHK_PAR
	if ( blksz > mplcb->mplsz ) {
		ercd = E_PAR;
		goto error_exit;
	}
#endif

	/* Check wait disable */
	if ( is_diswai((GCB*)mplcb, ctxtsk, TTW_MPL) ) {
		ercd = E_DISWAI;
		goto error_exit;
	}

	if ( gcb_top_of_wait_queue((GCB*)mplcb, ctxtsk) == ctxtsk
	  && (blk = get_blk(mplcb, blksz)) != NULL ) {
		/* Get memory block */
		*p_blk = blk;
	} else {
		/* Ready for wait */
		ctxtsk->wspec = ( (mplcb->mplatr & TA_TPRI) != 0 )?
					&wspec_mpl_tpri: &wspec_mpl_tfifo;
		ctxtsk->wercd = &ercd;
		ctxtsk->winfo.mpl.blksz = blksz;
		ctxtsk->winfo.mpl.p_blk = p_blk;
		gcb_make_wait_with_diswai((GCB*)mplcb, tmout);
	}

    error_exit:
	END_CRITICAL_SECTION;

	return ercd;
}
예제 #16
0
ER
tsnd_mbf(ID mbfid, const void *msg, uint_t msgsz, TMO tmout)
{
	MBFCB		*p_mbfcb;
	WINFO_SMBF	winfo_smbf;
	TMEVTB		tmevtb;
	ER			ercd;

	LOG_TSND_MBF_ENTER(mbfid, msg, msgsz, tmout);
	CHECK_DISPATCH();
	CHECK_ID(VALID_MBFID(mbfid));
	CHECK_PAR(VALID_TMOUT(tmout));
	CHECK_MACV_BUF_READ(msg, msgsz);
	CHECK_PAR(0 < msgsz);
	p_mbfcb = get_mbfcb(mbfid);

	lock_cpu_dsp();
	if (p_mbfcb->p_mbfinib->mbfatr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else if (VIOLATE_ACPTN(p_mbfcb->p_mbfinib->acvct.acptn1)) {
		ercd = E_OACV;
	}
	else if (!(msgsz <= p_mbfcb->p_mbfinib->maxmsz)) {
		ercd = E_PAR;
	}
	else if (p_runtsk->raster) {
		ercd = E_RASTER;
	}
	else if (send_message(p_mbfcb, msg, msgsz)) {
		if (p_runtsk != p_schedtsk) {
			dispatch();
		}
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		winfo_smbf.msg = msg;
		winfo_smbf.msgsz = msgsz;
		wobj_make_wait_tmout((WOBJCB *) p_mbfcb, TS_WAITING_SMBF,
								(WINFO_WOBJ *) &winfo_smbf, &tmevtb, tmout);
		dispatch();
		ercd = winfo_smbf.winfo.wercd;
	}
	unlock_cpu_dsp();

  error_exit:
	LOG_TSND_MBF_LEAVE(ercd);
	return(ercd);
}
예제 #17
0
/*
 * Event flag wait
 */
SYSCALL ER tk_wai_flg_impl( ID flgid, UINT waiptn, UINT wfmode, UINT *p_flgptn, TMO tmout )
{
	FLGCB	*flgcb;
	ER	ercd = E_OK;

	CHECK_FLGID(flgid);
	CHECK_PAR(waiptn != 0);
	CHECK_PAR((wfmode & ~(TWF_ORW|TWF_CLR|TWF_BITCLR)) == 0);
	CHECK_TMOUT(tmout);
	CHECK_DISPATCH();

	flgcb = get_flgcb(flgid);

	BEGIN_CRITICAL_SECTION;
	if ( flgcb->flgid == 0 ) {
		ercd = E_NOEXS;
		goto error_exit;
	}
	if ( (flgcb->flgatr & TA_WMUL) == 0 && !isQueEmpty(&flgcb->wait_queue) ) {
		/* Disable multiple tasks wait */
		ercd = E_OBJ;
		goto error_exit;
	}

	/* Meet condition for release wait? */
	if ( knl_eventflag_cond(flgcb, waiptn, wfmode) ) {
		*p_flgptn = flgcb->flgptn;

		/* Clear event flag */
		if ( (wfmode & TWF_BITCLR) != 0 ) {
			flgcb->flgptn &= ~waiptn;
		}
		if ( (wfmode & TWF_CLR) != 0 ) {
			flgcb->flgptn = 0;
		}
	} else {
		/* Ready for wait */
		knl_ctxtsk->wspec = ( (flgcb->flgatr & TA_TPRI) != 0 )?
					&knl_wspec_flg_tpri: &knl_wspec_flg_tfifo;
		knl_ctxtsk->wercd = &ercd;
		knl_ctxtsk->winfo.flg.waiptn = waiptn;
		knl_ctxtsk->winfo.flg.wfmode = wfmode;
		knl_ctxtsk->winfo.flg.p_flgptn = p_flgptn;
		knl_gcb_make_wait((GCB*)flgcb, tmout);
	}

    error_exit:
	END_CRITICAL_SECTION;

	return ercd;
}
예제 #18
0
ER
tloc_mtx(ID mtxid, TMO tmout)
{
	MTXCB	*p_mtxcb;
	WINFO_MTX winfo_mtx;
	TMEVTB	tmevtb;
	ER		ercd;

	LOG_TLOC_MTX_ENTER(mtxid, tmout);
	CHECK_DISPATCH();
	CHECK_MTXID(mtxid);
	CHECK_TMOUT(tmout);
	p_mtxcb = get_mtxcb(mtxid);

	t_lock_cpu();
	if (MTX_CEILING(p_mtxcb)
				&& p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) {
		ercd = E_ILUSE;
	}
	else if (p_mtxcb->p_loctsk == NULL) {
		(void) mutex_acquire(p_runtsk, p_mtxcb);
		/*
		 *  優先度上限ミューテックスをロックした場合,p_runtskの優先度
		 *  が上がる可能性があるが,ディスパッチが必要になることはない.
		 */
		assert(!(p_runtsk != p_schedtsk && dspflg));
		ercd = E_OK;
	}
	else if (p_mtxcb->p_loctsk == p_runtsk) {
		ercd = E_OBJ;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		p_runtsk->tstat = (TS_WAITING | TS_WAIT_MTX);
		wobj_make_wait_tmout((WOBJCB *) p_mtxcb, (WINFO_WOBJ *) &winfo_mtx,
														&tmevtb, tmout);
		dispatch();
		ercd = winfo_mtx.winfo.wercd;
	}
	t_unlock_cpu();

  error_exit:
	LOG_TLOC_MTX_LEAVE(ercd);
	return(ercd);
}
예제 #19
0
ER
trcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri, TMO tmout)
{
	PDQCB	*p_pdqcb;
	WINFO_RPDQ winfo_rpdq;
	TMEVTB	tmevtb;
	ER		ercd;

	LOG_TRCV_PDQ_ENTER(pdqid, p_data, p_datapri, tmout);
	CHECK_DISPATCH();
	CHECK_ID(VALID_PDQID(pdqid));
	CHECK_PAR(VALID_TMOUT(tmout));
	p_pdqcb = get_pdqcb(pdqid);

	lock_cpu_dsp();
	if (p_runtsk->raster) {
		ercd = E_RASTER;
	}
	else if (receive_pridata(p_pdqcb, p_data, p_datapri)) {
		if (p_runtsk != p_schedtsk) {
			dispatch();
		}
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		p_runtsk->tstat = TS_WAITING_RPDQ;
		make_wait_tmout(&(winfo_rpdq.winfo), &tmevtb, tmout);
		queue_insert_prev(&(p_pdqcb->rwait_queue), &(p_runtsk->task_queue));
		winfo_rpdq.p_pdqcb = p_pdqcb;
		LOG_TSKSTAT(p_runtsk);
		dispatch();
		ercd = winfo_rpdq.winfo.wercd;
		if (ercd == E_OK) {
			*p_data = winfo_rpdq.data;
			*p_datapri = winfo_rpdq.datapri;
		}
	}
	unlock_cpu_dsp();

  error_exit:
	LOG_TRCV_PDQ_LEAVE(ercd, p_data, p_datapri);
	return(ercd);
}
예제 #20
0
파일: mempfix.c 프로젝트: paduc77/gainos
/*
 * Return fixed size memory block 
 */
SYSCALL ER tk_rel_mpf_impl( ID mpfid, VP blf )
{
	MPFCB	*mpfcb;
	TCB	*tcb;
	FREEL	*free;
	ER	ercd = E_OK;

	CHECK_MPFID(mpfid);
	CHECK_DISPATCH();

	mpfcb = get_mpfcb(mpfid);

	knl_LockOBJ(&mpfcb->lock);
	if ( mpfcb->mpfid == 0 ) {
		ercd = E_NOEXS;
		goto error_exit;
	}
#if CHK_PAR
	if ( blf < mpfcb->mempool || blf >= knl_mempool_end(mpfcb) || (((VB*)blf - (VB*)mpfcb->mempool) % mpfcb->blfsz) != 0 ) {
		ercd = E_PAR;
		goto error_exit;
	}
#endif

	DISABLE_INTERRUPT;
	if ( !isQueEmpty(&mpfcb->wait_queue) ) {
		/* Send memory block to waiting task,
		   and then release the task */
		tcb = (TCB*)mpfcb->wait_queue.next;
		*tcb->winfo.mpf.p_blf = blf;
		knl_wait_release_ok(tcb);
		ENABLE_INTERRUPT;
	} else {
		ENABLE_INTERRUPT;
		/* Free memory block */
		free = (FREEL*)blf;
		free->next = mpfcb->freelist;
		mpfcb->freelist = free;
		mpfcb->frbcnt++;
	}

error_exit:
	knl_UnlockOBJ(&mpfcb->lock);

	return ercd;
}
예제 #21
0
ER
trcv_mbf(ID mbfid, void *msg, TMO tmout)
{
	MBFCB	*p_mbfcb;
	WINFO_MBF winfo_mbf;
	TMEVTB	tmevtb;
	uint_t	msgsz;
	bool_t	dspreq;
	ER_UINT	ercd;

	LOG_TRCV_MBF_ENTER(mbfid, msg, tmout);
	CHECK_DISPATCH();
	CHECK_MBFID(mbfid);
	CHECK_TMOUT(tmout);
	p_mbfcb = get_mbfcb(mbfid);

	t_lock_cpu();
	if ((msgsz = receive_message(p_mbfcb, msg, &dspreq)) > 0U) {
		if (dspreq) {
			dispatch();
		}
		ercd = (ER_UINT) msgsz;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		p_runtsk->tstat = (TS_WAITING | TS_WAIT_RMBF);
		make_wait_tmout(&(winfo_mbf.winfo), &tmevtb, tmout);
		queue_insert_prev(&(p_mbfcb->rwait_queue), &(p_runtsk->task_queue));
		winfo_mbf.p_mbfcb = p_mbfcb;
		winfo_mbf.msg = msg;
		LOG_TSKSTAT(p_runtsk);
		dispatch();
		ercd = winfo_mbf.winfo.wercd;
		if (ercd == E_OK) {
			ercd = (ER_UINT)(winfo_mbf.msgsz);
		}
	}
	t_unlock_cpu();

  error_exit:
	LOG_TRCV_MBF_LEAVE(ercd, msg);
	return(ercd);
}
예제 #22
0
/*
 * Wait on semaphore
 */
SYSCALL ER tk_wai_sem_impl( ID semid, INT cnt, TMO tmout )
{
	SEMCB	*semcb;
	ER	ercd = E_OK;

	CHECK_SEMID(semid);
	CHECK_PAR(cnt > 0);
	CHECK_TMOUT(tmout);
	CHECK_DISPATCH();

	semcb = get_semcb(semid);

	BEGIN_CRITICAL_SECTION;
	if ( semcb->semid == 0 ) {
		ercd = E_NOEXS;
		goto error_exit;
	}
#if CHK_PAR
	if ( cnt > semcb->maxsem ) {
		ercd = E_PAR;
		goto error_exit;
	}
#endif

	if ( ((semcb->sematr & TA_CNT) != 0
	      || knl_gcb_top_of_wait_queue((GCB*)semcb, knl_ctxtsk) == knl_ctxtsk)
	  && semcb->semcnt >= cnt ) {
		/* Get semaphore count */
		semcb->semcnt -= cnt;

	} else {
		/* Ready for wait */
		knl_ctxtsk->wspec = ( (semcb->sematr & TA_TPRI) != 0 )?
					&knl_wspec_sem_tpri: &knl_wspec_sem_tfifo;
		knl_ctxtsk->wercd = &ercd;
		knl_ctxtsk->winfo.sem.cnt = cnt;
		knl_gcb_make_wait((GCB*)semcb, tmout);
	}

    error_exit:
	END_CRITICAL_SECTION;

	return ercd;
}
예제 #23
0
ER
twai_sem(ID semid, TMO tmout)
{
    SEMCB	*p_semcb;
    WINFO_SEM winfo_sem;
    TMEVTB	tmevtb;
    ER		ercd;

    LOG_TWAI_SEM_ENTER(semid, tmout);
    CHECK_DISPATCH();
    CHECK_SEMID(semid);
    CHECK_TMOUT(tmout);
    p_semcb = get_semcb(semid);

    t_lock_cpu();
    if (p_semcb->p_seminib->sematr == TA_NOEXS) {
        ercd = E_NOEXS;
    }
    else if (VIOLATE_ACPTN(p_semcb->p_seminib->acvct.acptn2)) {
        ercd = E_OACV;
    }
    else if (p_semcb->semcnt >= 1) {
        p_semcb->semcnt -= 1;
        ercd = E_OK;
    }
    else if (tmout == TMO_POL) {
        ercd = E_TMOUT;
    }
    else if (p_runtsk->waifbd) {
        ercd = E_RLWAI;
    }
    else {
        p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
        wobj_make_wait_tmout((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem,
                             &tmevtb, tmout);
        dispatch();
        ercd = winfo_sem.winfo.wercd;
    }
    t_unlock_cpu();

error_exit:
    LOG_TWAI_SEM_LEAVE(ercd);
    return(ercd);
}
예제 #24
0
ER
tget_mpf(ID mpfid, void **p_blk, TMO tmout)
{
	MPFCB	*p_mpfcb;
	WINFO_MPF winfo_mpf;
	TMEVTB	tmevtb;
	ER		ercd;

	LOG_TGET_MPF_ENTER(mpfid, p_blk, tmout);
	CHECK_DISPATCH();
	CHECK_ID(VALID_MPFID(mpfid));
	CHECK_PAR(VALID_TMOUT(tmout));
	p_mpfcb = get_mpfcb(mpfid);

	lock_cpu_dsp();
	if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else if (p_runtsk->raster) {
		ercd = E_RASTER;
	}
	else if (p_mpfcb->fblkcnt > 0) {
		get_mpf_block(p_mpfcb, p_blk);
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		p_runtsk->tstat = TS_WAITING_MPF;
		wobj_make_wait_tmout((WOBJCB *) p_mpfcb, (WINFO_WOBJ *) &winfo_mpf,
														&tmevtb, tmout);
		dispatch();
		ercd = winfo_mpf.winfo.wercd;
		if (ercd == E_OK) {
			*p_blk = winfo_mpf.blk;
		}
	}
	unlock_cpu_dsp();

  error_exit:
	LOG_TGET_MPF_LEAVE(ercd, p_blk);
	return(ercd);
}
예제 #25
0
ER
tsnd_pdq(ID pdqid, intptr_t data, PRI datapri, TMO tmout)
{
	PDQCB	*p_pdqcb;
	WINFO_SPDQ winfo_spdq;
	TMEVTB	tmevtb;
	ER		ercd;

	LOG_TSND_PDQ_ENTER(pdqid, data, datapri, tmout);
	CHECK_DISPATCH();
	CHECK_ID(VALID_PDQID(pdqid));
	CHECK_PAR(VALID_TMOUT(tmout));
	p_pdqcb = get_pdqcb(pdqid);
	CHECK_PAR(TMIN_DPRI <= datapri && datapri <= p_pdqcb->p_pdqinib->maxdpri);

	lock_cpu_dsp();
	if (p_runtsk->raster) {
		ercd = E_RASTER;
	}
	else if (send_pridata(p_pdqcb, data, datapri)) {
		if (p_runtsk != p_schedtsk) {
			dispatch();
		}
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		winfo_spdq.data = data;
		winfo_spdq.datapri = datapri;
		p_runtsk->tstat = TS_WAITING_SPDQ;
		wobj_make_wait_tmout((WOBJCB *) p_pdqcb, (WINFO_WOBJ *) &winfo_spdq,
														&tmevtb, tmout);
		dispatch();
		ercd = winfo_spdq.winfo.wercd;
	}
	unlock_cpu_dsp();

  error_exit:
	LOG_TSND_PDQ_LEAVE(ercd);
	return(ercd);
}
예제 #26
0
ER
twai_sem(ID semid, TMO tmout)
{
	SEMCB		*p_semcb;
	WINFO_SEM	winfo_sem;
	TMEVTB		tmevtb;
	ER			ercd;

	LOG_TWAI_SEM_ENTER(semid, tmout);
	CHECK_DISPATCH();
	CHECK_ID(VALID_SEMID(semid));
	CHECK_PAR(VALID_TMOUT(tmout));
	p_semcb = get_semcb(semid);

	lock_cpu_dsp();
	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else if (VIOLATE_ACPTN(p_semcb->p_seminib->acvct.acptn2)) {
		ercd = E_OACV;
	}
	else if (p_runtsk->raster) {
		ercd = E_RASTER;
	}
	else if (p_semcb->semcnt >= 1) {
		p_semcb->semcnt -= 1;
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		wobj_make_wait_tmout((WOBJCB *) p_semcb, TS_WAITING_SEM,
								(WINFO_WOBJ *) &winfo_sem, &tmevtb, tmout);
		dispatch();
		ercd = winfo_sem.winfo.wercd;
	}
	unlock_cpu_dsp();

  error_exit:
	LOG_TWAI_SEM_LEAVE(ercd);
	return(ercd);
}
예제 #27
0
ER
trcv_dtq(ID dtqid, intptr_t *p_data, TMO tmout)
{
	DTQCB	*p_dtqcb;
	WINFO_DTQ winfo_dtq;
	TMEVTB	tmevtb;
	bool_t	reqdsp;
	ER		ercd;

	LOG_TRCV_DTQ_ENTER(dtqid, p_data, tmout);
	CHECK_DISPATCH();
	CHECK_DTQID(dtqid);
	CHECK_TMOUT(tmout);
	p_dtqcb = get_dtqcb(dtqid);

	t_lock_cpu();
	if (receive_data(p_dtqcb, p_data, &reqdsp)) {
		if (reqdsp) {
			dispatch();
		}
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		p_runtsk->tstat = (TS_WAITING | TS_WAIT_RDTQ);
		make_wait_tmout(&(winfo_dtq.winfo), &tmevtb, tmout);
		queue_insert_prev(&(p_dtqcb->rwait_queue), &(p_runtsk->task_queue));
		winfo_dtq.p_dtqcb = p_dtqcb;
		LOG_TSKSTAT(p_runtsk);
		dispatch();
		ercd = winfo_dtq.winfo.wercd;
		if (ercd == E_OK) {
			*p_data = winfo_dtq.data;
		}
	}
	t_unlock_cpu();

  error_exit:
	LOG_TRCV_DTQ_LEAVE(ercd, *p_data);
	return(ercd);
}
예제 #28
0
파일: eventflag.c 프로젝트: Han40/spamOSEK
SYSCALL ER
twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
{
    FLGCB	*flgcb;
    WINFO_FLG winfo;
    TMEVTB	tmevtb;
    ER	ercd;

    LOG_TWAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn, tmout);
    CHECK_DISPATCH();
    CHECK_FLGID(flgid);
    CHECK_PAR(waiptn != 0);
    CHECK_PAR((wfmode & ~TWF_ORW) == 0);
    CHECK_TMOUT(tmout);
    flgcb = get_flgcb(flgid);

    t_lock_cpu();
    if (!(queue_empty(&(flgcb->wait_queue)))) {
        ercd = E_ILUSE;
    }
    else if (eventflag_cond(flgcb, waiptn, wfmode, p_flgptn)) {
        ercd = E_OK;
    }
    else if (tmout == TMO_POL) {
        ercd = E_TMOUT;
    }
    else {
        winfo.waiptn = waiptn;
        winfo.wfmode = wfmode;
        wobj_make_wait_tmout((WOBJCB *) flgcb, (WINFO_WOBJ *) &winfo,
                             &tmevtb, tmout);
        dispatch();
        ercd = winfo.winfo.wercd;
        if (ercd == E_OK) {
            *p_flgptn = winfo.flgptn;
        }
    }
    t_unlock_cpu();

exit:
    LOG_TWAI_FLG_LEAVE(ercd, *p_flgptn);
    return(ercd);
}
예제 #29
0
ER
rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri)
{
    PDQCB	*p_pdqcb;
    WINFO_PDQ winfo_pdq;
    bool_t	reqdsp;
    ER		ercd;

    LOG_RCV_PDQ_ENTER(pdqid, p_data, p_datapri);
    CHECK_DISPATCH();
    CHECK_PDQID(pdqid);
    p_pdqcb = get_pdqcb(pdqid);

    t_lock_cpu();
    if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) {
        ercd = E_NOEXS;
    }
    else if (receive_pridata(p_pdqcb, p_data, p_datapri, &reqdsp)) {
        if (reqdsp) {
            dispatch();
        }
        ercd = E_OK;
    }
    else {
        p_runtsk->tstat = (TS_WAITING | TS_WAIT_RPDQ);
        make_wait(&(winfo_pdq.winfo));
        queue_insert_prev(&(p_pdqcb->rwait_queue), &(p_runtsk->task_queue));
        winfo_pdq.p_pdqcb = p_pdqcb;
        LOG_TSKSTAT(p_runtsk);
        dispatch();
        ercd = winfo_pdq.winfo.wercd;
        if (ercd == E_OK) {
            *p_data = winfo_pdq.data;
            *p_datapri = winfo_pdq.datapri;
        }
    }
    t_unlock_cpu();

error_exit:
    LOG_RCV_PDQ_LEAVE(ercd, *p_data, *p_datapri);
    return(ercd);
}
예제 #30
0
ER
wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn)
{
	FLGCB	*p_flgcb;
	WINFO_FLG winfo_flg;
	ER		ercd;

	LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn);
	CHECK_DISPATCH();
	CHECK_FLGID(flgid);
	CHECK_PAR(waiptn != 0U);
	CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW);
	p_flgcb = get_flgcb(flgid);

	t_lock_cpu();
	if (p_flgcb->p_flginib->flgatr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
					&& !queue_empty(&(p_flgcb->wait_queue))) {
		ercd = E_ILUSE;
	}
	else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
		ercd = E_OK;
	}
	else {
		winfo_flg.waiptn = waiptn;
		winfo_flg.wfmode = wfmode;
		p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
		wobj_make_wait((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg);
		dispatch();
		ercd = winfo_flg.winfo.wercd;
		if (ercd == E_OK) {
			*p_flgptn = winfo_flg.flgptn;
		}
	}
	t_unlock_cpu();

  error_exit:
	LOG_WAI_FLG_LEAVE(ercd, *p_flgptn);
	return(ercd);
}