예제 #1
0
파일: semaphore.c 프로젝트: Ashatta/tools
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);
}
예제 #2
0
파일: eventflag.c 프로젝트: inouema/toppers
ER
twai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn, TMO tmout)
{
	FLGCB	*p_flgcb;
	WINFO_FLG *p_winfo_flg;
	ER		ercd;
	PCB		*my_p_pcb;
	TCB		*p_runtsk;

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

	t_lock_cpu();
	my_p_pcb = get_my_p_pcb();
	T_CHECK_DISPATCH(my_p_pcb);

  retry:
	t_acquire_obj_lock(&GET_OBJLOCK(p_flgcb));
	if ((p_flgcb->p_flginib->flgatr & TA_WMUL) == 0U
					&& !queue_empty(&(p_flgcb->wait_queue))) {
		release_obj_lock(&GET_OBJLOCK(p_flgcb));
		ercd = E_ILUSE;
	}
	else if (check_flg_cond(p_flgcb, waiptn, wfmode, p_flgptn)) {
		release_obj_lock(&GET_OBJLOCK(p_flgcb));
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		release_obj_lock(&GET_OBJLOCK(p_flgcb));
		ercd = E_TMOUT;
	}
	else {
		if ((my_p_pcb = t_acquire_nested_tsk_lock_self(&GET_OBJLOCK(p_flgcb))) == NULL){
			goto retry;
		}
		p_runtsk = my_p_pcb->p_runtsk;
		p_winfo_flg = (WINFO_FLG *)(&(p_runtsk->winfo_obj));
		p_winfo_flg->waiptn = waiptn;
		p_winfo_flg->wfmode = wfmode;
		p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG);
		wobj_make_wait_tmout((WOBJCB *) p_flgcb, tmout, p_runtsk);
		release_nested_tsk_lock(my_p_pcb);
		release_obj_lock(&GET_OBJLOCK(p_flgcb));
		dispatch();
		ercd = p_runtsk->wercd;
		if (ercd == E_OK) {
			*p_flgptn = p_winfo_flg->flgptn;
		}
	}
	t_unlock_cpu();

  error_exit:
	LOG_TWAI_FLG_LEAVE(ercd, *p_flgptn);
	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 if (p_runtsk->waifbd) {
		ercd = E_RLWAI;
	}
	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
파일: task_sync.c 프로젝트: qreal/nxt-tools
SYSCALL 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 (runtsk->wupcnt) {
		runtsk->wupcnt = FALSE;
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		runtsk->tstat = (TS_WAITING | TS_WAIT_SLEEP);
		make_wait_tmout(&winfo, &tmevtb, tmout);
		LOG_TSKSTAT(runtsk);
		dispatch();
		ercd = winfo.wercd;
	}
	t_unlock_cpu();

    exit:
	LOG_TSLP_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
SYSCALL ER _tk_slp_tsk_u( TMO_U tmout )
{
	ER	ercd = E_OK;

	CHECK_TMOUT(tmout);
	CHECK_DISPATCH();

	BEGIN_CRITICAL_SECTION;
	/* Check wait disable */
	if ( (ctxtsk->waitmask & TTW_SLP) != 0 ) {
		ercd = E_DISWAI;
		goto error_exit;
	}

	if ( ctxtsk->wupcnt > 0 ) {
		ctxtsk->wupcnt--;
	} else {
		ercd = E_TMOUT;
		if ( tmout != TMO_POL ) {
			ctxtsk->wspec = &wspec_slp;
			ctxtsk->wid = 0;
			ctxtsk->wercd = &ercd;
			make_wait(tmout, TA_NULL);
			QueInit(&ctxtsk->tskque);
		}
	}

    error_exit:
	END_CRITICAL_SECTION;

	return ercd;
}
예제 #7
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;
}
예제 #8
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);
}
예제 #9
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);
}
예제 #10
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);
}
예제 #11
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;
}
예제 #12
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;
}
예제 #13
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;
}
예제 #14
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);
}
예제 #15
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);
}
예제 #16
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);
}
예제 #17
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;
}
예제 #18
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);
}
예제 #19
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);
}
예제 #20
0
ER
tsnd_mbf(ID mbfid, const void *msg, uint_t msgsz, TMO tmout)
{
	MBFCB	*p_mbfcb;
	WINFO_MBF winfo_mbf;
	TMEVTB	tmevtb;
	bool_t	dspreq;
	ER		ercd;

	LOG_TSND_MBF_ENTER(mbfid, msg, msgsz, tmout);
	CHECK_DISPATCH();
	CHECK_MBFID(mbfid);
	CHECK_TMOUT(tmout);
	p_mbfcb = get_mbfcb(mbfid);
	CHECK_PAR(0 < msgsz && msgsz <= p_mbfcb->p_mbfinib->maxmsz);

	t_lock_cpu();
	if (send_message(p_mbfcb, msg, msgsz, &dspreq)) {
		if (dspreq) {
			dispatch();
		}
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		winfo_mbf.msg = (void *) msg;
		winfo_mbf.msgsz = msgsz;
		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SMBF);
		wobj_make_wait_tmout((WOBJCB *) p_mbfcb, (WINFO_WOBJ *) &winfo_mbf,
														&tmevtb, tmout);
		dispatch();
		ercd = winfo_mbf.winfo.wercd;
	}
	t_unlock_cpu();

  error_exit:
	LOG_TSND_MBF_LEAVE(ercd);
	return(ercd);
}
예제 #21
0
SYSCALL ER _tk_rcv_mbx_u( ID mbxid, T_MSG **ppk_msg, TMO_U tmout )
{
	MBXCB	*mbxcb;
	ER	ercd = E_OK;

	CHECK_MBXID(mbxid);
	CHECK_TMOUT(tmout);
	CHECK_DISPATCH();

	mbxcb = get_mbxcb(mbxid);

	BEGIN_CRITICAL_SECTION;
	if ( mbxcb->mbxid == 0 ) {
		ercd = E_NOEXS;
		goto error_exit;
	}

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

	if ( headmsg(mbxcb) != NULL ) {
		/* Get message from head of queue */
		*ppk_msg = headmsg(mbxcb);
		headmsg(mbxcb) = nextmsg(*ppk_msg);
	} else {
		/* Ready for receive wait */
		ctxtsk->wspec = ( (mbxcb->mbxatr & TA_TPRI) != 0 )?
					&wspec_mbx_tpri: &wspec_mbx_tfifo;
		ctxtsk->wercd = &ercd;
		ctxtsk->winfo.mbx.ppk_msg = ppk_msg;
		gcb_make_wait_with_diswai((GCB*)mbxcb, tmout);
	}

    error_exit:
	END_CRITICAL_SECTION;

	return ercd;
}
예제 #22
0
ER
trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout)
{
	MBXCB	*p_mbxcb;
	WINFO_MBX winfo_mbx;
	TMEVTB	tmevtb;
	ER		ercd;
    
	LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout);
	CHECK_DISPATCH();
	CHECK_MBXID(mbxid);
	CHECK_TMOUT(tmout);
	p_mbxcb = get_mbxcb(mbxid);
    
	t_lock_cpu();
	if (p_mbxcb->pk_head != NULL) {
		*ppk_msg = p_mbxcb->pk_head;
		p_mbxcb->pk_head = (*ppk_msg)->pk_next;
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX);
		wobj_make_wait_tmout((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx,
														&tmevtb, tmout);
		dispatch();
		ercd = winfo_mbx.winfo.wercd;
		if (ercd == E_OK) {
			*ppk_msg = winfo_mbx.pk_msg;
		}
	}
	t_unlock_cpu();

  error_exit:
	LOG_TRCV_MBX_LEAVE(ercd, *ppk_msg);
	return(ercd);
}
예제 #23
0
ER
tsnd_dtq(ID dtqid, intptr_t data, TMO tmout)
{
	DTQCB	*p_dtqcb;
	WINFO_DTQ winfo_dtq;
	TMEVTB	tmevtb;
	bool_t	reqdsp;
	ER		ercd;

	LOG_TSND_DTQ_ENTER(dtqid, data, tmout);
	CHECK_DISPATCH();
	CHECK_DTQID(dtqid);
	CHECK_TMOUT(tmout);
	p_dtqcb = get_dtqcb(dtqid);

	t_lock_cpu();
	if (send_data(p_dtqcb, data, &reqdsp)) {
		if (reqdsp) {
			dispatch();
		}
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		winfo_dtq.data = data;
		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SDTQ);
		wobj_make_wait_tmout((WOBJCB *) p_dtqcb, (WINFO_WOBJ *) &winfo_dtq,
														&tmevtb, tmout);
		dispatch();
		ercd = winfo_dtq.winfo.wercd;
	}
	t_unlock_cpu();

  error_exit:
	LOG_TSND_DTQ_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_MPFID(mpfid);
	CHECK_TMOUT(tmout);
	p_mpfcb = get_mpfcb(mpfid);

	t_lock_cpu();
	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 | TS_WAIT_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;
		}
	}
	t_unlock_cpu();

  error_exit:
	LOG_TGET_MPF_LEAVE(ercd, *p_blk);
	return(ercd);
}
예제 #25
0
SYSCALL INT _tk_wai_tev_u( INT waiptn, TMO_U tmout )
{
	WSPEC	wspec;
	ER	ercd;

	CHECK_TMOUT(tmout);
	CHECK_PAR((((UINT)waiptn & ~0x000000ffU) == 0)&&(((UINT)waiptn & 0x000000FFU) != 0));
	CHECK_DISPATCH();

	BEGIN_CRITICAL_SECTION;
	/* Check wait disable */
	if ( (ctxtsk->waitmask & toTTW(waiptn)) != 0 ) {
		ercd = E_DISWAI;
		goto error_exit;
	}

	if ( (ctxtsk->tskevt & waiptn) != 0 ) {
		ercd = ctxtsk->tskevt;
		ctxtsk->tskevt &= ~waiptn;
	} else {
		ercd = E_TMOUT;
		if ( tmout != TMO_POL ) {
			wspec.tskwait = toTTW(waiptn);
			wspec.chg_pri_hook = NULL;
			wspec.rel_wai_hook = NULL;
			ctxtsk->wspec = &wspec;
			ctxtsk->wid = 0;
			ctxtsk->wercd = &ercd;
			make_wait(tmout, TA_NULL);
			QueInit(&ctxtsk->tskque);
		}
	}

    error_exit:
	END_CRITICAL_SECTION;

	return ercd;
}
예제 #26
0
파일: mailbox.c 프로젝트: Ashatta/tools
SYSCALL ER
trcv_mbx(ID mbxid, T_MSG **ppk_msg, TMO tmout)
{
	MBXCB	*mbxcb;
	WINFO_MBX winfo;
	TMEVTB	tmevtb;
	ER	ercd;
    
	LOG_TRCV_MBX_ENTER(mbxid, ppk_msg, tmout);
	CHECK_DISPATCH();
	CHECK_MBXID(mbxid);
	CHECK_TMOUT(tmout);
	mbxcb = get_mbxcb(mbxid);
    
	t_lock_cpu();
	if (mbxcb->head != NULL) {
		*ppk_msg = mbxcb->head;
		mbxcb->head = (*ppk_msg)->next;
		ercd = E_OK;
	}
	else if (tmout == TMO_POL) {
		ercd = E_TMOUT;
	}
	else {
		wobj_make_wait_tmout((WOBJCB *) mbxcb, (WINFO_WOBJ *) &winfo,
						&tmevtb, tmout);
		dispatch();
		ercd = winfo.winfo.wercd;
		if (ercd == E_OK) {
			*ppk_msg = winfo.pk_msg;
		}
	}
	t_unlock_cpu();

    exit:
	LOG_TRCV_MBX_LEAVE(ercd, *ppk_msg);
	return(ercd);
}
예제 #27
0
/*
 * Call rendezvous
 */
