📄 message.c
字号:
er = PidToPinfo(0, &mypi); if (er != 0) { return er; } /* Clear t_mask messages up to immediately before last_mask. */ for (top = &mypi->msg_top, q = top->next; q != top; q = q->next) { tymask = (W)MSGMASK(ME(q)->msg.msg_type); if ((tymask & last_mask) != 0) { break; } if ((tymask & t_mask) == 0) { continue; } /* Clear the message. */ QueRemove(q); prev = q->prev; /* If message is waiting for CNFM, reset wait state of the other party: do not release the area. */ if (ME(q)->cfmtsk != 0) { q->prev = (QUEUE *)NULL; /* Clear queue */ tk_sig_tev(ME(q)->cfmtsk, MSG_TEV); } else { MsgFree(ME(q)); } if (clear_one != 0) { break; } q = prev; } UnlockPinfo(); return E_OK;}/* Message reception wait rest (notification of event occurrence) Note that a task is also called from task-independent sections such as the cyclic handler.*/LOCAL ER _tkse_brk_msg( void ){ UW psw; ID tid; /* As for access of waievt_tid, disable interrupt to perform exclusive control. */ DI(psw); if ( waievt_tid > 0 ) { /* There is a task waiting in WAIEVT. */ tid = waievt_tid; waievt_tid = 0; } else { /* There is no task waiting in WAIEVT. */ tid = 0; waievt_tid = TSD_TBM_WAI_M1; /* Reservation for reset of wait state */ } EI(psw); if ( tid > 0 ) { tk_sig_tev(tid, BRK_TEV); } return E_OK;}/*====================================================================== Message handler processing======================================================================*//* Definitions of message handler*/LOCAL ER _tkse_DefMsgHdr(UW t_mask, FUNCP msg_hdr, FUNCP *hdrs){ PINFO *mypi; ID mtid; ER er; W i; UW m_mask; T_DTEX dtex; /* Parameter check */ if (hdrs &&( CheckSpaceRW(hdrs, sizeof(FUNCP) * TSD_TDM_VAL_31))) { return E_MACV; } if (msg_hdr && ((msg_hdr != MH_NONE )&&( msg_hdr != MH_BREAK )&& (msg_hdr != MH_TERM))&&( CheckSpaceRE((VP)msg_hdr, TSD_TDM_VAL_2))) { return E_MACV; } er = PidToPinfo(0, &mypi); if (er != 0) { return er; } mtid = mypi->tsk[0].tskid; /* Main task ID */ /* Note that t_mask is shifted by one bit from message mask. */ m_mask = t_mask >> 1; if (msg_hdr != 0) { /* Register message handler */ if (t_mask == 1U) { /* Initialization processing */ mypi->fexchdr = (VP)msg_hdr; dtex.texatr = TA_NULL; dtex.texhdr = (FP)msg_hdr; tk_def_tex(mtid, &dtex); } else { /* Normal registration processing */ if (msg_hdr == MH_NONE) { mypi->msg_ignmask |= m_mask; } else { mypi->msg_mhmask |= m_mask; } } tk_ena_tex(mtid, t_mask); /* Permit forced exception */ } else { /* Release message handler */ mypi->msg_ignmask &= ~m_mask; mypi->msg_mhmask &= ~m_mask; tk_dis_tex(mtid, t_mask); /* Prohibit forced exception */ } /* Register in message handler function table: Performed during SVC processing because there is a problem in timing when performed in user process. */ if (hdrs != 0) { for (i = 0; m_mask != 0; m_mask >>= 1, i++) { if ((m_mask & 1U) != 0) { hdrs[i] = msg_hdr; } } } UnlockPinfo(); return er;}/* Return from message handler abort <= 0 Abnormal termination abort = Termination code abort > 0 Terminate message handler abort = 1 Always execute tk_end_tex(). Return value is 0. abort = 2 If there is no message in the message queue, execute tk_end_tex(). If there is a message left in the message queue, return its type as a return value.*/LOCAL WER _tkse_RetMsgHdr(W abort){ QUEUE *top, *q; W t_mask, msgtype; PINFO *mypi; if ( abort <= 0 ) { /* Abnormal termination */ _tkse_abo_prc(0, abort); /* no return */ } mypi = LockGetPinfo(TSK_SELF); msgtype = 0; if ( mypi != NULL ) { /* Check the message queue for a message whose message type is registered by a message handler. */ t_mask = (W)mypi->msg_mhmask; top = &mypi->msg_top; for ( q = top->next; q != top; q = q->next ) { W msgty = ME(q)->msg.msg_type; if ( (MSGMASK(msgty) & (UW)t_mask) == 0 ) { continue; } /* There is a message. */ if ( abort == TSD_TRM_VAL_2 ) { msgtype = msgty; } else { /* Since there is a message, generate a forced exception. */ tk_ras_tex(mypi->tsk[0].tskid, msgty); } break; } } UnlockPinfo(); if ( msgtype == 0 ) { tk_end_tex(TRUE); } return msgtype;}/*====================================================================== Timeout message related======================================================================*//* Timeout message request*/LOCAL ER _tkse_req_tmg(TMOUT tmo, W code){ W pid; BOOL wupreq; TOUTMSG *tmsg; SYSTIM curtim; longlong ctime; QUEUE *q; if (tmo <= 0) { return E_PAR; } pid = GetMyPid(); if (pid < 0) { return pid; } /* Generate timeout message entry */ tmsg = (TOUTMSG*)MsgAlloc(sizeof(W), TRUE); if (!(tmsg )) { return E_SYSMEM; } tmsg->pid = pid; tmsg->code = code; tmsg->cfmtsk = 0; tk_get_otm(&curtim); hilo_ll(ctime, curtim.hi, curtim.lo); tmsg->e.time = ctime = ll_add(ctime, ltoll(tmo)); /* Absolute time */ Lock(&ToutMsgLock); /* Connect messages to the timeout message queue in order of send time. */ for (q = ToutMsgQue.next; q != &ToutMsgQue; q = q->next) { if (ll_cmp(TME(q)->e.time, ctime) >= 0) { break; } } QueInsert((QUEUE*)tmsg, q); /* If a message is placed in the start of the queue, perform wup of the processing task. */ wupreq = (ToutMsgQue.next == (QUEUE*)tmsg); Unlock(&ToutMsgLock); if (wupreq != 0) { tk_wup_tsk(ToutMsgTskId); } return E_OK;}/* Cancel timeout message (internal processing)*/LOCAL void CancelToutMsg(W pid){ QUEUE *q; TOUTMSG *tmsg; Lock(&ToutMsgLock); /* Remove from timeout message queue */ for (q = &ToutMsgQue; ; ) { q = QueSearch(q, &ToutMsgQue, pid, (W)offsetof(TOUTMSG, pid)); if (q == &ToutMsgQue) { break; } tmsg = TME(q); q = q->prev; QueRemove(&tmsg->q); tmsg->e.m.msg_size = sizeof(W); MsgFree(ME(tmsg)); } Unlock(&ToutMsgLock);}/* Cancel timeout message*/LOCAL ER _tkse_can_tmg(void){ W pid; pid = GetMyPid(); if (pid < 0) { return pid; } CancelToutMsg(pid); return E_OK;}/* Timeout message processing task*/LOCAL void TimeOutMsgTask( void ){ QUEUE *q; TMO tmout; SYSTIM curtim; longlong ctime; for (tmout = TMO_FEVR; ; ) { /* Wait for next message send time or until wup is performed. */ tk_slp_tsk(tmout); /* Send messages that reach their send time. */ for (;;) { Lock(&ToutMsgLock); q = ToutMsgQue.next; if (q == &ToutMsgQue) { /* Empty */ tmout = TMO_FEVR; } else { tk_get_otm(&curtim); hilo_ll(ctime, curtim.hi, curtim.lo); if (ll_cmp(TME(q)->e.time, ctime) > 0) { tmout = lltol(ll_sub(TME(q)->e.time, ctime)); } else { QueRemove(q); tmout = 0; } } Unlock(&ToutMsgLock); if (tmout != 0) { break; /* No corresponding message */ } /* Send message */ TME(q)->e.m.msg_type = MS_TMOUT; TME(q)->e.m.msg_size = sizeof(W); _tkse_snd_msg(TME(q)->pid, (MESSAGE*)q, WAIT, MS_TMOUT); } }}/* Initialization related to timeout messages*/LOCAL void InitToutMsg( void ){ T_CTSK ctsk; /* Generate lock for timeout message queue */ (void)CreateLock(&ToutMsgLock, (UB*)"TMsg"); /* Initialize timeout message queue */ QueInit(&ToutMsgQue); /* Generate/start timeout message processing task */ SetOBJNAME(ctsk.exinf, "TMsg"); ctsk.tskatr = TA_HLNG|TA_RNG0; ctsk.task = TimeOutMsgTask; ctsk.itskpri = TSD_ITM_ITS_137; ctsk.stksz = TSD_ITM_STK_512; ToutMsgTskId = tk_cre_tsk(&ctsk); if (ToutMsgTskId < 0) { SYSLOG((LOG_ERR, "Can\'t Create TOM-TASK : %d", ToutMsgTskId)); } tk_sta_tsk(ToutMsgTskId, 0);}/*====================================================================== SVC entry related======================================================================*//* Message SVC entry*/#define FNO(n) ( (UW)(n) >> 16 )LOCAL WER MsgSVCentry(VP para, W fn){ ER er; switch ( FNO(fn) ) { case TSD_MSE_CAS_1: { MSG_SND_MSG_PARA *p = para; er = (p->pid == MSGHDR_PID) ? _snd_hdr_msg(p->msg, p->opt) : _tkse_snd_msg(p->pid, p->msg, p->opt, 0); return (er < 0) ? er : E_OK; } case TSD_MSE_CAS_2: { MSG_RCV_MSG_PARA *p = para; return _tkse_rcv_msg(p->t_mask, p->msg, p->msgsz, p->opt); } case TSD_MSE_CAS_3: { return E_RSFN; } case TSD_MSE_CAS_4: { MSG_CLR_MSG_PARA *p = para; return _tkse_clr_msg(p->t_mask, p->last_mask); } case TSD_MSE_CAS_5: { MSG_DEFMSGHDR_PARA *p = para; return _tkse_DefMsgHdr((UW)p->t_mask, p->msg_hdr, p->hdrs); } case TSD_MSE_CAS_6: { MSG_RETMSGHDR_PARA *p = para; return _tkse_RetMsgHdr(p->abort); } case TSD_MSE_CAS_7: { MSG_REQ_TMG_PARA *p = para; return _tkse_req_tmg(p->tmo, p->code); } case TSD_MSE_CAS_8: { return _tkse_can_tmg(); } case TSD_MSE_CAS_9: { return _tkse_brk_msg(); } default: { return E_RSFN; } }}/* Termination processing of message process*/LOCAL void MsgCleanUp(ID resid, W pid){ PINFO *pinfo; QUEUE *q, *top; if ( GetPidToPinfo(pid, &pinfo) < E_OK ) { return; } /* Delete all of received messages to release the area. In the case of CFNM wait, use tk_rel_wai() to forcedly reset wait state. */ LockPinfo(); for (top = &pinfo->msg_top; (q = top->next) != top; ) { QueRemove(q); if (ME(q)->cfmtsk != 0) { q->prev = (QUEUE *)NULL; /* Clear queue */ tk_rel_wai(ME(q)->cfmtsk); } else { MsgFree(ME(q)); } } /* Nothing has to be done for send messages. In the case of CFNM wait, wait state has been reset by EV_DISWAI. */ /* Cancel timeout message */ CancelToutMsg(pinfo->procid); /* Prohibit message sending */ pinfo->msg_ignmask = MM_NOPRC|MM_ALL; UnlockPinfo();}/* Startup processing of message process*/LOCAL void MsgStartUp(ID resid, W pid){ PINFO *pinfo; W i; if ( GetPidToPinfo(pid, &pinfo) < E_OK ) { return; } /* Initialize message information */ pinfo->msg_ignmask = 0; pinfo->msg_mhmask = 0; for (i = 0; i < MAX_SUBTASKS; i++) { pinfo->tsk[i].msg_waimask = 0; } QueInit(&pinfo->msg_top);}/* Message break processing*/LOCAL void MsgBreak(ID taskid){ tk_dis_wai(taskid, TTW_EV1);}/*====================================================================== Initialization related======================================================================*//* Message manager initialization function*/EXPORT ER MessageMgr( INT ac, UB *av[] ){ T_CFLG cflg; T_DSSY dssy; W v[L_SYSCONF_VAL]; ER err; if ( ac < 0 ) { return E_OK; /* Omit termination processing */ } /* Initialization processing */ /* Obtain definitions of task event allocation */ if ( GetSysConf((UB*)"TEV_MsgEvt", v) < 1 ) { return E_SYS; } MSG_TEV = v[0]; if ( GetSysConf((UB*)"TEV_MsgBrk", v) < 1 ) { return E_SYS; } BRK_TEV = v[0]; /* Fetch maximum size of message memory area. */ if ( GetSysConf((UB*)"TotalMsgMax", v) < 1 ) { return E_SYS; } TOTAL_MSGMAX = v[0]; /* Fetch maximum size of individual message. */ if ( GetSysConf((UB*)"MaxMsgSz", v) < 1 ) { return E_SYS; } MAX_MSGSZ = v[0]; /* Generate wait flag for obtaining message memory area. */ SetOBJNAME(cflg.exinf, "Msg"); cflg.flgatr = TA_TFIFO | TA_WMUL; cflg.iflgptn = 0; MsgAllocFlg = err = tk_cre_flg(&cflg); if ( err < E_OK ) { SYSLOG((LOG_ERR, "** Can\'t Create MsgAllocFlg")); return err; } /* Initialization related to timeout messages */ InitToutMsg(); /* Register the manager. */ dssy.ssyatr = TA_NULL; dssy.ssypri = MSG_PRI; dssy.svchdr = (FP)MsgSVCentry; dssy.breakfn = MsgBreak; dssy.startupfn = MsgStartUp; dssy.cleanupfn = MsgCleanUp; dssy.eventfn = NULL; dssy.resblksz = 0; err = tk_def_ssy(MSG_SVC, &dssy); if ( err < E_OK ) { return err; } return E_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -