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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }
/* * 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; }
/* * 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; }
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); }
/* * 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; }
/* * 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; }
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); }
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); }
/* * 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; }
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); }
/* * 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; }