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