📄 rendezvous.c
字号:
(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;}/* * Forward Rendezvous to Other Port */SYSCALL ER _tk_fwd_por( ID porid, UINT calptn, RNO rdvno, VP msg, INT cmsgsz ){ PORCB *porcb; TCB *caltcb, *tcb; QUEUE *queue; RNO new_rdvno; ER ercd = E_OK; CHECK_PORID(porid); CHECK_PAR(calptn != 0); CHECK_RDVNO(rdvno); CHECK_PAR(cmsgsz >= 0); CHECK_INTSK(); porcb = get_porcb(porid); caltcb = get_tcb(get_tskid_rdvno(rdvno)); 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 if ( (caltcb->state & TS_WAIT) == 0 || caltcb->wspec != &wspec_rdv || rdvno != caltcb->winfo.rdv.rdvno ) { ercd = E_OBJ; goto error_exit; } if ( porcb->maxrmsz > caltcb->winfo.rdv.maxrmsz ) { ercd = E_OBJ; goto error_exit; }#if CHK_PAR if ( cmsgsz > caltcb->winfo.rdv.maxrmsz ) { 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 accept wait disable */ if ( is_diswai((GCB*)porcb, caltcb, TTW_CAL) ) { wait_release_ng(caltcb, E_DISWAI); ercd = E_DISWAI; goto error_exit; } /* Send message */ new_rdvno = gen_rdvno(caltcb); if ( cmsgsz > 0 ) { memcpy(tcb->winfo.acp.msg, msg, (UINT)cmsgsz); } *tcb->winfo.acp.p_rdvno = new_rdvno; *tcb->winfo.acp.p_cmsgsz = cmsgsz; wait_release_ok(tcb); /* Check rendezvous end wait disable */ if ( is_diswai((GCB*)porcb, caltcb, TTW_RDV) ) { wait_release_ng(caltcb, E_DISWAI); ercd = E_DISWAI; goto error_exit; } /* Change rendezvous end wait of the other task */ caltcb->winfo.rdv.rdvno = new_rdvno; caltcb->winfo.rdv.msg = caltcb->winfo.cal.msg; caltcb->winfo.rdv.maxrmsz = porcb->maxrmsz; caltcb->winfo.rdv.p_rmsgsz = caltcb->winfo.cal.p_rmsgsz; caltcb->nodiswai = ( (porcb->poratr & TA_NODISWAI) != 0 )? TRUE: FALSE; goto error_exit; } /* Check rendezvous accept wait disable */ if ( is_diswai((GCB*)porcb, caltcb, TTW_CAL) ) { wait_release_ng(caltcb, E_DISWAI); ercd = E_DISWAI; goto error_exit; } /* Change the other task to rendezvous call wait */ caltcb->wspec = ( (porcb->poratr & TA_TPRI) != 0 )? &wspec_cal_tpri: &wspec_cal_tfifo; caltcb->wid = porid; caltcb->winfo.cal.calptn = calptn; caltcb->winfo.cal.msg = caltcb->winfo.rdv.msg; caltcb->winfo.cal.cmsgsz = cmsgsz; caltcb->winfo.cal.p_rmsgsz = caltcb->winfo.rdv.p_rmsgsz; caltcb->nodiswai = ( (porcb->poratr & TA_NODISWAI) != 0 )? TRUE: FALSE; timer_insert(&caltcb->wtmeb, TMO_FEVR, (CBACK)wait_release_tmout, caltcb); if ( (porcb->poratr & TA_TPRI) != 0 ) { queue_insert_tpri(caltcb, &porcb->call_queue); } else { QueInsert(&caltcb->tskque, &porcb->call_queue); } if ( cmsgsz > 0 ) { memcpy(caltcb->winfo.cal.msg, msg, (UINT)cmsgsz); } error_exit: END_CRITICAL_SECTION; return ercd;}/* * Reply rendezvous */SYSCALL ER _tk_rpl_rdv( RNO rdvno, VP msg, INT rmsgsz ){ TCB *caltcb; ER ercd = E_OK; CHECK_RDVNO(rdvno); CHECK_PAR(rmsgsz >= 0); CHECK_INTSK(); caltcb = get_tcb(get_tskid_rdvno(rdvno)); BEGIN_CRITICAL_SECTION; if ( (caltcb->state & TS_WAIT) == 0 || caltcb->wspec != &wspec_rdv || rdvno != caltcb->winfo.rdv.rdvno ) { ercd = E_OBJ; goto error_exit; }#if CHK_PAR if ( rmsgsz > caltcb->winfo.rdv.maxrmsz ) { ercd = E_PAR; goto error_exit; }#endif /* Send message */ if ( rmsgsz > 0 ) { memcpy(caltcb->winfo.rdv.msg, msg, (UINT)rmsgsz); } *caltcb->winfo.rdv.p_rmsgsz = rmsgsz; wait_release_ok(caltcb); error_exit: END_CRITICAL_SECTION; return ercd;}/* * Refer rendezvous port */SYSCALL ER _tk_ref_por( ID porid, T_RPOR *pk_rpor ){ PORCB *porcb; ER ercd = E_OK; CHECK_PORID(porid); porcb = get_porcb(porid); BEGIN_CRITICAL_SECTION; if ( porcb->porid == 0 ) { ercd = E_NOEXS; } else { pk_rpor->exinf = porcb->exinf; pk_rpor->wtsk = wait_tskid(&porcb->call_queue); pk_rpor->atsk = wait_tskid(&porcb->accept_queue); pk_rpor->maxcmsz = porcb->maxcmsz; pk_rpor->maxrmsz = porcb->maxrmsz; } END_CRITICAL_SECTION; return ercd;}/* ------------------------------------------------------------------------ *//* * Debugger support function */#if USE_DBGSPT/* * Get object name from control block */#if USE_OBJECT_NAMEEXPORT ER rendezvous_getname(ID id, UB **name){ PORCB *porcb; ER ercd = E_OK; CHECK_PORID(id); BEGIN_DISABLE_INTERRUPT; porcb = get_porcb(id); if ( porcb->porid == 0 ) { ercd = E_NOEXS; goto error_exit; } if ( (porcb->poratr & TA_DSNAME) == 0 ) { ercd = E_OBJ; goto error_exit; } *name = porcb->name; error_exit: END_DISABLE_INTERRUPT; return ercd;}#endif /* USE_OBJECT_NAME *//* * Refer rendezvous port usage state */SYSCALL INT _td_lst_por( ID list[], INT nent ){ PORCB *porcb, *end; INT n = 0; BEGIN_DISABLE_INTERRUPT; end = porcb_table + NUM_PORID; for ( porcb = porcb_table; porcb < end; porcb++ ) { if ( porcb->porid == 0 ) { continue; } if ( n++ < nent ) { *list++ = porcb->porid; } } END_DISABLE_INTERRUPT; return n;}/* * Refer rendezvous port */SYSCALL ER _td_ref_por( ID porid, TD_RPOR *pk_rpor ){ PORCB *porcb; ER ercd = E_OK; CHECK_PORID(porid); porcb = get_porcb(porid); BEGIN_DISABLE_INTERRUPT; if ( porcb->porid == 0 ) { ercd = E_NOEXS; } else { pk_rpor->exinf = porcb->exinf; pk_rpor->wtsk = wait_tskid(&porcb->call_queue); pk_rpor->atsk = wait_tskid(&porcb->accept_queue); pk_rpor->maxcmsz = porcb->maxcmsz; pk_rpor->maxrmsz = porcb->maxrmsz; } END_DISABLE_INTERRUPT; return ercd;}/* * Refer rendezvous call wait queue */SYSCALL INT _td_cal_que( ID porid, ID list[], INT nent ){ PORCB *porcb; QUEUE *q; ER ercd = E_OK; CHECK_PORID(porid); porcb = get_porcb(porid); BEGIN_DISABLE_INTERRUPT; if ( porcb->porid == 0 ) { ercd = E_NOEXS; } else { INT n = 0; for ( q = porcb->call_queue.next; q != &porcb->call_queue; q = q->next ) { if ( n++ < nent ) { *list++ = ((TCB*)q)->tskid; } } ercd = n; } END_DISABLE_INTERRUPT; return ercd;}/* * Refer rendezvous accept wait queue */SYSCALL INT _td_acp_que( ID porid, ID list[], INT nent ){ PORCB *porcb; QUEUE *q; ER ercd = E_OK; CHECK_PORID(porid); porcb = get_porcb(porid); BEGIN_DISABLE_INTERRUPT; if ( porcb->porid == 0 ) { ercd = E_NOEXS; } else { INT n = 0; for ( q = porcb->accept_queue.next; q != &porcb->accept_queue; q = q->next ) { if ( n++ < nent ) { *list++ = ((TCB*)q)->tskid; } } ercd = n; } END_DISABLE_INTERRUPT; return ercd;}#endif /* USE_DBGSPT */#endif /* NUM_PORID */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -