Example #1
0
JSP_L1_CODE
SYSCALL ER
sig_sem(ID semid)
{
	SEMCB	*semcb;
	TCB	*tcb;
	ER	ercd;
    
	LOG_SIG_SEM_ENTER(semid);
	CHECK_TSKCTX_UNL();
	CHECK_SEMID(semid);
	semcb = get_semcb(semid);

	t_lock_cpu();
	if (!(queue_empty(&(semcb->wait_queue)))) {
		tcb = (TCB *) queue_delete_next(&(semcb->wait_queue));
		if (wait_complete(tcb)) {
			dispatch();
		}
		ercd = E_OK;
	}
	else if (semcb->semcnt < semcb->seminib->maxsem) {
		semcb->semcnt += 1;
		ercd = E_OK;
	}
	else {
		ercd = E_QOVR;
	}
	t_unlock_cpu();

    exit:
	LOG_SIG_SEM_LEAVE(ercd);
	return(ercd);
}
Example #2
0
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);
}
Example #3
0
SYSCALL ER
pol_sem(ID semid)
{
	SEMCB	*semcb;
	ER	ercd;

	LOG_POL_SEM_ENTER(semid);
	CHECK_TSKCTX_UNL();
	CHECK_SEMID(semid);
	semcb = get_semcb(semid);

	t_lock_cpu();
	if (semcb->semcnt >= 1) {
		semcb->semcnt -= 1;
		ercd = E_OK;
	}
	else {
		ercd = E_TMOUT;
	}
	t_unlock_cpu();

    exit:
	LOG_POL_SEM_LEAVE(ercd);
	return(ercd);
}
Example #4
0
ER
ref_sem(ID semid, T_RSEM *pk_rsem)
{
	SEMCB	*p_semcb;
	ER		ercd;
    
	LOG_REF_SEM_ENTER(semid, pk_rsem);
	CHECK_TSKCTX_UNL();
	CHECK_SEMID(semid);
	p_semcb = get_semcb(semid);

	t_lock_cpu();
	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else {
		pk_rsem->wtskid = wait_tskid(&(p_semcb->wait_queue));
		pk_rsem->semcnt = p_semcb->semcnt;
		ercd = E_OK;
	}
	t_unlock_cpu();

  error_exit:
	LOG_REF_SEM_LEAVE(ercd, pk_rsem);
	return(ercd);
}
Example #5
0
SYSCALL ER
isig_sem(ID semid)
{
	SEMCB	*semcb;
	TCB	*tcb;
	ER	ercd;
    
	LOG_ISIG_SEM_ENTER(semid);
	CHECK_INTCTX_UNL();
	CHECK_SEMID(semid);
	semcb = get_semcb(semid);

	i_lock_cpu();
	if (!queue_empty(&(semcb->wait_queue))) {
		tcb = (TCB *) queue_delete_next(&(semcb->wait_queue));
		if (wait_complete(tcb)) {
			reqflg = TRUE;
		}
		ercd = E_OK;
	}
	else if (semcb->semcnt < semcb->seminib->maxsem) {
		semcb->semcnt += 1;
		ercd = E_OK;
	}
	else {
		ercd = E_QOVR;
	}
	i_unlock_cpu();

    exit:
	LOG_ISIG_SEM_LEAVE(ercd);
	return(ercd);
}
Example #6
0
ER
ini_sem(ID semid)
{
	SEMCB	*p_semcb;
	bool_t	dspreq;
	ER		ercd;
    
	LOG_INI_SEM_ENTER(semid);
	CHECK_TSKCTX_UNL();
	CHECK_SEMID(semid);
	p_semcb = get_semcb(semid);

	t_lock_cpu();
	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else {
		dspreq = init_wait_queue(&(p_semcb->wait_queue));
		p_semcb->semcnt = p_semcb->p_seminib->isemcnt;
		if (dspreq) {
			dispatch();
		}
		ercd = E_OK;
	}
	t_unlock_cpu();

  error_exit:
	LOG_INI_SEM_LEAVE(ercd);
	return(ercd);
}
Example #7
0
ER
pol_sem(ID semid)
{
	SEMCB	*p_semcb;
	ER		ercd;

	LOG_POL_SEM_ENTER(semid);
	CHECK_TSKCTX_UNL();
	CHECK_SEMID(semid);
	p_semcb = get_semcb(semid);

	t_lock_cpu();
	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else if (p_semcb->semcnt >= 1) {
		p_semcb->semcnt -= 1;
		ercd = E_OK;
	}
	else {
		ercd = E_TMOUT;
	}
	t_unlock_cpu();

  error_exit:
	LOG_POL_SEM_LEAVE(ercd);
	return(ercd);
}
Example #8
0
ER
wai_sem(ID semid)
{
	SEMCB	*p_semcb;
	WINFO_SEM winfo_sem;
	ER		ercd;

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

	t_lock_cpu();
	if (p_semcb->p_seminib->sematr == TA_NOEXS) {
		ercd = E_NOEXS;
	}
	else if (p_semcb->semcnt >= 1) {
		p_semcb->semcnt -= 1;
		ercd = E_OK;
	}
	else {
		p_runtsk->tstat = (TS_WAITING | TS_WAIT_SEM);
		wobj_make_wait((WOBJCB *) p_semcb, (WINFO_WOBJ *) &winfo_sem);
		dispatch();
		ercd = winfo_sem.winfo.wercd;
	}
	t_unlock_cpu();

  error_exit:
	LOG_WAI_SEM_LEAVE(ercd);
	return(ercd);
}
Example #9
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);
}
Example #10
0
/*
 * Signal semaphore
 */