SYSCALL INT tk_cal_por_impl( ID porid, UINT calptn, VP msg, INT cmsgsz, TMO 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;
		}

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

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

		goto error_exit;
	}

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

    error_exit:
	END_CRITICAL_SECTION;

	return ( ercd < E_OK )? ercd: rmsgsz;
}
예제 #28
0
SYSCALL ER _tk_snd_mbf_u( ID mbfid, CONST void *msg, INT msgsz, TMO_U tmout )
{
	MBFCB	*mbfcb;
	TCB	*tcb;
	ER	ercd = E_OK;

	CHECK_MBFID(mbfid);
	CHECK_PAR(msgsz > 0);
	CHECK_TMOUT(tmout);
	CHECK_DISPATCH_POL(tmout);

	mbfcb = get_mbfcb(mbfid);

	BEGIN_CRITICAL_SECTION;
	if ( mbfcb->mbfid == 0 ) {
		ercd = E_NOEXS;
		goto error_exit;
	}
#if CHK_PAR
	if ( msgsz > mbfcb->maxmsz ) {
		ercd = E_PAR;
		goto error_exit;
	}
#endif

	/* Check send wait disable */
	if ( !in_indp() && is_diswai((GCB*)mbfcb, ctxtsk, TTW_SMBF) ) {
		ercd = E_DISWAI;
		goto error_exit;
	}

	if ( !isQueEmpty(&mbfcb->recv_queue) ) {
		/* Send directly to the receive wait task */
		tcb = (TCB*)mbfcb->recv_queue.next;
		memcpy(tcb->winfo.rmbf.msg, msg, (UINT)msgsz);
		*tcb->winfo.rmbf.p_msgsz = msgsz;
		wait_release_ok(tcb);

	} else if ( (in_indp() || gcb_top_of_wait_queue((GCB*)mbfcb, ctxtsk) == ctxtsk)
		  &&(mbf_free(mbfcb, msgsz)) ) {
		/* Store the message to message buffer */
		msg_to_mbf(mbfcb, msg, msgsz);

	} else {
		ercd = E_TMOUT;
		if ( tmout != TMO_POL ) {
			/* Ready for send wait */
			ctxtsk->wspec = ( (mbfcb->mbfatr & TA_TPRI) != 0 )?
					&wspec_smbf_tpri: &wspec_smbf_tfifo;
			ctxtsk->wercd = &ercd;
			ctxtsk->winfo.smbf.msg = msg;
			ctxtsk->winfo.smbf.msgsz = msgsz;
			gcb_make_wait_with_diswai((GCB*)mbfcb, tmout);
		}
	}

    error_exit:
	END_CRITICAL_SECTION;

	return ercd;
}
예제 #29
0
/*
 * Accept rendezvous
 */
SYSCALL INT tk_acp_por_impl( ID porid, UINT acpptn, RNO *p_rdvno, VP msg, TMO 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;
		}

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

		knl_wait_cancel(tcb);

		/* Make the other task at rendezvous end wait state */
		tcb->wspec = &knl_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;
		knl_timer_insert(&tcb->wtmeb, TMO_FEVR,
					(CBACK)knl_wait_release_tmout, tcb);
		QueInit(&tcb->tskque);

		goto error_exit;
	}

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

    error_exit:
	END_CRITICAL_SECTION;

	return ( ercd < E_OK )? ercd: cmsgsz;
}
예제 #30
0
파일: mutex.c 프로젝트: yuki74w/TRON
SYSCALL ER _tk_loc_mtx_u( ID mtxid, TMO_U tmout )
{
	MTXCB	*mtxcb;
	TCB	*mtxtsk;
	ATR	mtxatr;
	ER	ercd = E_OK;

	CHECK_MTXID(mtxid);
	CHECK_TMOUT(tmout);
	CHECK_DISPATCH();

	mtxcb = get_mtxcb(mtxid);

	BEGIN_CRITICAL_SECTION;
	if ( mtxcb->mtxid == 0 ) {
		ercd = E_NOEXS;
		goto error_exit;
	}
	if ( mtxcb->mtxtsk == ctxtsk ) {
		ercd = E_ILUSE;  /* Multiplexed lock */
		goto error_exit;
	}

	mtxatr = mtxcb->mtxatr & TA_CEILING;
	if ( mtxatr == TA_CEILING ) {
		if ( ctxtsk->bpriority < mtxcb->ceilpri ) {
			/* Violation of highest priority limit */
			ercd = E_ILUSE;
			goto error_exit;
		}
	}

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

	mtxtsk = mtxcb->mtxtsk;
	if ( mtxtsk == NULL ) {
		/* Get lock */
		mtxcb->mtxtsk = ctxtsk;
		mtxcb->mtxlist = ctxtsk->mtxlist;
		ctxtsk->mtxlist = mtxcb;

		if ( mtxatr == TA_CEILING ) {
			if ( ctxtsk->priority > mtxcb->ceilpri ) {
				/* Raise its own task to the highest
				   priority limit */
				change_task_priority(ctxtsk, mtxcb->ceilpri);
			}
		}
	} else {
		ercd = E_TMOUT;
		if ( tmout == TMO_POL ) {
			goto error_exit;
		}

		if ( mtxatr == TA_INHERIT ) {
			if ( mtxtsk->priority > ctxtsk->priority ) {
				/* Raise the priority of task during
				   locking to the same priority as its
				   own task */
				change_task_priority(mtxtsk, ctxtsk->priority);
			}
		}

		/* Ready for wait */
		ctxtsk->wspec = ( mtxatr == TA_TFIFO   )? &wspec_mtx_tfifo:
				( mtxatr == TA_INHERIT )? &wspec_mtx_inherit:
							  &wspec_mtx_tpri;
		ctxtsk->wercd = &ercd;
		ctxtsk->wid = mtxcb->mtxid;
		make_wait(tmout, mtxcb->mtxatr);
		if ( mtxatr == TA_TFIFO ) {
			QueInsert(&ctxtsk->tskque, &mtxcb->wait_queue);
		} else {
			queue_insert_tpri(ctxtsk, &mtxcb->wait_queue);
		}
	}

    error_exit:
	END_CRITICAL_SECTION;

	return ercd;
}