// -*-c++-*- #ifndef INFREQSTATEMANAGER_CC #define INFREQSTATEMANAGER_CC // Copyright (c) 1994-1996 Ohio Board of Regents and the University of // Cincinnati. All Rights Reserved. // BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY // FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT // PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, // EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE // PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME // THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. // IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING // WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR // REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR // DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL // DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM // (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED // INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF // THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER // OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. // // $Id: InfreqStateManager.cc,v 1.1.1.1 2007/03/15 15:45:06 rmadhoun Exp $ // // //--------------------------------------------------------------------------- #include "InfreqStateManager.hh" #include "../../../JackyDebugStream.h" //for jacky-debug-mode #ifdef JACKY_STATISTICS //[2006-04-02] #include "BasicTimeWarp.hh" #endif //end JACKY_STATISTICS //[2006-04-02] inline InfreqStateManager::InfreqStateManager(BasicTimeWarp *myProcessPtr): StateManager(myProcessPtr) { statePeriod = STATE_PERIOD; periodCounter = 0; timeAtLastCall = INVALIDTIME; #ifdef JACKY_INFREQ_STATEMANAGER //[2006-03-24] //set default value of "doStateSaving" to false doStateSaving = false; #endif //end JACKY_INFREQ_STATEMANAGER [2006-03-24] } void InfreqStateManager::createInitialState() { StateManager::createInitialState(); current->dirty = false; } //Jacky: this function overrides StateManager::saveState(). It saves the SimuObj's current state (the current //state is defined in StateManager and is inherited here) onto the StateQueue. The state saving strategy is: // 1. Only save the state derived from the 1st event executed at a given time // e.g. // If e1, e2, e3, e4, and e5 are the events executed by this SimuObj at simulated time t1, // then only the state after executing event e1 is saved! // 2. Save state every N+1 different simulated time, where N defaults to 3 // e.g. // In the following sequence of events, the state saved are: // Events: e1[000] e2[000] e3[100] e4[200] e5[200] e6[300] e7[300] e7[300] e8[400] e9[400] e10[500] // periodCounter: 3 2 1 0 3 // StateQ: stateQ[0] stateQ[1] // That is, state is saved for the 1st event at time 000, 400, 800, 1200, etc. void InfreqStateManager::saveState() { #ifdef LPDEBUG *lpFile << nameOfObject << " timeAtLastCall: " << timeAtLastCall << " lvt = " << current->lVT << "\n"; #endif #ifdef JACKY_DEBUG ostream& jacky_os = JackyDebugStream::Instance().Stream(); #endif #ifdef JACKY_INFREQ_STATEMANAGER //[2006-03-24] --------------------------------------------------------------------- if( doStateSaving == false ) { // flag is false, employ InfreqStateManager's state saving policy #endif //end JACKY_INFREQ_STATEMANAGER [2006-03-24] ----------------------------------------------------------------- #ifdef JACKY_DEBUG jacky_os << endl << "[InfreqStateManager]::saveState() -> doStateSaving=FALSE" << " / timeAtLastCall=" << timeAtLastCall.asString() << " / current->lVT=" << (current->lVT).asString() << endl << flush; #endif if (timeAtLastCall != current->lVT) { //Time Change detected! #ifdef JACKY_DEBUG jacky_os << "\t[InfreqStateManager] -> Time Change!" << endl << flush; #endif if (periodCounter == 0) { //Only save the 1st state at this new time #ifdef JACKY_DEBUG jacky_os << "\t[InfreqStateManager] -> periodCounter = 0! => StateManager::saveState()..." << endl << flush; #endif startStateTiming(); //inherit from StateManager, do nothing current->dirty = false; //state will be clean; StateManager::saveState(); //this does the actual state saving periodCounter = statePeriod; //reset periodCounter #ifdef JACKY_DEBUG jacky_os << "\t[InfreqStateManager] -> reset periodCounter = " << periodCounter << endl << endl << flush; #endif stopStateTiming(); //inherit from StateManager, do nothing } else { //Time changed, but we are in the skip interval #ifdef JACKY_DEBUG jacky_os << "\t[InfreqStateManager]e() -> periodCounter = " << periodCounter << flush; #endif periodCounter--; #ifdef JACKY_DEBUG jacky_os << " ==> No state saving! set periodCounter = " << periodCounter << endl << flush; #endif // If this function is called then the last state will be dirty unless this state is saved. (stateQ.back())->dirty = true; #ifdef JACKY_STATISTICS //[2006-04-02] BasicTimeWarp::totalNumberOfStatesOmitted++; #endif //end JACKY_STATISTICS //[2006-04-02] } timeAtLastCall = current->lVT; //update timeAtLastCall to the new time #ifdef JACKY_DEBUG jacky_os << "\t[InfreqStateManager] -> update timeAtLastCall = " << timeAtLastCall.asString() << endl << flush; #endif } else { //No Time Change, don't save state for all following events at this time #ifdef JACKY_DEBUG jacky_os << "\t[InfreqStateManager] -> No Time Change => No state saving!" << endl << flush; #endif // If this function is called then the last state will be dirty unless this state is saved. (stateQ.back())->dirty = true; #ifdef JACKY_STATISTICS //[2006-04-02] BasicTimeWarp::totalNumberOfStatesOmitted++; #endif //end JACKY_STATISTICS //[2006-04-02] } //end if Time Change or not #ifdef JACKY_INFREQ_STATEMANAGER //[2006-03-24] --------------------------------------------------------------------- } //end if doStateSaving == false else{ //flag is true, allways save state!!! (just like the StateManager does) #ifdef JACKY_DEBUG jacky_os << endl << "[InfreqStateManager]::saveState() -> doStateSaving=TRUE" << endl << flush; jacky_os << "\t[InfreqStateManager] => StateManager::saveState()... " << endl << flush; #endif startStateTiming(); //inherit from StateManager, do nothing current->dirty = false; //state will be clean; StateManager::saveState(); //this does the actual state saving stopStateTiming(); //inherit from StateManager, do nothing } #endif //end JACKY_INFREQ_STATEMANAGER [2006-03-24] ----------------------------------------------------------------- } /* void InfreqStateManager::saveState() { #ifdef LPDEBUG *lpFile << nameOfObject << " timeAtLastCall: " << timeAtLastCall << " lvt = " << current->lVT << "\n"; #endif #ifdef JACKY_DEBUG ostream& jacky_os = JackyDebugStream::Instance().Stream(); jacky_os << endl << "[InfreqStateManager] saveState() called!!" << endl << endl << flush; jacky_os << "\ttimeAtLastCall = " << timeAtLastCall.asString() << " / current->lVT = " << (current->lVT).asString() << endl << flush; #endif if (timeAtLastCall != current->lVT) { #ifdef JACKY_DEBUG jacky_os << "[InfreqStateManager] saveState() -> Time Change! [timeAtLastCall != current->lVT]" << endl << flush; #endif if (periodCounter == 0) { // We have not saved a state for this time and we have not executed a message at this time, // so we have just executed the first message at this time. // (Only save the first state at this time) #ifdef JACKY_DEBUG jacky_os << endl << "[InfreqStateManager] saveState() -> periodCounter = 0! " << "call StateManager::saveState()..." << endl << flush; #endif startStateTiming(); //inherit from StateManager, do nothing // state will be clean; current->dirty = false; StateManager::saveState(); //this does the actual state saving periodCounter = statePeriod; //reset periodCounter, default is 3 #ifdef JACKY_DEBUG jacky_os << "[InfreqStateManager] saveState() -> reset periodCounter = " << periodCounter << endl << endl << flush; #endif stopStateTiming(); //inherit from StateManager, do nothing } else { periodCounter--; #ifdef JACKY_DEBUG jacky_os << endl << "[InfreqStateManager] saveState() -> periodCounter != 0 => No state saving!!!" << " -> set periodCounter = " << periodCounter << endl << flush; #endif // If this function is called then the last state will be dirty unless this state is saved. (stateQ.back())->dirty = true; } timeAtLastCall = current->lVT; #ifdef JACKY_DEBUG jacky_os << "[InfreqStateManager] saveState() -> update timeAtLastCall = " << timeAtLastCall.asString() << endl << flush; #endif } else { #ifdef JACKY_DEBUG jacky_os << "[InfreqStateManager] saveState() -> No Time Change => No state saving!!!" << endl << flush; #endif // If this function is called then the last state will be dirty unless this state is saved. (stateQ.back())->dirty = true; } } */ //[2006-03-20] //this function is called indirectly by GVTManager::gcollect() to garbage collect the stateQ ******************* VTime InfreqStateManager::gcollect(VTime gtime, BasicEvent*& inputQptr, Container*& outputQptr) { VTime tmpTime = stateQ.gcollect(gtime, inputQptr, outputQptr); if ( (stateQ.front() ) == NULL ) { cout << "StateQueue is NULL at gtime " << gtime << " for " << nameOfObject << endl; } if ( (stateQ.front() )->dirty == true) { // There are messages between the last saved state before gVT and gVT. return(tmpTime); } else { return(gtime); } } //Jacky: this function overrides StateManager::restoreState(). It simply calls StateManager::restoreState() //and then reset the "timeAtLastCall" to the lVT in the state restored, which is the time of the LAST state //on the stateQ with lVT < restoreTime. VTime InfreqStateManager::restoreState(VTime restoreTime) { #ifdef JACKY_DEBUG ostream& jacky_os = JackyDebugStream::Instance().Stream(); jacky_os << endl << "[InfreqStateManager] restoreState() called!!" << endl << endl << flush; #endif VTime tmpTime = StateManager::restoreState(restoreTime); timeAtLastCall = tmpTime; //reset time at last call so that another state is not saved at this time //#ifdef JACKY_INFREQ_STATEMANAGER //[2006-03-24] // periodCounter = statePeriod; //Also reset periodCounter so restart saving policy again //#endif //end JACKY_INFREQ_STATEMANAGER [2006-03-24] #ifdef JACKY_DEBUG jacky_os << "\t[InfreqStateManager] restoreState() -> reset timeAtLastCall = " << timeAtLastCall.asString() << " / reset periodCounter = " << periodCounter << endl << flush; #endif return (tmpTime); } inline void InfreqStateManager::setStatePeriod(int period) { statePeriod = period; #ifdef OBJECTDEBUG // This check needs to be done becuase the timewarp constructor calls // this function before logical process sets the pointer if (lpFile->good()) *lpFile << "period = " << period << "\n"; #endif } #endif