#include #include #include using namespace std; /* implementation of callback routines */ /*************************************************************************** * Description: DefThread is called when a new nodeid/threadid is encountered. * This is a callback routine which must be registered by the * trace converter. ***************************************************************************/ int ThreadDef(unsigned int nodeToken, unsigned int threadToken, unsigned int processToken, const char *threadName ) { Thread &local = *(new Thread()); //cout << nodeToken << " Process " << &local << endl; local.nodeToken=nodeToken; local.threadToken=threadToken; Converter::threadnames[processToken] = new string(threadName);//local.threadName=threadName; local.lastState=-1; local.currentState=-1; local.finished=false; local.nextShot=-1; local.thisShot=0; local.lastTime=0; local.trigSeen=0; local.snapshot=-1; local.processToken=processToken; if(Converter::segmentInterval>0) { local.snapshot=0; local.nextShot=Converter::segmentInterval; } else if(Converter::trigEvent>-1) { local.snapshot=0; } //int curid; //EOF_Trace[pair (nodeToken,threadToken) ] = pair(0,local); //Converter::ThreadID[pair(nodeToken,threadToken)]= curid =Converter::ThreadID.size(); //EOF_Trace[curid]=false; Converter::ThreadMap[processToken]=&local; //cout << "Printing Thread: " << processToken << endl; //SnapshotThreadPrint(processToken,nodeToken,threadToken); return 0; } /*************************************************************************** * Description: DefState is called to define a new symbol (event). It uses * the token used to define the group identifier. * This is a callback routine which must be registered by the * trace converter. ***************************************************************************/ int StateDef(unsigned int stateToken, const char *stateName, unsigned int stateGroupToken ) { State &local = *(new State()); local.calls=0; local.subroutines=0; local.inclusive=0; local.exclusive=0; local.topTime=-1; local.fullTime=-1; local.countRec=0; /*These are all for monotonically increasing events*/ local.countMIE=0; local.lastaction=0; local.holdvalue=0; local.stateToken=stateToken; local.stateGroupToken=stateGroupToken; //local.stateName=stateName; Converter::statenames[stateToken]= new string(stateName); Converter::allstate[stateToken]=&local; return 0; } /*************************************************************************** * Description: DefStateGroup registers a profile group name with its id. * This is a callback routine which must be registered by the * trace converter. ***************************************************************************/ int StateGroupDef(unsigned int stateGroupToken, const char *stateGroupName ) { Converter::groupnames[stateGroupToken] = new string(stateGroupName); return 0; } /*************************************************************************** * Description: DefUserEvent is called to register the name and a token of the * user defined event (or a sample event in Vampir terminology). * This is a callback routine which must be registered by the * trace converter. ***************************************************************************/ int UserEventDef(unsigned int userEventToken,const char *userEventName , int monotonicallyIncreasing) { char *name = strdup(userEventName); int len = strlen(name); if ((name[0] == '"' ) && (name[len-1] == '"')) { name += 1; name[len-2] = '\0'; } /* create a state record */ if (monotonicallyIncreasing) { /* for hw counter data */ MonIncEvent &local = *(new MonIncEvent()); Converter::monincnames[userEventToken] = new string(userEventName);//local.eventName=name; local.eventToken=userEventToken; local.exclusive=0; local.inclusive=0; local.topCount=-1; local.fullCount=-1; local.holdvalue=-1; Converter::allmoninc.push_back(&local); //Converter::miecount++; Converter::monincids.insert(userEventToken); } else { /* for non monotonically increasing data */ UserEvent &local=*(new UserEvent()); Converter::usereventnames[userEventToken] = new string(userEventName);//local.userEventName=name; local.max=0; local.min=0; local.numevents=0; local.sum=0; local.sumsqr=0; local.tricount=0; local.userEventToken=userEventToken; Converter::allevents.push_back(&local); } return 0; } /*************************************************************************** * Description: ClockPeriod (in microseconds) is specified here. * This is a callback routine which must be registered by the * trace converter. ***************************************************************************/ int ClockPeriodDef(double clkPeriod ) { return 0; } /*************************************************************************** * Description: EndTrace is called when an EOF is encountered in a tracefile. * This is a callback routine which must be registered by the * trace converter. ***************************************************************************/ int EndTraceDef(unsigned int processToken)//unsigned int nodeToken, unsigned int threadToken, { //(EOF_Trace[pair (nodeToken,threadToken) ]).first = 1; /* flag it as over */ (Converter::ThreadMap[processToken])->finished=true; /* yes, it is over */ map ::iterator it;//pair, pair, less< pair > Converter::EndOfTrace = 1; /* Lets assume that it is over */ for (it = Converter::ThreadMap.begin(); it != Converter::ThreadMap.end(); it++) {/* cycle through all pairs to see if it really over */ if ((*it).second->finished == false)//.second. { Converter::EndOfTrace = 0; /* not over! */ /* If there's any processor that is not over, then the trace is not over */ } } return 0; } /*************************************************************************** * Description: EventTrigger is called when a user defined event is triggered. * This is a callback routine which must be registered by the * trace converter. ***************************************************************************/ int EventTriggerDef(double time, unsigned int pid, unsigned int userEventToken, long long userEventValue)//unsigned int nid,unsigned int tid, { if(time>Converter::lastTime)Converter::lastTime=time; //unsigned int curid=pid;//Converter::ThreadID[pair(nid,tid)]; Thread &threadin=*(Converter::ThreadMap[pid]); threadin.lastTime=time;//Converter::ThreadMap[curid].lastTime=time; //lastTime=time; SnapshotControl(time,-2, threadin); /* write the sample data */ if(Converter::monincids.count(userEventToken)==0) { /*not monotonically increasing*/ /*Each NMI event is between two '0' events which are ignored. (every 2nd of 3 events is used)*/ //ThreadMap[curid] <- EOF_Trace[pair(nid,tid)].second UserEvent &thisUE=*(threadin.allevents[userEventToken]); if(thisUE.tricount==0) { thisUE.tricount++; return(0); } if(thisUE.tricount==2) { thisUE.tricount=0; return(0); } /*Update the event data*/ thisUE.tricount++; thisUE.numevents++; thisUE.sum+=userEventValue; thisUE.sumsqr+= (userEventValue*userEventValue); if(userEventValue > thisUE.max) { thisUE.max=userEventValue; } if(userEventValue < thisUE.min ||thisUE.min==0) { thisUE.min=userEventValue; } } else { /*monotonically increasing*/ //cout << userEventToken << " entered " << pid << " with " << userEventValue << endl; int stateid=threadin.lastState; if(stateid==-1) { cout << "State not set" << endl; } State &thisState=*(threadin.allstate[stateid]); thisState.allmi[userEventToken]->holdvalue=userEventValue; thisState.countMIE++; /*If we have encountered every event associated with this state we can process all at once*/ if(thisState.countMIE==(Converter::monincids.size()+1)) {/*lastaction indicates if we should batch process a state exit or a state enter*/ if(thisState.lastaction==1) { //ThreadMap[curid]= StateEnter(time,threadin,thisState); } else if(thisState.lastaction==-1) { //ThreadMap[curid]= StateLeave(time,threadin,thisState); } else if(thisState.lastaction==0) { cout << "Action Detection Fault(Event Trigger)" << endl; } thisState.countMIE=0; thisState.lastaction=0; threadin.lastState=-1; } } return 0; } /*************************************************************************** * Description: EnterState is called at routine entry by trace input library * This is a callback routine which must be registered by the * trace converter. ***************************************************************************/ int EnterStateDef(double time, unsigned int pid, unsigned int stateid)//unsigned int nid, unsigned int tid, { if(time>Converter::lastTime)Converter::lastTime=time; //unsigned int curid=pid; Thread &threadin=*(Converter::ThreadMap[pid]); threadin.currentState=stateid; threadin.lastTime=time; //lastTime=time; SnapshotControl(time,-2, threadin); State &thisState=*(threadin.allstate[stateid]); /* * If we are recording user defined events, all state control is managed by 'EventTrigger' */ //int curid=ThreadID[pair(nid,tid)]; if(Converter::monincids.size()>0) { threadin.lastState=stateid; thisState.lastaction=1; thisState.holdvalue=time; if(thisState.countMIE>0) { cout << "User Event Couting Fault (EnterState)" << endl; } thisState.countMIE++; return 0; } //ThreadMap[curid]= StateEnter(time,threadin,thisState); return 0; } /*************************************************************************** * Description: LeaveState is called at routine exit by trace input library * This is a callback routine which must be registered by the * trace converter. ***************************************************************************/ int LeaveStateDef(double time,unsigned int pid)//, unsigned int stateid unsigned int nid, unsigned int tid, { if(time>Converter::lastTime)Converter::lastTime=time; //unsigned int curid=pid;//Converter::ThreadID[pair(nid,tid)]; Thread &threadin=*(Converter::ThreadMap[pid]); unsigned int stateid=threadin.currentState; State &thisState=*(threadin.allstate[stateid]); threadin.lastTime=time; //lastTime=time; SnapshotControl(time,stateid, threadin); /* * If we are recording user defined events, all state control is managed by 'EventTrigger' */ //int curid=ThreadID[pair(nid,tid)]; if(Converter::monincids.size()>0) { threadin.lastState=stateid; thisState.lastaction=-1; thisState.holdvalue=time; if(thisState.countMIE>0) { cout << "User Event Couting Fault (LeaveState)" << endl; } thisState.countMIE++; return 0; } //ThreadMap[curid]= StateLeave(time,threadin,thisState); return 0; }