|
libFAUDES
Sections
Index
|
sp_lpexecutor.cppGo to the documentation of this file.00001 /** @file sp_lpexecutor.cpp Executor with logging facilities */ 00002 00003 /* 00004 FAU Discrete Event Systems Library (libfaudes) 00005 00006 Copyright (C) 2007, 2008 Thomas Moor 00007 Copyright (C) 2007 Ruediger Berndt 00008 Exclusive copyright is granted to Klaus Schmidt 00009 00010 */ 00011 00012 00013 #include "sp_lpexecutor.h" 00014 00015 namespace faudes { 00016 00017 00018 // LoggingExecutor(void) 00019 LoggingExecutor::LoggingExecutor(void) 00020 : ParallelExecutor(), pLogTokenWriter(0), mLogFile(""), mLogMode(0) 00021 { 00022 FD_DX("LoggingExecutor(" << this << ")::LoggingExecutor()"); 00023 TraceClear(0); 00024 } 00025 00026 // LoggingExecutor(rFileName) 00027 LoggingExecutor::LoggingExecutor(const std::string& rFileName) 00028 : ParallelExecutor(rFileName), pLogTokenWriter(0), mLogFile(""), mLogMode(0) 00029 { 00030 FD_DX("LoggingExecutor(" << this << ")::LoggingExecutor(" << rFileName << ")"); 00031 TraceClear(0); 00032 } 00033 00034 // LoggingExecutor(void) 00035 LoggingExecutor::~LoggingExecutor(void) { 00036 FD_DX("LoggingExecutor(" << this << ")::~LoggingExecutor()"); 00037 LogClose(); 00038 } 00039 00040 // Compile() 00041 void LoggingExecutor::Compile(void) { 00042 FD_DX("LoggingExecutor(" << this << ")::Compile(): #" << Size()); 00043 // call base 00044 ParallelExecutor::Compile(); 00045 // care about my members 00046 CompileConditions(); 00047 FD_DX("LoggingExecutor(" << this << ")::Compile(): done"); 00048 } 00049 00050 // Reset() 00051 void LoggingExecutor::Reset(void) { 00052 FD_DX("LoggingExecutor(" << this << ")::Reset()"); 00053 // log trace 00054 LogWritePause(); 00055 // call base (incl compile) 00056 ParallelExecutor::Reset(); 00057 // log trace 00058 LogWriteResume(); 00059 // clear and initialise trace (base was called first) 00060 TraceClear(); 00061 // figure initial state 00062 ConditionsReset(); 00063 } 00064 00065 00066 // Clear() 00067 void LoggingExecutor::Clear(void) { 00068 FD_DX("LoggingExecutor(" << this << ")::Clear()"); 00069 // clear my members 00070 LogClose(); 00071 mConditions.Clear(); 00072 mBreakCondition=false; 00073 TraceClear(); 00074 // call base 00075 ParallelExecutor::Clear(); 00076 } 00077 00078 //DoWrite(rTr,rLabel) 00079 void LoggingExecutor::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const { 00080 (void) pContext; 00081 std::string label=rLabel; 00082 if(label=="") label = "Executor"; 00083 rTw.WriteBegin(label); 00084 ParallelExecutor::DoWrite(rTw,"Generators"); 00085 mConditions.Write(rTw,"Conditions",this); 00086 rTw.WriteEnd(label); 00087 } 00088 00089 //DoRead(rTr,rLabel) 00090 void LoggingExecutor::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) { 00091 (void) pContext; 00092 FD_DC("LoggingExecutor::DoRead(rTr, " << rLabel<<")"); 00093 std::string label=rLabel; 00094 if(label=="") label = "Executor"; 00095 rTr.ReadBegin(label); 00096 while(!rTr.Eos(label)) { 00097 // peek token 00098 Token token; 00099 rTr.Peek(token); 00100 // case 1: generators 00101 if(token.Type()==Token::Begin) 00102 if(token.StringValue()=="Generators") { 00103 ParallelExecutor::DoReadGenerators(rTr); 00104 continue; 00105 } 00106 // case 2: conditions 00107 if(token.Type()==Token::Begin) 00108 if(token.StringValue()=="Conditions") { 00109 mConditions.Read(rTr,"Conditions",this); 00110 continue; 00111 } 00112 // else report error 00113 std::stringstream errstr; 00114 errstr << "Invalid token, generators or conditions section expected, " << rTr.FileLine(); 00115 throw Exception("LoggingExecutor::DoRead", errstr.str(), 502); 00116 } 00117 rTr.ReadEnd(label); 00118 Reset(); 00119 } 00120 00121 00122 00123 // ExecuteTime(time) 00124 bool LoggingExecutor::ExecuteTime(tpTime::Type time) { 00125 // call base 00126 bool res=ParallelExecutor::ExecuteTime(time); 00127 // bail out 00128 if(!res) return false; 00129 // update trace (after base) 00130 TraceUpdateTime(); 00131 // done 00132 return res; 00133 } 00134 00135 // ExecuteEvent(event) 00136 bool LoggingExecutor::ExecuteEvent(Idx event) { 00137 // call base 00138 bool res=ParallelExecutor::ExecuteEvent(event); 00139 // bail out 00140 if(!res) return false; 00141 // process conditions 00142 ConditionsProcess(); 00143 // record log 00144 LogWriteTime(); 00145 LogWriteEvent(); 00146 LogWriteState(); 00147 // record trace 00148 TraceUpdateTransition(event); 00149 return true; 00150 } 00151 00152 00153 // set logic time 00154 void LoggingExecutor::CurrentStep(int step) { 00155 FD_DX("LoggingExecutor(" << this << ")::CurrentStep(step)"); 00156 // call base 00157 ParallelExecutor::CurrentStep(step); 00158 // clear trace 00159 TraceClear(); 00160 mConditions.Reset(); 00161 } 00162 00163 // set physical time 00164 void LoggingExecutor::CurrentTime(tpTime::Type time) { 00165 FD_DX("LoggingExecutor(" << this << ")::CurrentTime(time)"); 00166 // call base 00167 ParallelExecutor::CurrentTime(time); 00168 // clear trace 00169 TraceClear(); 00170 mConditions.Reset(); 00171 } 00172 00173 // set current state (clear trace) 00174 bool LoggingExecutor::CurrentParallelTimedState(const ParallelTimedState& ptstate) { 00175 FD_DX("LoggingExecutor(" << this << ")::CurrentParallelTimedState(ptstate)"); 00176 // call base 00177 bool res=ParallelExecutor::CurrentParallelTimedState(ptstate); 00178 // clear trace 00179 TraceClear(); 00180 ConditionsReset(); 00181 return res; 00182 } 00183 00184 00185 00186 // get conditions 00187 const SimConditionSet& LoggingExecutor::Conditions(void) const { 00188 return mConditions; 00189 } 00190 00191 // set conditions 00192 void LoggingExecutor::Conditions(const SimConditionSet& rConditions) { 00193 FD_DC("ProposingExecutor::DoRead(rTr,): loop X"); 00194 mConditions=rConditions; 00195 FD_DC("ProposingExecutor::DoRead(rTr, ): loop Y"); 00196 CompileConditions(); 00197 FD_DC("ProposingExecutor::DoRead(rTr, loop Z"); 00198 } 00199 00200 // get condition 00201 const AttributeSimCondition& LoggingExecutor::Condition(const std::string& rName) const { 00202 return mConditions.Attribute(mConditions.Index(rName)); 00203 } 00204 00205 // get condition 00206 const AttributeSimCondition& LoggingExecutor::Condition(Idx cond) const { 00207 return mConditions.Attribute(cond); 00208 } 00209 00210 /* 00211 // get condition pointer 00212 AttributeSimCondition* LoggingExecutor::Conditionp(const std::string& rName) { 00213 return mConditions.Attributep(mConditions.Index(rName)); 00214 } 00215 */ 00216 00217 /* 00218 // get condition pointer 00219 AttributeSimCondition* LoggingExecutor::Conditionp(Idx cond) { 00220 return mConditions.Attributep(cond); 00221 } 00222 */ 00223 00224 // add/edit one condition 00225 Idx LoggingExecutor::SetCondition(const std::string& rName, const AttributeSimCondition& rCondition) { 00226 Idx cond=mConditions.Insert(rName,rCondition); 00227 CompileConditions(); 00228 return cond; 00229 } 00230 00231 // edit one condition 00232 void LoggingExecutor::SetCondition(Idx cond, const AttributeSimCondition& rCondition) { 00233 mConditions.Insert(cond,rCondition); 00234 CompileConditions(); 00235 } 00236 00237 // remove condition 00238 void LoggingExecutor::ClrCondition(const std::string& rName) { 00239 mConditions.Erase(rName); 00240 CompileConditions(); 00241 } 00242 00243 // remove condition 00244 void LoggingExecutor::ClrCondition(Idx cond) { 00245 mConditions.Erase(cond); 00246 CompileConditions(); 00247 } 00248 00249 // token io 00250 void LoggingExecutor::ConditionsWrite(TokenWriter& rTw, const std::string& rLabel) const { 00251 mConditions.Write(rTw,rLabel); 00252 } 00253 00254 // token io 00255 void LoggingExecutor::ConditionsRead(TokenReader& rTr, const std::string& rLabel) { 00256 mConditions.Read(rTr,rLabel); 00257 CompileConditions(); 00258 } 00259 00260 00261 // iterators 00262 LoggingExecutor::ConditionIterator LoggingExecutor::ConditionsBegin(void) const { 00263 return mConditions.Begin(); 00264 } 00265 00266 // iterators 00267 LoggingExecutor::ConditionIterator LoggingExecutor::ConditionsEnd(void) const { 00268 return mConditions.End(); 00269 } 00270 00271 // set up internal datastructure 00272 void LoggingExecutor::CompileConditions(void) { 00273 FD_DX("LoggingExecutor::CompileConditions()"); 00274 // need a lock to prevent realocation of attributes 00275 mConditions.Lock(); 00276 // have a minmal copy to avoid pointless iterations 00277 mEnabledConditions.clear(); 00278 ConditionIterator cit=mConditions.Begin(); 00279 for(; cit != mConditions.End(); ++cit) { 00280 FD_DX("LoggingExecutor::CompileConditions(): compile " << mConditions.Str(*cit)); 00281 AttributeSimCondition* pattr=mConditions.Attributep(*cit); 00282 mConditions.DValid(); 00283 // reject if not enabled 00284 if(!pattr->Enabled()) continue; 00285 // reject incompatible dims 00286 if(pattr->IsStateCondition()) 00287 if(pattr->StateCondition().mStateSets.size()!=Size()) continue; 00288 // have it 00289 mEnabledConditions.push_back(pattr); 00290 } 00291 // reset all states (incl disabled) 00292 mConditions.Reset(); 00293 mBreakCondition=false; 00294 FD_DX("LoggingExecutor(" << this << ")::CompileConditions(): #" << mEnabledConditions.size()); 00295 } 00296 00297 // logging: reset 00298 void LoggingExecutor::ConditionsReset(void) { 00299 FD_DX("LoggingExecutor(" << this << ")::ConditionsReset()"); 00300 CompileConditions(); 00301 ConditionsProcess(); 00302 } 00303 00304 // logging: test 00305 void LoggingExecutor::ConditionsProcess(void) { 00306 FD_DX("LoggingExecutor(" << this << ")::ConditionsProcess()"); 00307 mBreakCondition=false; 00308 std::vector<AttributeSimCondition*>::iterator ait=mEnabledConditions.begin(); 00309 // loop over all enabled conditions 00310 for(; ait != mEnabledConditions.end(); ++ait) { 00311 AttributeSimCondition* pattr= *ait; 00312 // case 1: event condition 00313 if(pattr->IsEventCondition()) { 00314 // positive edge 00315 if(!pattr->Satisfied()) 00316 if(pattr->EventCondition().mStart.Exists(mRecentEvent)) { 00317 pattr->Satisfied(true,CurrentTime()); 00318 if(pattr->Breakpoint()) mBreakCondition=true; 00319 } 00320 // negative edge 00321 if(pattr->Satisfied()) 00322 if(pattr->EventCondition().mStop.Exists(mRecentEvent)) { 00323 pattr->Satisfied(false,CurrentTime()); 00324 } 00325 continue; 00326 } 00327 // case 2: state condition 00328 if(pattr->IsStateCondition()) { 00329 // stage a: figure state 00330 bool satisfied; 00331 if(pattr->StateCondition().mAllFlag) { 00332 // conjunctive 00333 satisfied=true; 00334 for(Idx i=0; i<Size(); i++) { 00335 Idx state = CurrentParallelState().at(i); 00336 const StateSet& set = pattr->StateCondition().mStateSets.at(i); 00337 if(set.Empty()) continue; 00338 if(!set.Exists(state)) { 00339 satisfied=false; 00340 break; 00341 } 00342 } 00343 } else { 00344 // disjunctive 00345 satisfied=false; 00346 for(Idx i=0; i<Size(); i++) { 00347 Idx state = CurrentParallelState().at(i); 00348 if(pattr->StateCondition().mStateSets.at(i).Exists(state)) { 00349 satisfied=true; 00350 break; 00351 } 00352 } 00353 } 00354 // state b: figure edge 00355 if(!pattr->Satisfied() && satisfied) { 00356 pattr->Satisfied(true,CurrentTime()); 00357 if(pattr->Breakpoint()) mBreakCondition=true; 00358 } 00359 if(pattr->Satisfied() && !satisfied) { 00360 pattr->Satisfied(false,CurrentTime()); 00361 } 00362 continue; 00363 } 00364 } // loop conditions 00365 } 00366 00367 00368 // logging io: start 00369 void LoggingExecutor::LogOpen(TokenWriter& rTw, int logmode) { 00370 FD_DX("LoggingExecutor(" << this << ")::LogOpen()"); 00371 pLogTokenWriter= &rTw; 00372 mLogFile=""; 00373 mLogMode=logmode; 00374 pLogTokenWriter->WriteBegin("ExecutionLog"); 00375 pLogTokenWriter->WriteBegin("Mode"); 00376 if(mLogMode & Statistics) pLogTokenWriter->WriteOption("Statistics"); 00377 if(mLogMode & States) pLogTokenWriter->WriteOption("States"); 00378 if(mLogMode & Events) pLogTokenWriter->WriteOption("Events"); 00379 if(mLogMode & Time) pLogTokenWriter->WriteOption("Time"); 00380 pLogTokenWriter->WriteEnd("Mode"); 00381 LogWriteTime(); 00382 LogWriteState(); 00383 } 00384 00385 // logging io: start 00386 void LoggingExecutor::LogOpen(const std::string& rFileName, int logmode, std::ios::openmode openmode) { 00387 FD_DX("LoggingExecutor(" << this << ")::LogOpen(" << rFileName << ")"); 00388 pLogTokenWriter= new TokenWriter(rFileName,openmode); 00389 LogOpen(*pLogTokenWriter, logmode); 00390 mLogFile=rFileName; 00391 } 00392 00393 00394 // logging io: stop 00395 void LoggingExecutor::LogClose(void) { 00396 if(mLogMode & Statistics) { 00397 LogWriteStatistics(); 00398 } 00399 if(mLogMode != 0) { 00400 FD_DX("LoggingExecutor(" << this << ")::LogClose(" << mLogFile << ")"); 00401 *pLogTokenWriter << "\n"; 00402 *pLogTokenWriter << "\n"; 00403 pLogTokenWriter->WriteEnd("ExecutionLog"); 00404 } 00405 if(mLogFile!="") { 00406 delete pLogTokenWriter; 00407 } 00408 mLogFile=""; 00409 pLogTokenWriter=0; 00410 mLogMode=0; 00411 } 00412 00413 // logging: report statistics 00414 void LoggingExecutor::LogWriteStatistics(void) { 00415 if(!(mLogMode & Statistics)) return; 00416 FD_DX("LoggingExecutor(" << this << ")::LogWriteStatistics()"); 00417 *pLogTokenWriter << "\n"; 00418 *pLogTokenWriter << "\n"; 00419 pLogTokenWriter->WriteBegin("Statistics"); 00420 std::vector<AttributeSimCondition*>::iterator ait=mEnabledConditions.begin(); 00421 for(; ait != mEnabledConditions.end(); ++ait) { 00422 AttributeSimCondition* pattr= *ait; 00423 pattr->mSamplesPeriod.Compile(); 00424 pattr->mSamplesPeriod.Write(*pLogTokenWriter); 00425 pattr->mSamplesDuration.Compile(); 00426 pattr->mSamplesDuration.Write(*pLogTokenWriter); 00427 *pLogTokenWriter << "\n"; 00428 } 00429 pLogTokenWriter->WriteEnd("Statistics"); 00430 *pLogTokenWriter << "\n"; 00431 *pLogTokenWriter << "\n"; 00432 } 00433 00434 // logging: report state 00435 void LoggingExecutor::LogWriteState(void) { 00436 if(!(mLogMode & States)) return; 00437 if(mLogMode & Time) { 00438 CurrentParallelTimedState().Write(*pLogTokenWriter,"TimedState",this); 00439 } else 00440 CurrentParallelTimedState().Write(*pLogTokenWriter,"DiscreteState",this); 00441 *pLogTokenWriter << "\n"; 00442 } 00443 00444 // logging: report event 00445 void LoggingExecutor::LogWriteEvent(void) { 00446 if(!(mLogMode & Events)) return; 00447 if(!(mLogMode & States)) { 00448 pLogTokenWriter->WriteString(Alphabet().SymbolicName(mRecentEvent)); 00449 *pLogTokenWriter << "\n"; 00450 } else { 00451 pLogTokenWriter->WriteBegin("Event"); 00452 pLogTokenWriter->WriteString(Alphabet().SymbolicName(mRecentEvent)); 00453 pLogTokenWriter->WriteEnd("Event"); 00454 } 00455 } 00456 00457 // loggging report time 00458 void LoggingExecutor::LogWriteTime(void) { 00459 if(!(mLogMode & Time)) return; 00460 if(!(mLogMode & States)) { 00461 pLogTokenWriter->WriteFloat(CurrentTime()); 00462 *pLogTokenWriter << "\n"; 00463 } else { 00464 pLogTokenWriter->WriteBegin("Time"); 00465 pLogTokenWriter->WriteFloat(CurrentTime()); 00466 pLogTokenWriter->WriteEnd("Time"); 00467 } 00468 } 00469 00470 // logging: pause 00471 void LoggingExecutor::LogWritePause(void) { 00472 FD_DX("LoggingExecutor(" << this << ")::LogWritePause()"); 00473 if(mLogMode == 0) return; 00474 LogWriteStatistics(); 00475 *pLogTokenWriter << "\n"; 00476 pLogTokenWriter->WriteEnd("ExecutionLog"); 00477 *pLogTokenWriter << "\n"; 00478 *pLogTokenWriter << "\n"; 00479 *pLogTokenWriter << "\n"; 00480 } 00481 00482 // logging report pause 00483 void LoggingExecutor::LogWriteResume(void) { 00484 FD_DX("LoggingExecutor(" << this << ")::LogWriteResume()"); 00485 if(mLogMode == 0) return; 00486 pLogTokenWriter->WriteBegin("ExecutionLog"); 00487 LogWriteState(); 00488 } 00489 00490 // trace: clear all 00491 void LoggingExecutor::TraceClear(int length) { 00492 FD_DX("LoggingExecutor(" << this << ")::TraceClear(" << length <<")"); 00493 // clear 00494 mTraceBuffer.clear(); 00495 mTraceTimeToStep.clear(); 00496 // set max length 00497 if(length>-2) mTraceMax=length; 00498 // set first step 00499 mTraceFirstStep=CurrentStep(); 00500 // bail out 00501 if(mTraceMax==0) return; 00502 // set first entry 00503 TraceAddSample(); 00504 } 00505 00506 // trace: access 00507 LoggingExecutor::TraceIterator LoggingExecutor::TraceBegin(void) const { 00508 return mTraceBuffer.begin(); 00509 } 00510 00511 // trace: access 00512 LoggingExecutor::TraceIterator LoggingExecutor::TraceEnd(void) const { 00513 return mTraceBuffer.end(); 00514 } 00515 00516 // trace: access 00517 const LoggingExecutor::TraceSample* LoggingExecutor::TraceAtStep(int step) const { 00518 int n = step-mTraceFirstStep; 00519 if(n<0) return 0; 00520 if(((unsigned int)n)>=mTraceBuffer.size()) return 0; 00521 return &mTraceBuffer[n]; 00522 } 00523 00524 // trace: access 00525 const LoggingExecutor::TraceSample* LoggingExecutor::TraceAtTime(tpTime::Type time) const { 00526 std::map<tpTime::Type,int>::const_iterator sit=mTraceTimeToStep.find(time); 00527 if(sit== mTraceTimeToStep.end()) 00528 return 0; 00529 int step = sit->second; 00530 return TraceAtStep(step); 00531 } 00532 00533 // trace: access 00534 const LoggingExecutor::TraceSample* LoggingExecutor::TraceCurrent(void) const { 00535 if(mTraceBuffer.size()==0) return 0; 00536 return &mTraceBuffer.back(); 00537 } 00538 00539 // trace: access 00540 const LoggingExecutor::TraceSample* LoggingExecutor::TraceRecent(void) const { 00541 if(mTraceBuffer.size()<2) return 0; 00542 return &mTraceBuffer[mTraceBuffer.size()-2]; 00543 } 00544 00545 // trace: access 00546 const LoggingExecutor::TraceSample* LoggingExecutor::TraceFirst(void) const { 00547 if(mTraceBuffer.size()<1) return 0; 00548 return &mTraceBuffer[0]; 00549 } 00550 00551 // trace: access 00552 int LoggingExecutor::TraceLength(void) const { 00553 return mTraceBuffer.size(); 00554 } 00555 00556 // trace: add empty sample 00557 void LoggingExecutor::TraceAddSample(void) { 00558 // initialize new sample 00559 TraceSample sample; 00560 sample.mState=CurrentParallelTimedState(); 00561 sample.mStep=CurrentStep(); 00562 sample.mTime=CurrentTime(); 00563 sample.mDuration=0; 00564 sample.mEvent=0; 00565 // add to buffer 00566 mTraceBuffer.push_back(sample); 00567 // drop first sample 00568 if(mTraceMax>0) 00569 while(mTraceBuffer.size()> (unsigned int) mTraceMax) 00570 mTraceBuffer.pop_front(); 00571 // fix timing 00572 if(mTraceMax>0) 00573 mTraceFirstStep=mTraceBuffer.front().mStep; 00574 // todo: time map 00575 } 00576 00577 // trace:: update after transition 00578 void LoggingExecutor::TraceUpdateTransition(Idx event) { 00579 // bail out 00580 if(mTraceMax==0) return; 00581 // fix last entry 00582 TraceSample& sample=mTraceBuffer.back(); 00583 sample.mEvent=event; 00584 sample.mDuration=CurrentTime()-sample.mTime; 00585 // add entry 00586 TraceAddSample(); 00587 } 00588 00589 // trace:: update time 00590 void LoggingExecutor::TraceUpdateTime(void) { 00591 // bail out 00592 if(mTraceMax==0) return; 00593 // fix last entry 00594 TraceSample& sample=mTraceBuffer.back(); 00595 sample.mDuration=CurrentTime()-sample.mTime; 00596 } 00597 00598 00599 00600 // trace: tokenwriter output 00601 void LoggingExecutor::TraceWrite(TokenWriter& rTw, const TraceSample& sample) const { 00602 rTw.WriteBegin("Sample"); 00603 rTw.WriteComment(" State " + PTSStr(sample.mState)); 00604 rTw << sample.mStep; 00605 rTw << sample.mTime; 00606 rTw << sample.mDuration; 00607 rTw << "\n"; 00608 if(sample.mEvent>0) 00609 rTw << EventName(sample.mEvent); 00610 rTw.WriteEnd("Sample"); 00611 } 00612 00613 // trace: console output 00614 void LoggingExecutor::TraceWrite(const TraceSample& sample) const { 00615 TokenWriter tw(TokenWriter::Stdout); 00616 TraceWrite(tw, sample); 00617 } 00618 00619 // trace: console output (all) 00620 void LoggingExecutor::TraceWrite() const { 00621 for(TraceIterator sit=TraceBegin(); sit!=TraceEnd(); sit++) { 00622 TraceWrite(*sit); 00623 }; 00624 } 00625 00626 // trace: string output 00627 std::string LoggingExecutor::TraceToString(const TraceSample& sample) const { 00628 TokenWriter tw(TokenWriter::String); 00629 TraceWrite(tw, sample); 00630 return tw.Str(); 00631 } 00632 00633 // Revert executors state to past step from buffer 00634 bool LoggingExecutor::RevertToStep(Idx step) { 00635 FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << ")"); 00636 bool res=true; 00637 const TraceSample* samplep = TraceAtStep(step); 00638 if(!samplep) return false; 00639 FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << "): found step"); 00640 // set state 00641 res=ParallelExecutor::CurrentParallelTimedState(samplep->mState); 00642 if(!res) return false; 00643 // care log trace 00644 LogWritePause(); 00645 // set time 00646 ParallelExecutor::CurrentTime(samplep->mTime); 00647 ParallelExecutor::CurrentStep(samplep->mStep); 00648 LogWriteResume(); 00649 // care trace: remove 00650 FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << "): fixing trace"); 00651 while(mTraceBuffer.size()>0) { 00652 const TraceSample& lsample= mTraceBuffer.back(); 00653 if(lsample.mStep<=step) break; 00654 mTraceBuffer.pop_back(); 00655 } 00656 // care trace: invalidate last sample 00657 if(mTraceBuffer.size()>0) { 00658 TraceSample& lsample= mTraceBuffer.back(); 00659 lsample.mEvent=0; 00660 lsample.mDuration=0; 00661 } 00662 // clear condition state 00663 mConditions.Reset(); 00664 FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << "): done"); 00665 return true; 00666 } 00667 00668 } // namespace faudes 00669 00670 |
libFAUDES 2.18b --- 2010-12-17 --- c++ source docu by doxygen 1.6.3