ER slp_tsk(void) { WINFO winfo; ER ercd; LOG_SLP_TSK_ENTER(); CHECK_DISPATCH(); lock_cpu_dsp(); if (p_runtsk->raster) { ercd = E_RASTER; } else if (p_runtsk->wupque) { p_runtsk->wupque = false; ercd = E_OK; } else { p_runtsk->tstat = TS_WAITING_SLP; make_wait(&winfo); LOG_TSKSTAT(p_runtsk); dispatch(); ercd = winfo.wercd; } unlock_cpu_dsp(); error_exit: LOG_SLP_TSK_LEAVE(ercd); 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; }
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 if (p_runtsk->waifbd) { ercd = E_RLWAI; } 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); }
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 slp_tsk() { WINFO winfo; ER ercd; LOG_SLP_TSK_ENTER(); CHECK_DISPATCH(); t_lock_cpu(); if (runtsk->wupcnt) { runtsk->wupcnt = FALSE; ercd = E_OK; } else { runtsk->tstat = (TS_WAITING | TS_WAIT_SLEEP); make_wait(&winfo); LOG_TSKSTAT(runtsk); dispatch(); ercd = winfo.wercd; } t_unlock_cpu(); exit: LOG_SLP_TSK_LEAVE(ercd); return(ercd); }
void wobj_make_wait(WOBJCB *p_wobjcb, WINFO_WOBJ *p_winfo_wobj) { make_wait((WINFO *) p_winfo_wobj); wobj_queue_insert(p_wobjcb); p_winfo_wobj->p_wobjcb = p_wobjcb; LOG_TSKSTAT(p_runtsk); }
void wobj_make_wait(WOBJCB *p_wobjcb, uint_t tstat, WINFO_WOBJ *p_winfo_wobj) { make_wait(tstat, &(p_winfo_wobj->winfo)); wobj_queue_insert(p_wobjcb); p_winfo_wobj->p_wobjcb = p_wobjcb; LOG_TSKSTAT(p_runtsk); }
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; }
void wobj_make_wait(WOBJCB *wobjcb, WINFO_WOBJ *winfo) { runtsk->tstat = (TS_WAITING | TS_WAIT_WOBJ | TS_WAIT_WOBJCB); make_wait(&(winfo->winfo)); wobj_queue_insert(wobjcb); winfo->wobjcb = wobjcb; LOG_TSKSTAT(runtsk); }
ER rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) { PDQCB *p_pdqcb; WINFO_PDQ winfo_pdq; bool_t dspreq; ER ercd; LOG_RCV_PDQ_ENTER(pdqid, p_data, p_datapri); CHECK_DISPATCH(); CHECK_PDQID(pdqid); CHECK_MACV_WRITE(p_data, intptr_t); CHECK_MACV_WRITE(p_datapri, PRI); 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 (p_runtsk->waifbd) { ercd = E_RLWAI; } 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_UINT rcv_mbf(ID mbfid, void *msg) { MBFCB *p_mbfcb; WINFO_RMBF winfo_rmbf; uint_t msgsz; ER_UINT ercd; LOG_RCV_MBF_ENTER(mbfid, msg); CHECK_DISPATCH(); CHECK_ID(VALID_MBFID(mbfid)); 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 { make_wait(TS_WAITING_RMBF, &(winfo_rmbf.winfo)); 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_RCV_MBF_LEAVE(ercd, msg); return(ercd); }
ER rcv_pdq(ID pdqid, intptr_t *p_data, PRI *p_datapri) { PDQCB *p_pdqcb; WINFO_RPDQ winfo_rpdq; ER ercd; LOG_RCV_PDQ_ENTER(pdqid, p_data, p_datapri); CHECK_DISPATCH(); CHECK_ID(VALID_PDQID(pdqid)); 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 { p_runtsk->tstat = TS_WAITING_RPDQ; make_wait(&(winfo_rpdq.winfo)); 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_RCV_PDQ_LEAVE(ercd, p_data, p_datapri); return(ercd); }
ER_UINT rcv_mbf(ID mbfid, void *msg) { MBFCB *p_mbfcb; WINFO_MBF winfo_mbf; uint_t msgsz; bool_t dspreq; ER_UINT ercd; LOG_RCV_MBF_ENTER(mbfid, msg); CHECK_DISPATCH(); CHECK_MBFID(mbfid); 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 { p_runtsk->tstat = (TS_WAITING | TS_WAIT_RMBF); make_wait(&(winfo_mbf.winfo)); 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_RCV_MBF_LEAVE(ercd, msg); 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; }
ER rcv_dtq(ID dtqid, intptr_t *p_data) { DTQCB *p_dtqcb; WINFO_DTQ winfo_dtq; bool_t reqdsp; ER ercd; LOG_RCV_DTQ_ENTER(dtqid, p_data); CHECK_DISPATCH(); CHECK_DTQID(dtqid); p_dtqcb = get_dtqcb(dtqid); t_lock_cpu(); if (receive_data(p_dtqcb, p_data, &reqdsp)) { if (reqdsp) { dispatch(); } ercd = E_OK; } else { p_runtsk->tstat = (TS_WAITING | TS_WAIT_RDTQ); make_wait(&(winfo_dtq.winfo)); 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_RCV_DTQ_LEAVE(ercd, *p_data); return(ercd); }
SYSCALL INT _tk_acp_por_u( ID porid, UINT acpptn, RNO *p_rdvno, void *msg, TMO_U 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; } /* Check rendezvous accept wait disable */ if ( is_diswai((GCB*)porcb, ctxtsk, TTW_ACP) ) { ercd = E_DISWAI; goto error_exit; } /* Receive message */ *p_rdvno = rdvno = gen_rdvno(tcb); cmsgsz = tcb->winfo.cal.cmsgsz; if ( cmsgsz > 0 ) { memcpy(msg, tcb->winfo.cal.msg, (UINT)cmsgsz); } /* Check rendezvous end wait disable */ if ( is_diswai((GCB*)porcb, tcb, TTW_RDV) ) { wait_release_ng(tcb, E_DISWAI); goto error_exit; } wait_cancel(tcb); /* Make the other task at rendezvous end wait state */ tcb->wspec = &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; timer_insert(&tcb->wtmeb, TMO_FEVR, (CBACK)wait_release_tmout, tcb); QueInit(&tcb->tskque); goto error_exit; } /* Check rendezvous accept wait disable */ if ( is_diswai((GCB*)porcb, ctxtsk, TTW_ACP) ) { ercd = E_DISWAI; goto error_exit; } ercd = E_TMOUT; if ( tmout != TMO_POL ) { /* Ready for rendezvous accept wait */ ctxtsk->wspec = &wspec_acp; ctxtsk->wid = porid; ctxtsk->wercd = &ercd; ctxtsk->winfo.acp.acpptn = acpptn; ctxtsk->winfo.acp.msg = msg; ctxtsk->winfo.acp.p_rdvno = p_rdvno; ctxtsk->winfo.acp.p_cmsgsz = &cmsgsz; make_wait(tmout, porcb->poratr); QueInsert(&ctxtsk->tskque, &porcb->accept_queue); } error_exit: END_CRITICAL_SECTION; return ( ercd < E_OK )? ercd: cmsgsz; }
SYSCALL INT _tk_cal_por_u( ID porid, UINT calptn, void *msg, INT cmsgsz, TMO_U 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; } /* Check rendezvous call wait disable */ if ( is_diswai((GCB*)porcb, ctxtsk, TTW_CAL) ) { ercd = E_DISWAI; goto error_exit; } /* Send message */ rdvno = gen_rdvno(ctxtsk); if ( cmsgsz > 0 ) { memcpy(tcb->winfo.acp.msg, msg, (UINT)cmsgsz); } *tcb->winfo.acp.p_rdvno = rdvno; *tcb->winfo.acp.p_cmsgsz = cmsgsz; wait_release_ok(tcb); /* Check rendezvous end wait disable */ if ( is_diswai((GCB*)porcb, ctxtsk, TTW_RDV) ) { ercd = E_DISWAI; goto error_exit; } /* Ready for rendezvous end wait */ ercd = E_TMOUT; ctxtsk->wspec = &wspec_rdv; ctxtsk->wid = 0; ctxtsk->wercd = &ercd; ctxtsk->winfo.rdv.rdvno = rdvno; ctxtsk->winfo.rdv.msg = msg; ctxtsk->winfo.rdv.maxrmsz = porcb->maxrmsz; ctxtsk->winfo.rdv.p_rmsgsz = &rmsgsz; make_wait(TMO_FEVR, porcb->poratr); QueInit(&ctxtsk->tskque); goto error_exit; } /* Ready for rendezvous call wait */ ctxtsk->wspec = ( (porcb->poratr & TA_TPRI) != 0 )? &wspec_cal_tpri: &wspec_cal_tfifo; ctxtsk->wercd = &ercd; ctxtsk->winfo.cal.calptn = calptn; ctxtsk->winfo.cal.msg = msg; ctxtsk->winfo.cal.cmsgsz = cmsgsz; ctxtsk->winfo.cal.p_rmsgsz = &rmsgsz; gcb_make_wait_with_diswai((GCB*)porcb, tmout); error_exit: END_CRITICAL_SECTION; return ( ercd < E_OK )? ercd: rmsgsz; }
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; }