📄 tm.c
字号:
/*----------------------------------------------------------------------------*//* A "hybrid/combination" TM implementation! *//* Author(s): Kalyan Perumalla <www.cc.gatech.edu/~kalyan> 26Nov2003 *//* $Revision: 1.20 $ $Name: v26apr05 $ $Date: 2005/02/03 14:56:23 $ *//*----------------------------------------------------------------------------*/#include <stdlib.h>#include <string.h>#include <stdio.h>#include "mycompat.h"#include "fm.h"#include "tm.h"/*----------------------------------------------------------------------------*/typedef struct{ TM_Time LBTS; /*Most recently known value*/ TM_TimeQual qual; /*Qualification of recent LBTS; see TM_TimeQual*/ long epoch_id; /*Epoch number corresponding to recent LBTS*/ int modindex; /*Which module delivered this recent LBTS value?*/ TM_Time rep_ts; /*What min ts this PE supplied most recently?*/ TM_TimeQual rep_qual; /*What min qual this PE supplied most recently?*/ TM_LBTSStartedProc sproc;/*Callback for getting this PE's snap shot value*/ TM_LBTSDoneProc *dproc; /*List of callbacks waiting for new LBTS value*/ int max_dproc; /*Limit on #callbacks that can wait for new LBTS*/ int n_dproc; /*Actual #callbacks waiting for new LBTS*/} TMLBTSInfo;/*----------------------------------------------------------------------------*/typedef struct{ long nlbts; /*Total number of LBTS computations so far*/ TIMER_TYPE start; /*When did TM_Init() end?*/} TMStatistics;/*----------------------------------------------------------------------------*/typedef struct _TMModuleStateStruct{ TMModule cl; /*Module metaclass info*/ int index; /*Index of this module into array of modules*/ int inited; /*Has this module been initialized?*/ long nwins; /*#times this module advanced time before others*/ struct _TMModuleStateStruct* next; /*Next in linked list of modules*/} TMModuleState;/*----------------------------------------------------------------------------*/typedef struct{ int nmods; /*Number of TM modules registered*/ int maxmods; /*Current limit on #modules; expanded as needed*/ int activemod; /*Which module is being ticked currently*/ TMModuleState *mods; /*Array of registered modules*/} TMModuleList;/*----------------------------------------------------------------------------*/typedef struct{ int debug; /*Debugging level*/ int myid; /*My processor ID*/ int N; /*Total number of processors*/ TMLBTSInfo lbts; /*How LBTS values must be acquired/stored/reported*/ TMModuleList modlist; /*List of TM sub-modules*/ TMStatistics stats; /*Self-explanatory*/} TMState;/*----------------------------------------------------------------------------*//* Global TM state, and cached pointers into the global TM state *//* In multi-threaded implementation, pass TM state as argument to API calls, *//* and move the cached pointers into the functions (as local variables). *//*----------------------------------------------------------------------------*/static TMState tm_state, *st;static TMLBTSInfo *lbts;static TMModuleList *modlist;static TMStatistics *stats;static char tmp_str[1000];/*Scratch to hold timestamp->string conversion*//*----------------------------------------------------------------------------*/void TM_AddModule( TMModule *mod ){ if( modlist->nmods >= modlist->maxmods ) { void *p = modlist->mods; int n = (modlist->maxmods += 10)*sizeof(TMModuleState); modlist->mods = (TMModuleState*) (p ? realloc(p,n) : malloc(n)); MYASSERT( modlist->mods, ("!") ); } MYASSERT( modlist->nmods < modlist->maxmods, ("!") ); { int i = modlist->nmods++; TMModuleState *lmod = &modlist->mods[i]; lmod->cl = *mod; lmod->index = i; lmod->inited = FALSE; lmod->nwins = 0; lmod->next = 0; if( i > 0 ) (lmod-1)->next = lmod; }}/*----------------------------------------------------------------------------*/static void TM_AddDoneProc( TM_LBTSDoneProc dproc ){ if( dproc ) { MYASSERT( lbts->n_dproc < lbts->max_dproc, ("!") ); lbts->dproc[lbts->n_dproc++] = dproc; }}/*----------------------------------------------------------------------------*/static void TM_InitMod( TMModuleState *mod );/*----------------------------------------------------------------------------*/static void TM_LBTSDone( TM_Time new_lbts, TM_TimeQual new_qual, long epoch_id ){ TMModuleState *amod = &modlist->mods[modlist->activemod];if(st->debug>0){printf("TM_LBTSDone(LBTS=%s, qual=%s) epoch=%ld activemod=%d nwins=%ld\n",TM_STR(tmp_str,new_lbts), TM_TIME_QUAL_STR(new_qual), lbts->epoch_id, modlist->activemod, amod->nwins);fflush(stdout);} if( TM_GT(new_lbts, lbts->LBTS) || (TM_EQ(new_lbts, lbts->LBTS) && new_qual > lbts->qual) ) { lbts->LBTS = new_lbts; lbts->qual = new_qual; lbts->modindex = modlist->activemod; amod->nwins++;if(st->debug>1)printf("** WIN **\n"); /*Inform other TM modules of this new value*/ { TMModuleState *mod = modlist->mods; while( mod ) { if(mod != amod) { if(!mod->inited)TM_InitMod( mod ); mod->cl.newlbts(mod->cl.closure, lbts->LBTS, lbts->qual); } mod = mod->next; } } } /*Inform all the waiting dprocs*/ { int c; for( c = 0; c < lbts->n_dproc; c++ ) { lbts->dproc[c]( lbts->LBTS, lbts->qual, lbts->epoch_id ); } lbts->n_dproc = 0; lbts->epoch_id++; }if(st->debug>3)TM_PrintState();}/*----------------------------------------------------------------------------*/static long TM_LBTSStarted( long epoch_id, TM_Time *min_ts, TM_TimeQual *qual, TM_LBTSDoneProc *dproc ){ long sproc_flag = TM_ACCEPT; if( lbts->n_dproc > 0 ) { *min_ts = lbts->rep_ts; *qual = lbts->rep_qual; *dproc = &TM_LBTSDone; } else { MYASSERT( lbts->sproc, ("!") ); sproc_flag = lbts->sproc( lbts->epoch_id, min_ts, qual, dproc ); if(sproc_flag == TM_DEFER) { *min_ts = lbts->LBTS; *qual = lbts->qual; } else {if( *dproc ) { TM_AddDoneProc( *dproc ); *dproc = &TM_LBTSDone; }} lbts->rep_ts = *min_ts; lbts->rep_qual = *qual; }if(st->debug>0){printf("TM_LBTSStarted(min_ts=%s, qual=%s)\n",TM_STR(tmp_str,*min_ts),TM_TIME_QUAL_STR(*qual));fflush(stdout);}if(st->debug>3)TM_PrintState(); return sproc_flag;}/*----------------------------------------------------------------------------*/static void TM_InitMod( TMModuleState *mod ){ if( !mod->inited ) { mod->inited = TRUE; mod->cl.init(mod->cl.closure, TM_LBTSStarted); }}/*----------------------------------------------------------------------------*/void TM_Init (long long_k){ char *dbgstr = getenv("TM_DEBUG"); st = &tm_state; lbts = &st->lbts; modlist = &st->modlist; stats = &st->stats; st->debug = dbgstr?atoi(dbgstr):0; st->myid = (int) FM_nodeid; st->N = (int) FM_numnodes;if(st->debug>1){printf("TM_DEBUG=%d\n",st->debug);} lbts->LBTS = TM_ZERO; lbts->qual = TM_TIME_QUAL_INCL; lbts->epoch_id = 0; lbts->sproc = 0; lbts->max_dproc = 1000; lbts->n_dproc = 0; lbts->dproc = (TM_LBTSDoneProc *)malloc( sizeof(TM_LBTSDoneProc)*lbts->max_dproc); modlist->nmods = 0; modlist->maxmods = 0; modlist->activemod = -1; modlist->mods = 0; stats->nlbts = 0; TM_TopoInit(); /*Add modules*/ { if(!getenv("TM_NORED" )){void TMMRed_AddModule(void); TMMRed_AddModule();} if(FALSE || getenv("TM_DONULL"))/*Add TM-Null only on explicit request?*/ if(!getenv("TM_NONULL")){void TMMNull_AddModule(void);TMMNull_AddModule();} } FML_Barrier(); TIMER_NOW(stats->start);if(st->debug>1){printf("TM_Init() done.\n");}}/*----------------------------------------------------------------------------*/void TM_InitDone(void){ TMModuleState *mod = modlist->mods; while( mod ) { if(!mod->inited)TM_InitMod( mod ); mod = mod->next; }}/*----------------------------------------------------------------------------*/void TM_SetLBTSStartProc( TM_LBTSStartedProc started_proc ){ lbts->sproc = started_proc;}/*----------------------------------------------------------------------------*/long TM_CurrentEpoch( void ){ return lbts->epoch_id;}/*----------------------------------------------------------------------------*/void TM_Recent_LBTS( TM_Time *pts ){ if( pts ) *pts = lbts->LBTS;}/*----------------------------------------------------------------------------*/void TM_Recent_Qual( TM_TimeQual *pq ){ if( pq ) *pq = lbts->qual;}/*----------------------------------------------------------------------------*/long TM_StartLBTS( TM_Time min_ts, TM_TimeQual qual, TM_LBTSDoneProc done_proc, long *ptrans ){ TMModuleState *mod = modlist->mods;if(st->debug>0){printf("TM_StartLBTS(min_ts=%s,qual=%s,dproc=%p,trans=%ld)\n",TM_STR(tmp_str,min_ts),TM_TIME_QUAL_STR(qual),done_proc,*ptrans);fflush(stdout);} lbts->rep_ts = min_ts; lbts->rep_qual = qual; TM_AddDoneProc( done_proc ); *ptrans = lbts->epoch_id; while( mod ) { if(!mod->inited)TM_InitMod( mod ); mod->cl.startlbts(mod->cl.closure, min_ts, qual, &TM_LBTSDone, NULL); mod = mod->next; } return TM_SUCCESS;}/*----------------------------------------------------------------------------*/void TM_PutTag( TM_TagType *ptag ){ int nbytes = 0; TMModuleState *mod = modlist->mods;if(st->debug>1){printf("TM_PutTag(%ld)\n",(*((long*)ptag)));} while( mod ) { int tagsz = 0; if(!mod->inited)TM_InitMod( mod ); mod->cl.puttag(mod->cl.closure, ((char*)ptag)+nbytes, &tagsz); nbytes += tagsz; mod = mod->next; }}/*----------------------------------------------------------------------------*/void TM_Out( TM_Time ts, long nevents ){ TMModuleState *mod = modlist->mods;if(st->debug>1){printf("TM_Out(ts=%f,nevents=%ld)\n",TM_TS(ts),nevents);} while( mod ) { if(!mod->inited)TM_InitMod( mod ); mod->cl.out(mod->cl.closure, ts, nevents); mod = mod->next; }}/*----------------------------------------------------------------------------*/void TM_In( TM_Time ts, TM_TagType tag ){ int nbytes = 0; TMModuleState *mod = modlist->mods;if(st->debug>1){printf("TM_In(ts=%f,tag=%ld)\n",TM_TS(ts),(*((long*)&tag)));} while( mod ) { int tagsz = 0; if(!mod->inited)TM_InitMod( mod ); mod->cl.in(mod->cl.closure, ts, ((char*)&tag)+nbytes, &tagsz); nbytes += tagsz; mod = mod->next; }}/*----------------------------------------------------------------------------*/void TM_PrintStats( void ){ TMModuleState *mod = modlist->mods; while( mod ) { if(!mod->inited)TM_InitMod( mod ); mod->cl.printstats(mod->cl.closure);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -