/******************************************************************* * Declaration: This class is partially based on Glinsky's version that * can be found in the "oldsource" directory. * * DESCRIPTION: class ParallelNodeCoordinatorState * * AUTHOR: Qi (Jacky) Liu * * EMAIL: mailto://liuqi@sce.carleton.ca * * DATE: Sept, 2005 * *******************************************************************/ #ifndef _PNCOORDSTATE_H #define _PNCOORDSTATE_H #include #include "pProcessorState.h" #include "eventlist.h" #include "NCmsgbag.h" //class NCMessageBag #include "msgbag.h" #include "pprocess.h" #include "JackyDebugStream.h" //for jacky-debug-mode //#ifdef JACKY_NCBAG_POINTERS //[2006-02-03] //#include //multimap //#endif //end JACKY_NCBAG_POINTERS //[2006-02-03] /** forward declarations **/ class BasicPortMessage; /*Note: last & next time is defined in class ParallelProcessorState*/ class ParallelNodeCoordinatorState :public ParallelProcessorState { public: /*The NC will hold * 1> the external events list loaded from the environment .EV file * 2> the next type of message to send: a (@) msg or a (*) msg */ /* Jacky Note: The state will be restored during rollback. If we define the eventsCursor here, it will be restored to point to a previous external event in the EventList during a rollback. However, the previous external events have already been sent by the NC, they are stored as (X) msgs in the inputQ! When there is a rollback, these msgs will be unprocessed, thus we should not restore the eventsCursor to avoid the same external events being processed twice! So I move the eventsCursor from here to the ParallelNodeCoordinator class (Sept. 12, 2005) */ //To manage the external events, we only need a pointer to the //current event, the whole event list is hold by the NC processor EventList::iterator eventsCursor; enum NextMsgType { CollectMsg, InternalMsg }; NextMsgType nextMsgType; /*This is a flag to indicate the status of the NC. ** FALSE -> the simulation on the local machine has not yet bene finished ** TRUE -> the simulation on the local machine has been done, i.e. the first unprocessed event ** in the inputQ (thus with the smallest timestamp) has a recvTime > stopTime(), and ** the NC is passive while waiting (X) msgs ** from other NCs */ bool dormant; typedef set ProcSet; // Oct. 19, 2005 //the set is used to record the procIds of remote NCs to which we need to send an (X) msg //Note: only ONE (X) msg will be sent to each remote NC ProcSet remoteNCList; // Oct. 19, 2005 /* Note: ** The NCMessageBag cannot be put here! Oct. 26, 2005 */ //we use a pointer to the NCMessageBag instead of an NCMessageBag object here! //NCMessageBag* bag; // Oct. 19, 2005 //typedef multimap< const VTime, BasicEvent* > NCBagReference; //[2006-03-15] //pair //NCBagReference bagref; //[2006-03-15] ParallelNodeCoordinatorState(); virtual ~ParallelNodeCoordinatorState(); ParallelNodeCoordinatorState& operator=(ParallelNodeCoordinatorState& thisState); //Assignment void copyState(BasicState *); int getSize() const; #ifdef JACKY_DEBUG //Jacky: this function will be defined in all state classes for ParallelProcesses & Models // to show (print) the content of the state for debugging purpose virtual void showStateContent( ostream& ) const; void showRemoteNCList( ostream& ) const; void showCurrentEvent( ostream& ) const; //void showNCBagRef( ostream& ) const; #endif }; #ifdef JACKY_DEBUG inline void ParallelNodeCoordinatorState::showStateContent( ostream& out ) const{ //1> first call the counterpart function in the base class ParallelProcessorState::showStateContent(out); //2> show content defined in this class out << "\tParallelNodeCoordinatorState -> nextMsgType = " << flush; if( nextMsgType == ParallelNodeCoordinatorState::CollectMsg ){ out << "@" << flush; } else if( nextMsgType == ParallelNodeCoordinatorState::InternalMsg ){ out << "*" << flush; } out << " / dormant = " << flush; if( dormant ){ out << "TRUE" << endl << flush; } else { out << "FALSE" << endl << flush; } showRemoteNCList( out ); //show the current eventsCursor //out << "showing eventsCursor...(not implemented)" << endl; showCurrentEvent( out ); //out << "------------------ NCBagRef ---------------------------" << endl << flush; //showNCBagRef( out ); } inline void ParallelNodeCoordinatorState::showRemoteNCList( ostream& out ) const { ParallelNodeCoordinatorState::ProcSet::const_iterator it = remoteNCList.begin(); out << "\tremoteNCList: < " << flush; if( remoteNCList.size() == 0 ){ out << "EMPTY >" << endl << flush; } else { for( ; it != remoteNCList.end(); it++){ out << (*it) << ", " << flush; } out << " >" << endl << flush; } } /* inline void ParallelNodeCoordinatorState::showNCBagRef( ostream& out ) const { if( bagref.size() > 0 ){ ParallelNodeCoordinatorState::NCBagReference::const_iterator pos = bagref.begin(); for( ; pos != bagref.end(); pos++ ){ //print out the recvTime of the BasicEvent, and its address out << "<" << (pos->first).asString() << ", " << pos->second << "> " << flush; } out << endl << flush; } else { out << "-> EMPTY!" << endl << flush; } } */ #endif //end JACKY_DEBUG #endif //_PROOTSTATE_H