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