/* * Refer message buffer receive wait queue */ SYSCALL INT _td_rmbf_que( ID mbfid, ID list[], INT nent ) { MBFCB *mbfcb; QUEUE *q; ER ercd = E_OK; CHECK_MBFID(mbfid); mbfcb = get_mbfcb(mbfid); BEGIN_DISABLE_INTERRUPT; if ( mbfcb->mbfid == 0 ) { ercd = E_NOEXS; } else { INT n = 0; for ( q = mbfcb->recv_queue.next; q != &mbfcb->recv_queue; q = q->next ) { if ( n++ < nent ) { *list++ = ((TCB*)q)->tskid; } } ercd = n; } END_DISABLE_INTERRUPT; return ercd; }
ER ini_mbf(ID mbfid) { MBFCB *p_mbfcb; bool_t dspreq; ER ercd; LOG_INI_MBF_ENTER(mbfid); CHECK_TSKCTX_UNL(); CHECK_MBFID(mbfid); p_mbfcb = get_mbfcb(mbfid); t_lock_cpu(); dspreq = init_wait_queue(&(p_mbfcb->swait_queue)); if (init_wait_queue(&(p_mbfcb->rwait_queue))) { dspreq = true; } p_mbfcb->fmbfsz = p_mbfcb->p_mbfinib->mbfsz; p_mbfcb->head = 0U; p_mbfcb->tail = 0U; p_mbfcb->smbfcnt = 0U; if (dspreq) { dispatch(); } ercd = E_OK; t_unlock_cpu(); error_exit: LOG_INI_MBF_LEAVE(ercd); return(ercd); }
/* * Refer message buffer state */ SYSCALL ER _td_ref_mbf( ID mbfid, TD_RMBF *pk_rmbf ) { MBFCB *mbfcb; TCB *tcb; ER ercd = E_OK; CHECK_MBFID(mbfid); mbfcb = get_mbfcb(mbfid); BEGIN_DISABLE_INTERRUPT; if ( mbfcb->mbfid == 0 ) { ercd = E_NOEXS; } else { pk_rmbf->exinf = mbfcb->exinf; pk_rmbf->wtsk = wait_tskid(&mbfcb->recv_queue); pk_rmbf->stsk = wait_tskid(&mbfcb->send_queue); if ( !mbf_empty(mbfcb) ) { pk_rmbf->msgsz = *(HEADER*)&mbfcb->buffer[mbfcb->head]; } else { if ( !isQueEmpty(&mbfcb->send_queue) ) { tcb = (TCB*)mbfcb->send_queue.next; pk_rmbf->msgsz = tcb->winfo.smbf.msgsz; } else { pk_rmbf->msgsz = 0; } } pk_rmbf->frbufsz = mbfcb->frbufsz; pk_rmbf->maxmsz = mbfcb->maxmsz; } END_DISABLE_INTERRUPT; return ercd; }
/* * Delete message buffer */ SYSCALL ER _tk_del_mbf( ID mbfid ) { MBFCB *mbfcb; VB *msgbuf = NULL; ER ercd = E_OK; CHECK_MBFID(mbfid); mbfcb = get_mbfcb(mbfid); BEGIN_CRITICAL_SECTION; if ( mbfcb->mbfid == 0 ) { ercd = E_NOEXS; } else { msgbuf = mbfcb->buffer; /* Release wait state of task (E_DLT) */ wait_delete(&mbfcb->recv_queue); wait_delete(&mbfcb->send_queue); /* Return to FreeQue */ QueInsert(&mbfcb->send_queue, &free_mbfcb); mbfcb->mbfid = 0; } END_CRITICAL_SECTION; if ( msgbuf != NULL ) { Ifree(msgbuf); } return ercd; }
ER prcv_mbf(ID mbfid, void *msg) { MBFCB *p_mbfcb; uint_t msgsz; bool_t dspreq; ER_UINT ercd; LOG_PRCV_MBF_ENTER(mbfid, msg); CHECK_TSKCTX_UNL(); 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 { ercd = E_TMOUT; } t_unlock_cpu(); error_exit: LOG_PRCV_MBF_LEAVE(ercd, msg); return(ercd); }
ER psnd_mbf(ID mbfid, const void *msg, uint_t msgsz) { MBFCB *p_mbfcb; bool_t dspreq; ER ercd; LOG_PSND_MBF_ENTER(mbfid, msg, msgsz); CHECK_TSKCTX_UNL(); CHECK_MBFID(mbfid); p_mbfcb = get_mbfcb(mbfid); CHECK_PAR(0 < msgsz && msgsz <= p_mbfcb->p_mbfinib->maxmsz); t_lock_cpu(); if (send_message(p_mbfcb, msg, msgsz, &dspreq)) { if (dspreq) { dispatch(); } ercd = E_OK; } else { ercd = E_TMOUT; } t_unlock_cpu(); error_exit: LOG_PSND_MBF_LEAVE(ercd); return(ercd); }
ER snd_mbf(ID mbfid, const void *msg, uint_t msgsz) { MBFCB *p_mbfcb; WINFO_MBF winfo_mbf; bool_t dspreq; ER ercd; LOG_SND_MBF_ENTER(mbfid, msg, msgsz); CHECK_DISPATCH(); CHECK_MBFID(mbfid); p_mbfcb = get_mbfcb(mbfid); CHECK_PAR(0 < msgsz && msgsz <= p_mbfcb->p_mbfinib->maxmsz); t_lock_cpu(); if (send_message(p_mbfcb, msg, msgsz, &dspreq)) { if (dspreq) { dispatch(); } ercd = E_OK; } else { winfo_mbf.msg = (void *) msg; winfo_mbf.msgsz = msgsz; p_runtsk->tstat = (TS_WAITING | TS_WAIT_SMBF); wobj_make_wait((WOBJCB *) p_mbfcb, (WINFO_WOBJ *) &winfo_mbf); dispatch(); ercd = winfo_mbf.winfo.wercd; } t_unlock_cpu(); error_exit: LOG_SND_MBF_LEAVE(ercd); 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_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); }
ER ref_mbf(ID mbfid, T_RMBF *pk_rmbf) { MBFCB *p_mbfcb; ER ercd; LOG_REF_MBF_ENTER(mbfid, pk_rmbf); CHECK_TSKCTX_UNL(); CHECK_MBFID(mbfid); p_mbfcb = get_mbfcb(mbfid); t_lock_cpu(); pk_rmbf->stskid = wait_tskid(&(p_mbfcb->swait_queue)); pk_rmbf->rtskid = wait_tskid(&(p_mbfcb->rwait_queue)); pk_rmbf->smbfcnt = p_mbfcb->smbfcnt; pk_rmbf->fmbfsz = p_mbfcb->fmbfsz; ercd = E_OK; t_unlock_cpu(); error_exit: LOG_REF_MBF_LEAVE(ercd, pk_rmbf); return(ercd); }
EXPORT ER messagebuffer_getname(ID id, UB **name) { MBFCB *mbfcb; ER ercd = E_OK; CHECK_MBFID(id); BEGIN_DISABLE_INTERRUPT; mbfcb = get_mbfcb(id); if ( mbfcb->mbfid == 0 ) { ercd = E_NOEXS; goto error_exit; } if ( (mbfcb->mbfatr & TA_DSNAME) == 0 ) { ercd = E_OBJ; goto error_exit; } *name = mbfcb->name; error_exit: END_DISABLE_INTERRUPT; return ercd; }
SYSCALL ER _tk_snd_mbf_u( ID mbfid, CONST void *msg, INT msgsz, TMO_U tmout ) { MBFCB *mbfcb; TCB *tcb; ER ercd = E_OK; CHECK_MBFID(mbfid); CHECK_PAR(msgsz > 0); CHECK_TMOUT(tmout); CHECK_DISPATCH_POL(tmout); mbfcb = get_mbfcb(mbfid); BEGIN_CRITICAL_SECTION; if ( mbfcb->mbfid == 0 ) { ercd = E_NOEXS; goto error_exit; } #if CHK_PAR if ( msgsz > mbfcb->maxmsz ) { ercd = E_PAR; goto error_exit; } #endif /* Check send wait disable */ if ( !in_indp() && is_diswai((GCB*)mbfcb, ctxtsk, TTW_SMBF) ) { ercd = E_DISWAI; goto error_exit; } if ( !isQueEmpty(&mbfcb->recv_queue) ) { /* Send directly to the receive wait task */ tcb = (TCB*)mbfcb->recv_queue.next; memcpy(tcb->winfo.rmbf.msg, msg, (UINT)msgsz); *tcb->winfo.rmbf.p_msgsz = msgsz; wait_release_ok(tcb); } else if ( (in_indp() || gcb_top_of_wait_queue((GCB*)mbfcb, ctxtsk) == ctxtsk) &&(mbf_free(mbfcb, msgsz)) ) { /* Store the message to message buffer */ msg_to_mbf(mbfcb, msg, msgsz); } else { ercd = E_TMOUT; if ( tmout != TMO_POL ) { /* Ready for send wait */ ctxtsk->wspec = ( (mbfcb->mbfatr & TA_TPRI) != 0 )? &wspec_smbf_tpri: &wspec_smbf_tfifo; ctxtsk->wercd = &ercd; ctxtsk->winfo.smbf.msg = msg; ctxtsk->winfo.smbf.msgsz = msgsz; gcb_make_wait_with_diswai((GCB*)mbfcb, tmout); } } error_exit: END_CRITICAL_SECTION; return ercd; }