Beispiel #1
0
StatusType SleepTask ( TickType Timeout )
{
    StatusType ercd = E_OK;
    OS_CHECK_EXT(!in_indp(),E_OS_CALLEVEL);
	OS_CHECK_EXT(isQueEmpty(&knl_ctxtsk->resque),E_OS_RESOURCE);

	BEGIN_CRITICAL_SECTION;

    if ( knl_ctxtsk->wupcnt > 0 ) {
        knl_ctxtsk->wupcnt--;
    } else {
        ercd = E_OS_TMOUT;
        if ( Timeout != 0 ) {
            knl_ctxtsk->wspec = &knl_wspec_slp;
            knl_ctxtsk->wid = 0;
            knl_ctxtsk->wercd = &ercd;
            knl_make_wait(Timeout);
            QueInit(&knl_ctxtsk->tskque);
        }
    }

    END_CRITICAL_SECTION;
Error_Exit:
	return ercd;
}
Beispiel #2
0
/*
 * Change the active task state to wait state and connect to the timer wait 
 * queue and the object wait queue. Also set 'wid' in 'knl_ctxtsk'.
 */
EXPORT void knl_gcb_make_wait( GCB *gcb, TMO tmout )
{
	*knl_ctxtsk->wercd = E_TMOUT;
	if ( tmout != TMO_POL ) {
		knl_ctxtsk->wid = gcb->objid;
		knl_make_wait(tmout, gcb->objatr);
		if ( (gcb->objatr & TA_TPRI) != 0 ) {
			knl_queue_insert_tpri(knl_ctxtsk, &gcb->wait_queue);
		} else {
			QueInsert(&knl_ctxtsk->tskque, &gcb->wait_queue);
		}
	}
}
Beispiel #3
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;
}
Beispiel #4
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;
}
Beispiel #5
0
/*
 * Lock mutex
 */
SYSCALL ER tk_loc_mtx_impl( ID mtxid, TMO 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 == knl_ctxtsk ) {
		ercd = E_ILUSE;  /* Multiplexed lock */
		goto error_exit;
	}

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

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

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

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

		/* Ready for wait */
		knl_ctxtsk->wspec = ( mtxatr == TA_TFIFO   )? &knl_wspec_mtx_tfifo:
				( mtxatr == TA_INHERIT )? &knl_wspec_mtx_inherit:
							  &knl_wspec_mtx_tpri;
		knl_ctxtsk->wercd = &ercd;
		knl_ctxtsk->wid = mtxcb->mtxid;
		knl_make_wait(tmout, mtxcb->mtxatr);
		if ( mtxatr == TA_TFIFO ) {
			QueInsert(&knl_ctxtsk->tskque, &mtxcb->wait_queue);
		} else {
			knl_queue_insert_tpri(knl_ctxtsk, &mtxcb->wait_queue);
		}
	}

    error_exit:
	END_CRITICAL_SECTION;

	return ercd;
}