ER slp_tsk(void) { WINFO winfo; ER ercd; LOG_SLP_TSK_ENTER(); CHECK_DISPATCH(); t_lock_cpu(); if (p_runtsk->wupque) { p_runtsk->wupque = false; ercd = E_OK; } else { p_runtsk->tstat = (TS_WAITING | TS_WAIT_SLP); make_wait(&winfo); LOG_TSKSTAT(p_runtsk); dispatch(); ercd = winfo.wercd; } t_unlock_cpu(); error_exit: LOG_SLP_TSK_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); }
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 { 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); }
ER dly_tsk(RELTIM dlytim) { WINFO winfo; TMEVTB tmevtb; ER ercd; LOG_DLY_TSK_ENTER(dlytim); CHECK_DISPATCH(); CHECK_PAR(dlytim <= TMAX_RELTIM); t_lock_cpu(); p_runtsk->tstat = (TS_WAITING | TS_WAIT_DLY); (void) make_non_runnable(p_runtsk); p_runtsk->p_winfo = &winfo; winfo.p_tmevtb = &tmevtb; tmevtb_enqueue(&tmevtb, dlytim, (CBACK) wait_tmout_ok, (void *) p_runtsk); LOG_TSKSTAT(p_runtsk); dispatch(); ercd = winfo.wercd; t_unlock_cpu(); error_exit: LOG_DLY_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); }
JSP_L1_CODE 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 rcv_mbx(ID mbxid, T_MSG **ppk_msg) { MBXCB *mbxcb; WINFO_MBX winfo; ER ercd; LOG_RCV_MBX_ENTER(mbxid, ppk_msg); CHECK_DISPATCH(); CHECK_MBXID(mbxid); mbxcb = get_mbxcb(mbxid); t_lock_cpu(); if (mbxcb->head != NULL) { *ppk_msg = mbxcb->head; mbxcb->head = (*ppk_msg)->next; ercd = E_OK; } else { wobj_make_wait((WOBJCB *) mbxcb, (WINFO_WOBJ *) &winfo); dispatch(); ercd = winfo.winfo.wercd; if (ercd == E_OK) { *ppk_msg = winfo.pk_msg; } } t_unlock_cpu(); exit: LOG_RCV_MBX_LEAVE(ercd, *ppk_msg); 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 loc_mtx(ID mtxid) { MTXCB *p_mtxcb; WINFO_MTX winfo_mtx; ER ercd; LOG_LOC_MTX_ENTER(mtxid); CHECK_DISPATCH(); CHECK_ID(VALID_MTXID(mtxid)); p_mtxcb = get_mtxcb(mtxid); lock_cpu_dsp(); if (p_mtxcb->p_mtxinib->mtxatr == TA_NOEXS) { ercd = E_NOEXS; } else if (VIOLATE_ACPTN(p_mtxcb->p_mtxinib->acvct.acptn1)) { ercd = E_OACV; } else if (MTX_CEILING(p_mtxcb) && p_mtxcb->p_mtxinib->ceilpri < p_runtsk->p_dominib->minpriority && VIOLATE_ACPTN(p_runtsk->p_dominib->acvct.acptn2)) { ercd = E_OACV; /*[NGKI5124]*/ } else if (p_runtsk->raster) { ercd = E_RASTER; } else if (MTX_CEILING(p_mtxcb) && p_runtsk->bpriority < p_mtxcb->p_mtxinib->ceilpri) { ercd = E_ILUSE; } else if (p_mtxcb->p_loctsk == NULL) { mutex_acquire(p_runtsk, p_mtxcb); /* * 優先度上限ミューテックスをロックした場合,p_runtskの優先度 * が上がる可能性があるが,ディスパッチが必要になることはない. */ assert(p_runtsk == p_schedtsk); ercd = E_OK; } else if (p_mtxcb->p_loctsk == p_runtsk) { ercd = E_OBJ; } else { wobj_make_wait((WOBJCB *) p_mtxcb, TS_WAITING_MTX, (WINFO_WOBJ *) &winfo_mtx); dispatch(); ercd = winfo_mtx.winfo.wercd; } unlock_cpu_dsp(); error_exit: LOG_LOC_MTX_LEAVE(ercd); 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; }
ER trcv_mbf(ID mbfid, void *msg, TMO tmout) { MBFCB *p_mbfcb; WINFO_RMBF winfo_rmbf; TMEVTB tmevtb; uint_t msgsz; ER_UINT ercd; LOG_TRCV_MBF_ENTER(mbfid, msg, tmout); CHECK_DISPATCH(); CHECK_ID(VALID_MBFID(mbfid)); CHECK_PAR(VALID_TMOUT(tmout)); p_mbfcb = get_mbfcb(mbfid); lock_cpu_dsp(); if (p_mbfcb->p_mbfinib->mbfatr == TA_NOEXS) { ercd = E_NOEXS; } else if (VIOLATE_ACPTN(p_mbfcb->p_mbfinib->acvct.acptn2)) { ercd = E_OACV; } else if (!KERNEL_PROBE_BUF_WRITE(msg, p_mbfcb->p_mbfinib->maxmsz)) { ercd = E_MACV; } else if (p_runtsk->raster) { ercd = E_RASTER; } else if ((msgsz = receive_message(p_mbfcb, msg)) > 0U) { if (p_runtsk != p_schedtsk) { dispatch(); } ercd = (ER_UINT) msgsz; } else if (tmout == TMO_POL) { ercd = E_TMOUT; } else { make_wait_tmout(TS_WAITING_RMBF, &(winfo_rmbf.winfo), &tmevtb, tmout); queue_insert_prev(&(p_mbfcb->rwait_queue), &(p_runtsk->task_queue)); winfo_rmbf.p_mbfcb = p_mbfcb; winfo_rmbf.msg = msg; LOG_TSKSTAT(p_runtsk); dispatch(); ercd = winfo_rmbf.winfo.wercd; } unlock_cpu_dsp(); error_exit: LOG_TRCV_MBF_LEAVE(ercd, msg); 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; }
ER tsnd_mbf(ID mbfid, const void *msg, uint_t msgsz, TMO tmout) { MBFCB *p_mbfcb; WINFO_SMBF winfo_smbf; TMEVTB tmevtb; ER ercd; LOG_TSND_MBF_ENTER(mbfid, msg, msgsz, tmout); CHECK_DISPATCH(); CHECK_ID(VALID_MBFID(mbfid)); CHECK_PAR(VALID_TMOUT(tmout)); CHECK_MACV_BUF_READ(msg, msgsz); CHECK_PAR(0 < msgsz); p_mbfcb = get_mbfcb(mbfid); lock_cpu_dsp(); if (p_mbfcb->p_mbfinib->mbfatr == TA_NOEXS) { ercd = E_NOEXS; } else if (VIOLATE_ACPTN(p_mbfcb->p_mbfinib->acvct.acptn1)) { ercd = E_OACV; } else if (!(msgsz <= p_mbfcb->p_mbfinib->maxmsz)) { ercd = E_PAR; } else if (p_runtsk->raster) { ercd = E_RASTER; } else if (send_message(p_mbfcb, msg, msgsz)) { if (p_runtsk != p_schedtsk) { dispatch(); } ercd = E_OK; } else if (tmout == TMO_POL) { ercd = E_TMOUT; } else { winfo_smbf.msg = msg; winfo_smbf.msgsz = msgsz; wobj_make_wait_tmout((WOBJCB *) p_mbfcb, TS_WAITING_SMBF, (WINFO_WOBJ *) &winfo_smbf, &tmevtb, tmout); dispatch(); ercd = winfo_smbf.winfo.wercd; } unlock_cpu_dsp(); error_exit: LOG_TSND_MBF_LEAVE(ercd); 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_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri, TMO tmout) { PDQCB *p_pdqcb; WINFO_RPDQ winfo_rpdq; TMEVTB tmevtb; ER ercd; LOG_TRCV_PDQ_ENTER(pdqid, p_data, p_datapri, tmout); CHECK_DISPATCH(); CHECK_ID(VALID_PDQID(pdqid)); CHECK_PAR(VALID_TMOUT(tmout)); p_pdqcb = get_pdqcb(pdqid); lock_cpu_dsp(); if (p_runtsk->raster) { ercd = E_RASTER; } else if (receive_pridata(p_pdqcb, p_data, p_datapri)) { if (p_runtsk != p_schedtsk) { dispatch(); } ercd = E_OK; } else if (tmout == TMO_POL) { ercd = E_TMOUT; } else { p_runtsk->tstat = TS_WAITING_RPDQ; make_wait_tmout(&(winfo_rpdq.winfo), &tmevtb, tmout); queue_insert_prev(&(p_pdqcb->rwait_queue), &(p_runtsk->task_queue)); winfo_rpdq.p_pdqcb = p_pdqcb; LOG_TSKSTAT(p_runtsk); dispatch(); ercd = winfo_rpdq.winfo.wercd; if (ercd == E_OK) { *p_data = winfo_rpdq.data; *p_datapri = winfo_rpdq.datapri; } } unlock_cpu_dsp(); error_exit: LOG_TRCV_PDQ_LEAVE(ercd, p_data, p_datapri); return(ercd); }
/* * Return fixed size memory block */ SYSCALL ER tk_rel_mpf_impl( ID mpfid, VP blf ) { MPFCB *mpfcb; TCB *tcb; FREEL *free; ER ercd = E_OK; CHECK_MPFID(mpfid); CHECK_DISPATCH(); mpfcb = get_mpfcb(mpfid); knl_LockOBJ(&mpfcb->lock); if ( mpfcb->mpfid == 0 ) { ercd = E_NOEXS; goto error_exit; } #if CHK_PAR if ( blf < mpfcb->mempool || blf >= knl_mempool_end(mpfcb) || (((VB*)blf - (VB*)mpfcb->mempool) % mpfcb->blfsz) != 0 ) { ercd = E_PAR; goto error_exit; } #endif DISABLE_INTERRUPT; if ( !isQueEmpty(&mpfcb->wait_queue) ) { /* Send memory block to waiting task, and then release the task */ tcb = (TCB*)mpfcb->wait_queue.next; *tcb->winfo.mpf.p_blf = blf; knl_wait_release_ok(tcb); ENABLE_INTERRUPT; } else { ENABLE_INTERRUPT; /* Free memory block */ free = (FREEL*)blf; free->next = mpfcb->freelist; mpfcb->freelist = free; mpfcb->frbcnt++; } error_exit: knl_UnlockOBJ(&mpfcb->lock); 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); }
/* * 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); }
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_ID(VALID_MPFID(mpfid)); CHECK_PAR(VALID_TMOUT(tmout)); p_mpfcb = get_mpfcb(mpfid); lock_cpu_dsp(); if (p_mpfcb->p_mpfinib->mpfatr == TA_NOEXS) { ercd = E_NOEXS; } else if (p_runtsk->raster) { ercd = E_RASTER; } else 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_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; } } unlock_cpu_dsp(); error_exit: LOG_TGET_MPF_LEAVE(ercd, p_blk); return(ercd); }
ER tsnd_pdq(ID pdqid, intptr_t data, PRI datapri, TMO tmout) { PDQCB *p_pdqcb; WINFO_SPDQ winfo_spdq; TMEVTB tmevtb; ER ercd; LOG_TSND_PDQ_ENTER(pdqid, data, datapri, tmout); CHECK_DISPATCH(); CHECK_ID(VALID_PDQID(pdqid)); CHECK_PAR(VALID_TMOUT(tmout)); p_pdqcb = get_pdqcb(pdqid); CHECK_PAR(TMIN_DPRI <= datapri && datapri <= p_pdqcb->p_pdqinib->maxdpri); lock_cpu_dsp(); if (p_runtsk->raster) { ercd = E_RASTER; } else if (send_pridata(p_pdqcb, data, datapri)) { if (p_runtsk != p_schedtsk) { dispatch(); } ercd = E_OK; } else if (tmout == TMO_POL) { ercd = E_TMOUT; } else { winfo_spdq.data = data; winfo_spdq.datapri = datapri; p_runtsk->tstat = TS_WAITING_SPDQ; wobj_make_wait_tmout((WOBJCB *) p_pdqcb, (WINFO_WOBJ *) &winfo_spdq, &tmevtb, tmout); dispatch(); ercd = winfo_spdq.winfo.wercd; } unlock_cpu_dsp(); error_exit: LOG_TSND_PDQ_LEAVE(ercd); 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_ID(VALID_SEMID(semid)); CHECK_PAR(VALID_TMOUT(tmout)); p_semcb = get_semcb(semid); lock_cpu_dsp(); 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_runtsk->raster) { ercd = E_RASTER; } else if (p_semcb->semcnt >= 1) { p_semcb->semcnt -= 1; ercd = E_OK; } else if (tmout == TMO_POL) { ercd = E_TMOUT; } else { wobj_make_wait_tmout((WOBJCB *) p_semcb, TS_WAITING_SEM, (WINFO_WOBJ *) &winfo_sem, &tmevtb, tmout); dispatch(); ercd = winfo_sem.winfo.wercd; } unlock_cpu_dsp(); error_exit: LOG_TWAI_SEM_LEAVE(ercd); 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); }
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 rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) { PDQCB *p_pdqcb; WINFO_PDQ winfo_pdq; bool_t reqdsp; ER ercd; LOG_RCV_PDQ_ENTER(pdqid, p_data, p_datapri); CHECK_DISPATCH(); CHECK_PDQID(pdqid); p_pdqcb = get_pdqcb(pdqid); t_lock_cpu(); if (p_pdqcb->p_pdqinib->pdqatr == TA_NOEXS) { ercd = E_NOEXS; } else if (receive_pridata(p_pdqcb, p_data, p_datapri, &reqdsp)) { if (reqdsp) { dispatch(); } ercd = E_OK; } else { p_runtsk->tstat = (TS_WAITING | TS_WAIT_RPDQ); make_wait(&(winfo_pdq.winfo)); 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_RCV_PDQ_LEAVE(ercd, *p_data, *p_datapri); return(ercd); }
ER wai_flg(ID flgid, FLGPTN waiptn, MODE wfmode, FLGPTN *p_flgptn) { FLGCB *p_flgcb; WINFO_FLG winfo_flg; ER ercd; LOG_WAI_FLG_ENTER(flgid, waiptn, wfmode, p_flgptn); CHECK_DISPATCH(); CHECK_FLGID(flgid); CHECK_PAR(waiptn != 0U); CHECK_PAR(wfmode == TWF_ORW || wfmode == TWF_ANDW); p_flgcb = get_flgcb(flgid); t_lock_cpu(); if (p_flgcb->p_flginib->flgatr == TA_NOEXS) { ercd = E_NOEXS; } 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 { winfo_flg.waiptn = waiptn; winfo_flg.wfmode = wfmode; p_runtsk->tstat = (TS_WAITING | TS_WAIT_FLG); wobj_make_wait((WOBJCB *) p_flgcb, (WINFO_WOBJ *) &winfo_flg); dispatch(); ercd = winfo_flg.winfo.wercd; if (ercd == E_OK) { *p_flgptn = winfo_flg.flgptn; } } t_unlock_cpu(); error_exit: LOG_WAI_FLG_LEAVE(ercd, *p_flgptn); return(ercd); }