⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 message.c

📁 T-kernel 的extension源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	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 + -