SYSCALL ER tk_sig_sem_impl( ID semid, INT cnt )
{
	SEMCB	*semcb;
	TCB	*tcb;
	QUEUE	*queue;
	ER	ercd = E_OK;
    
	CHECK_SEMID(semid);
	CHECK_PAR(cnt > 0);

	semcb = get_semcb(semid);

	BEGIN_CRITICAL_SECTION;
	if ( semcb->semid == 0 ) {
		ercd = E_NOEXS;
		goto error_exit;
	}
	if ( cnt > (semcb->maxsem - semcb->semcnt) ) {
		ercd = E_QOVR;
		goto error_exit;
	}

	/* Return semaphore counts */
	semcb->semcnt += cnt;

	/* Search task that frees wait */
	queue = semcb->wait_queue.next;
	while ( queue != &semcb->wait_queue ) {
		tcb = (TCB*)queue;
		queue = queue->next;

		/* Meet condition for Releasing wait? */
		if ( semcb->semcnt < tcb->winfo.sem.cnt ) {
			if ( (semcb->sematr & TA_CNT) == 0 ) {
				break;
			}
			continue;
		}

		/* Release wait */
		knl_wait_release_ok(tcb);

		semcb->semcnt -= tcb->winfo.sem.cnt;
		if ( semcb->semcnt <= 0 ) {
			break;
		}
	}

    error_exit:
	END_CRITICAL_SECTION;

	return ercd;
}
Example #11
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;
}
Example #12
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);
}
Example #13
0
/*
 * Refer object state
 */
SYSCALL ER td_ref_sem_impl( ID semid, TD_RSEM *pk_rsem )
{
	SEMCB	*semcb;
	ER	ercd = E_OK;

	CHECK_SEMID(semid);

	semcb = get_semcb(semid);

	BEGIN_DISABLE_INTERRUPT;
	if ( semcb->semid == 0 ) {
		ercd = E_NOEXS;
	} else {
		pk_rsem->exinf  = semcb->exinf;
		pk_rsem->wtsk   = knl_wait_tskid(&semcb->wait_queue);
		pk_rsem->semcnt = semcb->semcnt;
	}
	END_DISABLE_INTERRUPT;

	return ercd;
}
Example #14
0
/*
 * Refer semaphore state
 */
SYSCALL ER tk_ref_sem_impl( ID semid, T_RSEM *pk_rsem )
{
	SEMCB	*semcb;
	ER	ercd = E_OK;

	CHECK_SEMID(semid);

	semcb = get_semcb(semid);

	BEGIN_CRITICAL_SECTION;
	if ( semcb->semid == 0 ) {
		ercd = E_NOEXS;
	} else {
		pk_rsem->exinf  = semcb->exinf;
		pk_rsem->wtsk   = knl_wait_tskid(&semcb->wait_queue);
		pk_rsem->semcnt = semcb->semcnt;
	}
	END_CRITICAL_SECTION;

	return ercd;
}
Example #15
0
ER
del_sem(ID semid)
{
    SEMCB	*p_semcb;
    SEMINIB	*p_seminib;
    bool_t	dspreq;
    ER		ercd;

    LOG_DEL_SEM_ENTER(semid);
    CHECK_TSKCTX_UNL();
    CHECK_SEMID(semid);
    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.acptn3)) {
        ercd = E_OACV;
    }
    else if (SEMID(p_semcb) > tmax_ssemid) {
        dspreq = init_wait_queue(&(p_semcb->wait_queue));
        p_seminib = (SEMINIB *)(p_semcb->p_seminib);
        p_seminib->sematr = TA_NOEXS;
        queue_insert_prev(&free_semcb, &(p_semcb->wait_queue));
        if (dspreq) {
            dispatch();
        }
        ercd = E_OK;
    }
    else {
        ercd = E_OBJ;
    }
    t_unlock_cpu();

error_exit:
    LOG_DEL_SEM_LEAVE(ercd);
    return(ercd);
}
Example #16
0
ER
sig_sem(ID semid)
{
    SEMCB	*p_semcb;
    TCB		*p_tcb;
    ER		ercd;

    LOG_SIG_SEM_ENTER(semid);
    CHECK_TSKCTX_UNL();
    CHECK_SEMID(semid);
    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.acptn1)) {
        ercd = E_OACV;
    }
    else if (!queue_empty(&(p_semcb->wait_queue))) {
        p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
        if (wait_complete(p_tcb)) {
            dispatch();
        }
        ercd = E_OK;
    }
    else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
        p_semcb->semcnt += 1;
        ercd = E_OK;
    }
    else {
        ercd = E_QOVR;
    }
    t_unlock_cpu();

error_exit:
    LOG_SIG_SEM_LEAVE(ercd);
    return(ercd);
}
Example #17
0
/*
 * Get object name from control block
 */
EXPORT ER knl_semaphore_getname(ID id, UB **name)
{
	SEMCB	*semcb;
	ER	ercd = E_OK;

	CHECK_SEMID(id);

	BEGIN_DISABLE_INTERRUPT;
	semcb = get_semcb(id);
	if ( semcb->semid == 0 ) {
		ercd = E_NOEXS;
		goto error_exit;
	}
	if ( (semcb->sematr & TA_DSNAME) == 0 ) {
		ercd = E_OBJ;
		goto error_exit;
	}
	*name = semcb->name;

    error_exit:
	END_DISABLE_INTERRUPT;

	return ercd;
}
Example #18
0
ER
isig_sem(ID semid)
{
    SEMCB	*p_semcb;
    TCB		*p_tcb;
    ER		ercd;

    LOG_ISIG_SEM_ENTER(semid);
    CHECK_INTCTX_UNL();
    CHECK_SEMID(semid);
    p_semcb = get_semcb(semid);

    i_lock_cpu();
    if (p_semcb->p_seminib->sematr == TA_NOEXS) {
        ercd = E_NOEXS;
    }
    else if (!queue_empty(&(p_semcb->wait_queue))) {
        p_tcb = (TCB *) queue_delete_next(&(p_semcb->wait_queue));
        if (wait_complete(p_tcb)) {
            reqflg = true;
        }
        ercd = E_OK;
    }
    else if (p_semcb->semcnt < p_semcb->p_seminib->maxsem) {
        p_semcb->semcnt += 1;
        ercd = E_OK;
    }
    else {
        ercd = E_QOVR;
    }
    i_unlock_cpu();

error_exit:
    LOG_ISIG_SEM_LEAVE(ercd);
    return(ercd);
}
Example #19
0
/*
 * Delete semaphore
 */
SYSCALL ER tk_del_sem_impl( ID semid )
{
	SEMCB	*semcb;
	ER	ercd = E_OK;

	CHECK_SEMID(semid);

	semcb = get_semcb(semid);

	BEGIN_CRITICAL_SECTION;
	if ( semcb->semid == 0 ) {
		ercd = E_NOEXS;
	} else {
		/* Release wait state of task (E_DLT) */
		knl_wait_delete(&semcb->wait_queue);

		/* Return to FreeQue */
		QueInsert(&semcb->wait_queue, &knl_free_semcb);
		semcb->semid = 0;
	}
	END_CRITICAL_SECTION;

	return ercd;
}