ER ini_mbx(ID mbxid) { MBXCB *p_mbxcb; bool_t dspreq; ER ercd; LOG_INI_MBX_ENTER(mbxid); CHECK_TSKCTX_UNL(); CHECK_MBXID(mbxid); p_mbxcb = get_mbxcb(mbxid); t_lock_cpu(); dspreq = init_wait_queue(&(p_mbxcb->wait_queue)); p_mbxcb->pk_head = NULL; if (dspreq) { dispatch(); } ercd = E_OK; t_unlock_cpu(); error_exit: LOG_INI_MBX_LEAVE(ercd); return(ercd); }
ER rcv_mbx(ID mbxid, T_MSG **ppk_msg) { MBXCB *p_mbxcb; WINFO_MBX winfo_mbx; ER ercd; LOG_RCV_MBX_ENTER(mbxid, ppk_msg); CHECK_DISPATCH(); CHECK_MBXID(mbxid); 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 { p_runtsk->tstat = (TS_WAITING | TS_WAIT_MBX); wobj_make_wait((WOBJCB *) p_mbxcb, (WINFO_WOBJ *) &winfo_mbx); dispatch(); ercd = winfo_mbx.winfo.wercd; if (ercd == E_OK) { *ppk_msg = winfo_mbx.pk_msg; } } t_unlock_cpu(); error_exit: LOG_RCV_MBX_LEAVE(ercd, *ppk_msg); return(ercd); }
ER prcv_mbx(ID mbxid, T_MSG **ppk_msg) { MBXCB *p_mbxcb; ER ercd; LOG_PRCV_MBX_ENTER(mbxid, ppk_msg); CHECK_TSKCTX_UNL(); CHECK_MBXID(mbxid); 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 { ercd = E_TMOUT; } t_unlock_cpu(); error_exit: LOG_PRCV_MBX_LEAVE(ercd, *ppk_msg); return(ercd); }
/* * Refer mailbox wait queue */ SYSCALL INT _td_mbx_que( ID mbxid, ID list[], INT nent ) { MBXCB *mbxcb; QUEUE *q; ER ercd = E_OK; CHECK_MBXID(mbxid); mbxcb = get_mbxcb(mbxid); BEGIN_DISABLE_INTERRUPT; if ( mbxcb->mbxid == 0 ) { ercd = E_NOEXS; } else { INT n = 0; for ( q = mbxcb->wait_queue.next; q != &mbxcb->wait_queue; q = q->next ) { if ( n++ < nent ) { *list++ = ((TCB*)q)->tskid; } } ercd = n; } END_DISABLE_INTERRUPT; return ercd; }
/* * Processing if the priority of wait task changes */ LOCAL void mbx_chg_pri( TCB *tcb, INT oldpri ) { MBXCB *mbxcb; mbxcb = get_mbxcb(tcb->wid); gcb_change_priority((GCB*)mbxcb, tcb); }
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); }
/* * 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; }
ER snd_mbx(ID mbxid, T_MSG *pk_msg) { MBXCB *p_mbxcb; TCB *p_tcb; ER ercd; LOG_SND_MBX_ENTER(mbxid, pk_msg); CHECK_TSKCTX_UNL(); CHECK_MBXID(mbxid); p_mbxcb = get_mbxcb(mbxid); CHECK_PAR((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) == 0U || (TMIN_MPRI <= MSGPRI(pk_msg) && MSGPRI(pk_msg) <= p_mbxcb->p_mbxinib->maxmpri)); t_lock_cpu(); if (!queue_empty(&(p_mbxcb->wait_queue))) { p_tcb = (TCB *) queue_delete_next(&(p_mbxcb->wait_queue)); ((WINFO_MBX *)(p_tcb->p_winfo))->pk_msg = pk_msg; if (wait_complete(p_tcb)) { dispatch(); } ercd = E_OK; } else if ((p_mbxcb->p_mbxinib->mbxatr & TA_MPRI) != 0U) { enqueue_msg_pri(&(p_mbxcb->pk_head), pk_msg); ercd = E_OK; } else { pk_msg->pk_next = NULL; if (p_mbxcb->pk_head != NULL) { p_mbxcb->pk_last->pk_next = pk_msg; } else { p_mbxcb->pk_head = pk_msg; } p_mbxcb->pk_last = pk_msg; ercd = E_OK; } t_unlock_cpu(); error_exit: LOG_SND_MBX_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 ref_mbx(ID mbxid, T_RMBX *pk_rmbx) { MBXCB *p_mbxcb; ER ercd; LOG_REF_MBX_ENTER(mbxid, pk_rmbx); CHECK_TSKCTX_UNL(); CHECK_MBXID(mbxid); p_mbxcb = get_mbxcb(mbxid); t_lock_cpu(); pk_rmbx->wtskid = wait_tskid(&(p_mbxcb->wait_queue)); pk_rmbx->pk_msg = p_mbxcb->pk_head; ercd = E_OK; t_unlock_cpu(); error_exit: LOG_REF_MBX_LEAVE(ercd, pk_rmbx); return(ercd); }
/* * Refer mailbox state */ SYSCALL ER _td_ref_mbx( ID mbxid, TD_RMBX *pk_rmbx ) { MBXCB *mbxcb; ER ercd = E_OK; CHECK_MBXID(mbxid); mbxcb = get_mbxcb(mbxid); BEGIN_DISABLE_INTERRUPT; if ( mbxcb->mbxid == 0 ) { ercd = E_NOEXS; } else { pk_rmbx->exinf = mbxcb->exinf; pk_rmbx->wtsk = wait_tskid(&mbxcb->wait_queue); pk_rmbx->pk_msg = headmsg(mbxcb); } END_DISABLE_INTERRUPT; return ercd; }
/* * Refer mailbox state */ SYSCALL ER _tk_ref_mbx( ID mbxid, T_RMBX *pk_rmbx ) { MBXCB *mbxcb; ER ercd = E_OK; CHECK_MBXID(mbxid); mbxcb = get_mbxcb(mbxid); BEGIN_CRITICAL_SECTION; if ( mbxcb->mbxid == 0 ) { ercd = E_NOEXS; } else { pk_rmbx->exinf = mbxcb->exinf; pk_rmbx->wtsk = wait_tskid(&mbxcb->wait_queue); pk_rmbx->pk_msg = headmsg(mbxcb); } 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); }
EXPORT ER mailbox_getname(ID id, UB **name) { MBXCB *mbxcb; ER ercd = E_OK; CHECK_MBXID(id); BEGIN_DISABLE_INTERRUPT; mbxcb = get_mbxcb(id); if ( mbxcb->mbxid == 0 ) { ercd = E_NOEXS; goto error_exit; } if ( (mbxcb->mbxatr & TA_DSNAME) == 0 ) { ercd = E_OBJ; goto error_exit; } *name = mbxcb->name; error_exit: END_DISABLE_INTERRUPT; return ercd; }
/* * Delete mailbox */ SYSCALL ER _tk_del_mbx( ID mbxid ) { MBXCB *mbxcb; ER ercd = E_OK; CHECK_MBXID(mbxid); mbxcb = get_mbxcb(mbxid); BEGIN_CRITICAL_SECTION; if ( mbxcb->mbxid == 0 ) { ercd = E_NOEXS; } else { /* Release wait state of task (E_DLT) */ wait_delete(&mbxcb->wait_queue); /* Return to FreeQue */ QueInsert(&mbxcb->wait_queue, &free_mbxcb); mbxcb->mbxid = 0; } END_CRITICAL_SECTION; return ercd; }