📄 tkpor.c
字号:
/* *---------------------------------------------------------------------- * T-Kernel / Standard Extension * * Copyright (C) 2006 by Ken Sakamura. All rights reserved. * T-Kernel / Standard Extension is distributed * under the T-License for T-Kernel / Standard Extension. *---------------------------------------------------------------------- * * Version: 1.00.00 * Released by T-Engine Forum(http://www.t-engine.org) at 2006/8/11. * *---------------------------------------------------------------------- *//* * tkpor.c (taskcomm) * * T-Kernel compatible rendezvous */#include "tcmgr.h"/* * Generate rendezvous port * T_CPOR * exinf Ignored * poratr TA_NODISWAI cannot be specified * poratr:= (TA_TFIFO || TA_TPRI) | TA_DELEXIT * maxcmsz Up to 4096 bytes * maxrmsz Up to 4096 bytes * * Maximum message size can be changed by * TcBufLim of SYSCONF. */EXPORT ID _tkse_cre_por( T_CPOR *pk_cpor ){ T_CPOR cpor; ID id; ER err; /* Parameter check */ err = ChkSpaceR(pk_cpor, sizeof(T_CPOR)); if ( err < E_OK ) { goto err_ret1; } if ( (pk_cpor->poratr & (TA_DSNAME | TA_NODISWAI) ) != 0U ) { err = E_RSATR; goto err_ret1; } if ( ((err = tcmTkCheckBuffSize(pk_cpor->maxcmsz)) < E_OK ) ||( (err = tcmTkCheckBuffSize(pk_cpor->maxrmsz)) < E_OK )) { goto err_ret1; } cpor = *pk_cpor; if ( (pk_cpor->poratr & (UW)TA_DELEXIT) != 0U ) { cpor.exinf = GetTCinfo(TSK_SELF); cpor.poratr &= ~(UW)TA_DELEXIT; } else { cpor.exinf = NULL; } /* Generate rendezvous port */ id = tk_cre_por(&cpor); if ( id < E_OK ) { err = id; goto err_ret1; } id = toBID(O_POR, id); if (cpor.exinf != NULL) { /* Register ID for deletion at termination. */ err = tcmTkRegistObject(id); if ( err < E_OK ) { goto err_ret2; } } return id;err_ret2: (void)tk_del_por(toIID(id));err_ret1: DEBUG_PRINT(("_tkse_cre_por err = %d\n", err)); return err;}/* * Delete rendezvous port * When rendezvous port generation process terminates, * the rendezvous port is deleted automatically. */EXPORT ER _tkse_del_por( ID id ){ TCINFO *tcinfo; T_RPOR rpor; ER err; /* Check ID */ err = tcmTkCheckID(O_POR, id); if ( err < E_OK ) { goto err_ret; } /* Obtain rendezvous port information. */ err = tk_ref_por(toIID(id), &rpor); if ( err < E_OK ) { goto err_ret; } tcinfo = rpor.exinf; /* Rendezvous port generation process */ /* Delete rendezvous port. */ err = tk_del_por(toIID(id)); if ( err < E_OK ) { goto err_ret; } if ( tcinfo != NULL ) { /* Deregister ID */ err = tcmTkDeleteObject(id, tcinfo); if ( err < E_OK ) { goto err_ret; } } return E_OK;err_ret: DEBUG_PRINT(("_tkse_del_por err = %d\n", err)); return err;}/* * Call rendezvous. * When interrupted by message handler, * wait state is reset and E_DISWAI is returned. */EXPORT INT _tkse_cal_por( ID id, UINT calptn, VP msg, INT cmsz, TMO tmout ){ T_RPOR rpor; VP buf; INT rmsz; W maxsz; ER err; /* Parameter check */ err = tcmTkCheckBuffSize(cmsz); if ( err < E_OK ) { goto err_ret; } /* Check ID */ err = tcmTkCheckID(O_POR, id); if ( err < E_OK ) { goto err_ret; } /* Obtain rendezvous port information. */ err = tk_ref_por(toIID(id), &rpor); if ( err < E_OK ) { goto err_ret; } maxsz = max(cmsz, rpor.maxrmsz); /* Address check */ err = ChkSpaceRW(msg, maxsz); if ( err < E_OK ) { goto err_ret; }#if VIRTUAL_ADDRESS /* In the case of virtual storage, call message is copied on system stack. */ buf = memcpy(alloca((size_t)maxsz), msg, (size_t)cmsz);#else buf = msg;#endif /* Call rendezvous. */ rmsz = tk_cal_por(toIID(id), calptn, buf, cmsz, tmout); if ( rmsz < E_OK ) { err = rmsz; goto err_ret; }#if VIRTUAL_ADDRESS /* Response message is copied from system stack to specified buffer. */ memcpy(msg, buf, (size_t)rmsz);#endif return rmsz;err_ret: DEBUG_PRINT(("_tkse_cal_por err = %d\n", err)); return err;}/* * Receive rendezvous * When interrupted by message handler, * wait state is reset and E_DISWAI is returned. */EXPORT INT _tkse_acp_por( ID id, UINT acpptn, RNO *p_rdvno, VP msg, TMO tmout ){ T_RPOR rpor; VP buf; INT cmsz; RNO rdvno; ER err; /* Check ID */ err = tcmTkCheckID(O_POR, id); if ( err < E_OK ) { goto err_ret; } /* Obtain rendezvous port information. */ err = tk_ref_por(toIID(id), &rpor); if ( err < E_OK ) { goto err_ret; } /* Address check */ if (( (err = ChkSpaceRW(msg, rpor.maxcmsz)) < E_OK ) ||( (err = ChkSpaceRW(p_rdvno, sizeof(RNO))) < E_OK )) { goto err_ret; }#if VIRTUAL_ADDRESS /* In the case of virtual storage, message is received on system stack first. */ buf = alloca((size_t)rpor.maxcmsz);#else buf = msg;#endif /* Receive rendezvous */ cmsz = tk_acp_por(toIID(id), acpptn, &rdvno, buf, tmout); if ( cmsz < E_OK ) { err = cmsz; goto err_ret; }#if VIRTUAL_ADDRESS /* Call message is copied from system stack to specified buffer. */ memcpy(msg, buf, (size_t)cmsz);#endif /* To support virtual storage, rdvno is fetched to system stack first.*/ *p_rdvno = rdvno; return cmsz;err_ret: DEBUG_PRINT(("_tkse_acp_por err = %d\n", err)); return err;}/* * Forward rendezvous */EXPORT ER _tkse_fwd_por( ID id, UINT calptn, RNO rdvno, VP msg, INT cmsz ){ ER err; /* Parameter check */ err = tcmTkCheckBuffSize(cmsz); if ( err < E_OK ) { goto err_ret; } /* Check ID */ err = tcmTkCheckID(O_POR, id); if ( err < E_OK ) { goto err_ret; } /* Address check */ err = ChkSpaceR(msg, cmsz); if ( err < E_OK ) { goto err_ret; }#if VIRTUAL_ADDRESS /* In the case of virtual storage, message is copied on system stack first. */ msg = memcpy(alloca((size_t)cmsz), msg, (size_t)cmsz);#endif /* Forward rendezvous */ err = tk_fwd_por(toIID(id), calptn, rdvno, msg, cmsz); if ( err < E_OK ) { goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("_tkse_fwd_por err = %d\n", err)); return err;}/* * Forward rendezvous */EXPORT ER _tkse_rpl_rdv( RNO rdvno, VP msg, INT rmsz ){ ER err; /* Parameter check */ err = tcmTkCheckBuffSize(rmsz); if ( err < E_OK ) { goto err_ret; } /* Address check */ err = ChkSpaceR(msg, rmsz); if ( err < E_OK ) { goto err_ret; }#if VIRTUAL_ADDRESS /* In the case of virtual storage, message is copied on system stack first. */ msg = memcpy(alloca((size_t)rmsz), msg, (size_t)rmsz);#endif /* Respond to rendezvous */ err = tk_rpl_rdv(rdvno, msg, rmsz); if ( err < E_OK ) { goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("_tkse_rpl_rdv err = %d\n", err)); return err;}/* * Refer to rendezvous port state * T_RPOR * exinf Always return NULL */EXPORT ER _tkse_ref_por( ID id, T_RPOR *pk_rpor ){ T_RPOR rpor; ER err; /* Parameter check */ err = ChkSpaceRW(pk_rpor, sizeof(T_RPOR)); if ( err < E_OK ) { goto err_ret; } /* Check ID */ err = tcmTkCheckID(O_POR, id); if ( err < E_OK ) { goto err_ret; } /* Obtain rendezvous port information. */ err = tk_ref_por(toIID(id), &rpor); if ( err < E_OK ) { goto err_ret; } *pk_rpor = rpor; pk_rpor->exinf = NULL; return E_OK;err_ret: DEBUG_PRINT(("_tkse_ref_por err = %d\n", err)); return err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -