📄 main.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. * *---------------------------------------------------------------------- *//* * main.c (taskcomm) * * Inter-task synchronous communication management */#include "tcmgr.h"#include <sys/pinfo.h>#define OLD_SPEC_SEM 0 /* When old semaphore specification is used: 1 */EXPORT FastLock tcmLock; /* Exclusive control lock */LOCAL W BuffLimit; /* Buffer size upper limit (number of bytes) */#define TSD_SER_RTN_M1 (-1)/* * Object registration list */typedef struct { W nslot; /* Number of id slots */ ID id[1]; /* ID lists (variable number) */} ObjectList;LOCAL W search_slot( ObjectList *p, ID id );LOCAL void tcmCleanupEntry( ID resid, ID pid );LOCAL void tcmBreakEntry( ID tskid );LOCAL WER tcmSyscallEntry( VP para, W fn );LOCAL ER initialize( void );LOCAL ER finish( void );/* * Check object ID */EXPORT ER tcmTkCheckID( ObjectType type, ID id ){ PINFO *pinfo = GetPinfo(TSK_SELF); ObjectType t = (ObjectType)((UW)id & (UW)O_Mask); return ( (t == type) || ((pinfo->sysproc == 1) && (t == 0)) )? E_OK: E_ID;}/* * Check buffer size limit */EXPORT ER tcmTkCheckBuffSize( W sz ){ if ( sz <= 0 ) { return E_PAR; } if ( sz > BuffLimit ) { return E_LIMIT; } return E_OK;}/* ------------------------------------------------------------------------ */#define OL_SZ(n) ( sizeof(W) + ((UW)(n) * sizeof(ID)) )#define OL_ADD 5 /* Extension steps of registration list (number of lists) *//* * Search for ID slot */LOCAL W search_slot( ObjectList *p, ID id ){ W i; if ( p == NULL ) { return TSD_SER_RTN_M1; } i = p->nslot; while ( --i >= 0 ) { if ( p->id[i] == id ) { break; } } return i;}/* * Register object in process-related information * Register in TCINFO of current process */EXPORT ER tcmTkRegistObject( ID id ){ TCINFO *tcinfo; ObjectList *p; W i; ER err; LockTCM(); tcinfo = GetTCinfo(TSK_SELF); if ( tcinfo == NULL ) { err = E_CTX; goto err_ret; } /* Search for empty slot */ p = tcinfo->tcobj; i = search_slot(p, 0); if ( i < 0 ) { /* Extend object list */ i = ( p == NULL )? 0: p->nslot; p = Vrealloc(p, (size_t)(OL_SZ(i + OL_ADD))); if ( p == NULL ) { err = E_NOMEM; goto err_ret; } p->nslot = i + OL_ADD; memset(&p->id[i], 0, (size_t)((UW)OL_ADD * sizeof(ID))); tcinfo->tcobj = p; } /* Register */ p->id[i] = id; UnlockTCM(); return E_OK;err_ret: UnlockTCM(); DEBUG_PRINT(("tcmTkRegistObject err = %d\n", err)); return err;}/* * Deregister object from process-related information (TCINFO) * Deregister from tcinfo process. * Object is not always deleted by registration process. */EXPORT ER tcmTkDeleteObject( ID id, TCINFO *tcinfo ){ ObjectList *p; W i; LockTCM(); /* Search for id slot */ p = tcinfo->tcobj; i = search_slot(p, id); if ( i >= 0 ) { /* Deregister */ p->id[i] = 0; } UnlockTCM(); return E_OK;}/* * Search object from process-related information (TCINFO) * Search from tcinfo process. */EXPORT ER tcmTkSearchObject( ID id, TCINFO *tcinfo ){ ER err; ObjectList *p; W i; LockTCM(); /* Search for id slot */ p = tcinfo->tcobj; i = search_slot(p, id); if ( i >= 0 ) { err = E_OK; } else { err = E_NOEXS; } UnlockTCM(); return err;}/* ------------------------------------------------------------------------ *//* * Cleanup entry */LOCAL void tcmCleanupEntry( ID resid, ID pid ){ TCINFO *tcinfo; ObjectList *p; ID id; W i; if ( tk_get_res(resid, TCM_SVC, (VP*)&tcinfo) < E_OK ) { return; } p = tcinfo->tcobj; if ( p == NULL ) { return; } LockTCM(); /* Delete object */ i = p->nslot; while ( --i >= 0 ) { id = toIID(p->id[i]); switch ( p->id[i] & O_Mask ) { case O_SEM: tk_del_sem(id); break; case O_FLG: tk_del_flg(id); break; case O_MBF: tk_del_mbf(id); break; case O_POR: tk_del_por(id); break; case O_MTX: tk_del_mtx(id); break; case O_MBX: tk_del_mbx(id); break; default: /* nothing to do */ break; } } tcinfo->tcobj = NULL; Vfree(p); UnlockTCM();}/* * Break entry */LOCAL void tcmBreakEntry( ID tskid ){static const UW waiptn = TTW_SEM | TTW_MTX | TTW_FLG | TTW_MBX | TTW_RMBF | TTW_SMBF | TTW_CAL | TTW_ACP | TTW_RDV; tk_dis_wai(tskid, waiptn);}/* * Extended SVC entry */LOCAL WER tcmSyscallEntry( VP para, W fn ){ switch ( fn ) { /* T-Kernel compatible semaphore */ case TCM_CRE_SEM_FN: { TCM_CRE_SEM_PARA *p = para; return _tkse_cre_sem(p->pk_csem); } case TCM_DEL_SEM_FN: { TCM_DEL_SEM_PARA *p = para; return _tkse_del_sem(p->semid); } case TCM_SIG_SEM_FN: { TCM_SIG_SEM_PARA *p = para; return _tkse_sig_sem(p->semid, p->cnt); } case TCM_WAI_SEM_FN: { TCM_WAI_SEM_PARA *p = para; return _tkse_wai_sem(p->semid, p->cnt, p->tmout); } case TCM_REF_SEM_FN: { TCM_REF_SEM_PARA *p = para; return _tkse_ref_sem(p->semid, p->pk_rsem); } /* T-Kernel compatible mutex */ case TCM_CRE_MTX_FN: { TCM_CRE_MTX_PARA *p = para; return _tkse_cre_mtx(p->pk_cmtx); } case TCM_DEL_MTX_FN: { TCM_DEL_MTX_PARA *p = para; return _tkse_del_mtx(p->mtxid); } case TCM_LOC_MTX_FN: { TCM_LOC_MTX_PARA *p = para; return _tkse_loc_mtx(p->mtxid, p->tmout); } case TCM_UNL_MTX_FN: { TCM_UNL_MTX_PARA *p = para; return _tkse_unl_mtx(p->mtxid); } case TCM_REF_MTX_FN: { TCM_REF_MTX_PARA *p = para; return _tkse_ref_mtx(p->mtxid, p->pk_rmtx); } /* T-Kernel compatible event flag */ case TCM_CRE_FLG_FN: { TCM_CRE_FLG_PARA *p = para; return _tkse_cre_flg(p->pk_cflg); } case TCM_DEL_FLG_FN: { TCM_DEL_FLG_PARA *p = para; return _tkse_del_flg(p->flgid); } case TCM_SET_FLG_FN: { TCM_SET_FLG_PARA *p = para; return _tkse_set_flg(p->flgid, p->setptn); } case TCM_CLR_FLG_FN: { TCM_CLR_FLG_PARA *p = para; return _tkse_clr_flg(p->flgid, p->clrptn); } case TCM_WAI_FLG_FN: { TCM_WAI_FLG_PARA *p = para; return _tkse_wai_flg(p->flgid, p->waiptn, p->wfmode, p->p_flgptn, p->tmout); } case TCM_REF_FLG_FN: { TCM_REF_FLG_PARA *p = para; return _tkse_ref_flg(p->flgid, p->pk_rflg); } /* T-Kernel compatible message buffer */ case TCM_CRE_MBF_FN: { TCM_CRE_MBF_PARA *p = para; return _tkse_cre_mbf(p->pk_cmbf); } case TCM_DEL_MBF_FN: { TCM_DEL_MBF_PARA *p = para; return _tkse_del_mbf(p->mbfid); } case TCM_SND_MBF_FN: { TCM_SND_MBF_PARA *p = para; return _tkse_snd_mbf(p->mbfid, p->msg, p->msgsz, p->tmout); } case TCM_RCV_MBF_FN: { TCM_RCV_MBF_PARA *p = para; return _tkse_rcv_mbf(p->mbfid, p->msg, p->tmout); } case TCM_REF_MBF_FN: { TCM_REF_MBF_PARA *p = para; return _tkse_ref_mbf(p->mbfid, p->pk_rmbf); } /* T-Kernel compatible rendezvous */ case TCM_CRE_POR_FN: { TCM_CRE_POR_PARA *p = para; return _tkse_cre_por(p->pk_cpor); } case TCM_DEL_POR_FN: { TCM_DEL_POR_PARA *p = para; return _tkse_del_por(p->porid); } case TCM_CAL_POR_FN: { TCM_CAL_POR_PARA *p = para; return _tkse_cal_por(p->porid, p->calptn, p->msg, p->cmsgsz, p->tmout); } case TCM_ACP_POR_FN: { TCM_ACP_POR_PARA *p = para; return _tkse_acp_por(p->porid, p->acpptn, p->p_rdvno, p->msg, p->tmout); } case TCM_FWD_POR_FN: { TCM_FWD_POR_PARA *p = para; return _tkse_fwd_por(p->porid, p->calptn, p->rdvno, p->msg, p->cmsgsz); } case TCM_RPL_RDV_FN: { TCM_RPL_RDV_PARA *p = para; return _tkse_rpl_rdv(p->rdvno, p->msg, p->rmsgsz); } case TCM_REF_POR_FN: { TCM_REF_POR_PARA *p = para; return _tkse_ref_por(p->porid, p->pk_rpor); } /* T-Kernel compatible mail box */ case TCM_CRE_MBX_FN: { TCM_CRE_MBX_PARA *p = para; return _tkse_cre_mbx(p->pk_cmbx); } case TCM_DEL_MBX_FN: { TCM_DEL_MBX_PARA *p = para; return _tkse_del_mbx(p->mbxid); } case TCM_SND_MBX_FN: { TCM_SND_MBX_PARA *p = para; return _tkse_snd_mbx(p->mbxid, p->msg ); } case TCM_RCV_MBX_FN: { TCM_RCV_MBX_PARA *p = para; return _tkse_rcv_mbx(p->mbxid, p->msg, p->tmout); } case TCM_REF_MBX_FN: { TCM_REF_MBX_PARA *p = para; return _tkse_ref_mbx(p->mbxid, p->pk_rmbx); } default: { /* nothing to do */ break; } } return E_RSFN;}/* ------------------------------------------------------------------------ *//* * Initialization processing */LOCAL ER initialize( void ){ T_DSSY dssy; W n, w[L_SYSCONF_VAL]; ER err; /* Obtain buffer size upper limit */ n = GetSysConf((UB*)"TcBufLim", w); if ( n != 1 ) { err = E_SYS; goto err_ret; } BuffLimit = w[0]; /* Generate exclusive control lock */ err = CreateLock(&tcmLock, (UB*)"TC"); if ( err < E_OK ) { goto err_ret; } /* Register the manager. */ dssy.ssyatr = TA_NULL; dssy.ssypri = TCM_PRI; dssy.svchdr = (FP)tcmSyscallEntry; dssy.breakfn = tcmBreakEntry; dssy.startupfn = NULL; dssy.cleanupfn = tcmCleanupEntry; dssy.eventfn = NULL; dssy.resblksz = sizeof(TCINFO); err = tk_def_ssy(TCM_SVC, &dssy); if ( err < E_OK ) { goto err_ret; } return E_OK;err_ret: DEBUG_PRINT(("initialize err = %d\n", err)); return err;}/* * Termination processing */LOCAL ER finish( void ){ ER err, error = E_OK; /* Deregister the manager. */ err = tk_def_ssy(TCM_SVC, NULL); if ( err < E_OK ) { error = err; } /* Delete exclusive control lock */ DeleteLock(&tcmLock); if ( error < E_OK ) { DEBUG_PRINT(("finish err = %d\n", error)); } return error;}/* * Initialization/termination processing of inter-task synchronous communication management */EXPORT ER TaskCommMgr( INT ac, UB *av[] ){ ER err; if ( ac >= 0 ) { /* Initialization */ err = initialize(); if ( err < E_OK ) { (void)finish(); } } else { /* Termination processing */ err = finish(); } return err;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -