/* * Send to mailbox */ SYSCALL ER _tk_snd_mbx( ID mbxid, T_MSG *pk_msg ) { MBXCB *mbxcb; TCB *tcb; ER ercd = E_OK; CHECK_MBXID(mbxid); mbxcb = get_mbxcb(mbxid); BEGIN_CRITICAL_SECTION; if (mbxcb->mbxid == 0) { ercd = E_NOEXS; goto error_exit; } if ( (mbxcb->mbxatr & TA_MPRI) != 0 ) { if ( ((T_MSG_PRI*)pk_msg)->msgpri <= 0 ) { ercd = E_PAR; goto error_exit; } } if ( !isQueEmpty(&mbxcb->wait_queue) ) { /* Directly send to receive wait task */ tcb = (TCB*)(mbxcb->wait_queue.next); *tcb->winfo.mbx.ppk_msg = pk_msg; wait_release_ok(tcb); } else { /* Connect message to queue */ if ( (mbxcb->mbxatr & TA_MPRI) != 0 ) { /* Connect message to queue following priority */ queue_insert_mpri((T_MSG_PRI*)pk_msg, &mbxcb->mq_head); } else { /* Connect to end of queue */ nextmsg(pk_msg) = NULL; if ( headmsg(mbxcb) == NULL ) { headmsg(mbxcb) = pk_msg; } else { nextmsg(mbxcb->mq_tail) = pk_msg; } mbxcb->mq_tail = pk_msg; } } error_exit: END_CRITICAL_SECTION; return ercd; }
/* * Insert a message queue following priority */ Inline void queue_insert_mpri( T_MSG_PRI *pk_msg, T_MSG *head ) { T_MSG_PRI *msg; T_MSG *prevmsg = head; while ( (msg = (T_MSG_PRI*)nextmsg(prevmsg)) != NULL ) { if ( msg->msgpri > pk_msg->msgpri ) { break; } prevmsg = (T_MSG*)msg; } nextmsg(pk_msg) = msg; nextmsg(prevmsg) = pk_msg; }
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 i_vsnd_tmb(ID tskid,T_MSG *pk_msg) { TCB *tcb; TSTAT state; ER ercd = E_OK; CHECK_TSKID(tskid); CHECK_TSKACV(tskid); CHECK_NONSELF(tskid); tcb = get_tcb(tskid); BEGIN_CRITICAL_SECTION; if ( !task_alive(state = tcb->state) ) { ercd = (state == TS_NONEXIST) ? E_NOEXS : E_OBJ; } else if ((state & TS_WAIT) && tcb->wspec == &wspec_tmb_tfifo) { *(tcb->winfo.tmb.ppk_msg) = pk_msg; wait_release_ok(tcb); } else { nextmsg(pk_msg) = (T_MSG *) 0; if (tcb->tmq_head) { nextmsg(tcb->tmq_tail) = pk_msg; } else { tcb->tmq_head = pk_msg; } tcb->tmq_tail = pk_msg; } END_CRITICAL_SECTION; 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; }