00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "sp_lpexecutor.h"
00014
00015 namespace faudes {
00016
00017
00018
00019 LoggingExecutor::LoggingExecutor(void)
00020 : ParallelExecutor(), pLogTokenWriter(0), mLogFile(""), mLogMode(0)
00021 {
00022 FD_DX("LoggingExecutor(" << this << ")::LoggingExecutor()");
00023 TraceClear(0);
00024 }
00025
00026
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
00035 LoggingExecutor::~LoggingExecutor(void) {
00036 FD_DX("LoggingExecutor(" << this << ")::~LoggingExecutor()");
00037 LogClose();
00038 }
00039
00040
00041 void LoggingExecutor::Compile(void) {
00042 FD_DX("LoggingExecutor(" << this << ")::Compile(): #" << Size());
00043
00044 ParallelExecutor::Compile();
00045
00046 CompileConditions();
00047 FD_DX("LoggingExecutor(" << this << ")::Compile(): done");
00048 }
00049
00050
00051 void LoggingExecutor::Reset(void) {
00052 FD_DX("LoggingExecutor(" << this << ")::Reset()");
00053
00054 LogWritePause();
00055
00056 ParallelExecutor::Reset();
00057
00058 LogWriteResume();
00059
00060 TraceClear();
00061
00062 ConditionsReset();
00063 }
00064
00065
00066
00067 void LoggingExecutor::Clear(void) {
00068 FD_DX("LoggingExecutor(" << this << ")::Clear()");
00069
00070 LogClose();
00071 mConditions.Clear();
00072 mBreakCondition=false;
00073 TraceClear();
00074
00075 ParallelExecutor::Clear();
00076 }
00077
00078
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
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.SeekBegin(label);
00096 while(!rTr.Eos(label)) {
00097
00098 Token token;
00099 rTr.Peek(token);
00100
00101 if(token.Type()==Token::Begin)
00102 if(token.StringValue()=="Generators") {
00103 ParallelExecutor::DoReadGenerators(rTr);
00104 continue;
00105 }
00106
00107 if(token.Type()==Token::Begin)
00108 if(token.StringValue()=="Conditions") {
00109 mConditions.Read(rTr,"Conditions",this);
00110 continue;
00111 }
00112
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.SeekEnd(label);
00118 Reset();
00119 }
00120
00121
00122
00123
00124 bool LoggingExecutor::ExecuteTime(tpTime::Type time) {
00125
00126 bool res=ParallelExecutor::ExecuteTime(time);
00127
00128 if(!res) return false;
00129
00130 TraceUpdateTime();
00131
00132 return res;
00133 }
00134
00135
00136 bool LoggingExecutor::ExecuteEvent(Idx event) {
00137
00138 bool res=ParallelExecutor::ExecuteEvent(event);
00139
00140 if(!res) return false;
00141
00142 ConditionsProcess();
00143
00144 LogWriteTime();
00145 LogWriteEvent();
00146 LogWriteState();
00147
00148 TraceUpdateTransition(event);
00149 return true;
00150 }
00151
00152
00153
00154 void LoggingExecutor::CurrentStep(int step) {
00155 FD_DX("LoggingExecutor(" << this << ")::CurrentStep(step)");
00156
00157 ParallelExecutor::CurrentStep(step);
00158
00159 TraceClear();
00160 mConditions.Reset();
00161 }
00162
00163
00164 void LoggingExecutor::CurrentTime(tpTime::Type time) {
00165 FD_DX("LoggingExecutor(" << this << ")::CurrentTime(time)");
00166
00167 ParallelExecutor::CurrentTime(time);
00168
00169 TraceClear();
00170 mConditions.Reset();
00171 }
00172
00173
00174 bool LoggingExecutor::CurrentParallelTimedState(const ParallelTimedState& ptstate) {
00175 FD_DX("LoggingExecutor(" << this << ")::CurrentParallelTimedState(ptstate)");
00176
00177 bool res=ParallelExecutor::CurrentParallelTimedState(ptstate);
00178
00179 TraceClear();
00180 ConditionsReset();
00181 return res;
00182 }
00183
00184
00185
00186
00187 const SimConditionSet& LoggingExecutor::Conditions(void) const {
00188 return mConditions;
00189 }
00190
00191
00192 void LoggingExecutor::Conditions(const SimConditionSet& rConditions) {
00193 mConditions=rConditions;
00194 CompileConditions();
00195 }
00196
00197
00198 const SimConditionAttribute& LoggingExecutor::Condition(const std::string& rName) const {
00199 return mConditions.Attribute(mConditions.Index(rName));
00200 }
00201
00202
00203 const SimConditionAttribute& LoggingExecutor::Condition(Idx cond) const {
00204 return mConditions.Attribute(cond);
00205 }
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 Idx LoggingExecutor::SetCondition(const std::string& rName, const SimConditionAttribute& rCondition) {
00223 Idx cond=mConditions.Insert(rName,rCondition);
00224 CompileConditions();
00225 return cond;
00226 }
00227
00228
00229 void LoggingExecutor::SetCondition(Idx cond, const SimConditionAttribute& rCondition) {
00230 mConditions.Insert(cond,rCondition);
00231 CompileConditions();
00232 }
00233
00234
00235 void LoggingExecutor::ClrCondition(const std::string& rName) {
00236 mConditions.Erase(rName);
00237 CompileConditions();
00238 }
00239
00240
00241 void LoggingExecutor::ClrCondition(Idx cond) {
00242 mConditions.Erase(cond);
00243 CompileConditions();
00244 }
00245
00246
00247 void LoggingExecutor::ConditionsWrite(TokenWriter& rTw, const std::string& rLabel) const {
00248 mConditions.Write(rTw,rLabel);
00249 }
00250
00251
00252 void LoggingExecutor::ConditionsRead(TokenReader& rTr, const std::string& rLabel) {
00253 mConditions.Read(rTr,rLabel);
00254 CompileConditions();
00255 }
00256
00257
00258
00259 LoggingExecutor::ConditionIterator LoggingExecutor::ConditionsBegin(void) const {
00260 return mConditions.Begin();
00261 }
00262
00263
00264 LoggingExecutor::ConditionIterator LoggingExecutor::ConditionsEnd(void) const {
00265 return mConditions.End();
00266 }
00267
00268
00269 void LoggingExecutor::CompileConditions(void) {
00270
00271 mEnabledConditions.clear();
00272 ConditionIterator cit=mConditions.Begin();
00273 for(; cit != mConditions.End(); ++cit) {
00274 SimConditionAttribute* pattr=mConditions.Attributep(*cit);
00275
00276 if(!pattr->IsEnabled()) continue;
00277
00278 if(pattr->IsStateCondition())
00279 if(pattr->StateCondition().mStateSets.size()!=Size()) continue;
00280
00281 mEnabledConditions.push_back(pattr);
00282 }
00283
00284 mConditions.Reset();
00285 mBreakCondition=false;
00286 FD_DX("LoggingExecutor(" << this << ")::CompileConditions(): #" << mEnabledConditions.size());
00287 }
00288
00289
00290 void LoggingExecutor::ConditionsReset(void) {
00291 FD_DX("LoggingExecutor(" << this << ")::ConditionsReset()");
00292 CompileConditions();
00293 ConditionsProcess();
00294 }
00295
00296
00297 void LoggingExecutor::ConditionsProcess(void) {
00298 FD_DX("LoggingExecutor(" << this << ")::ConditionsProcess()");
00299 mBreakCondition=false;
00300 std::vector<SimConditionAttribute*>::iterator ait=mEnabledConditions.begin();
00301
00302 for(; ait != mEnabledConditions.end(); ++ait) {
00303 SimConditionAttribute* pattr= *ait;
00304
00305 if(pattr->IsEventCondition()) {
00306
00307 if(!pattr->Satisfied())
00308 if(pattr->EventCondition().mStart.Exists(mRecentEvent)) {
00309 FD_DX("LoggingExecutor(" << this << ")::ConditionsProcess(): " <<
00310 mConditions.SymbolicName(**citit) << " satisfied");
00311 pattr->Satisfied(true,CurrentTime());
00312 if(pattr->IsBreakCondition()) mBreakCondition=true;
00313 }
00314
00315 if(pattr->Satisfied())
00316 if(pattr->EventCondition().mStop.Exists(mRecentEvent)) {
00317 FD_DX("LoggingExecutor(" << this << ")::ConditionsProcess(): " <<
00318 mConditions.SymbolicName(**citit) << " failed");
00319 pattr->Satisfied(false,CurrentTime());
00320 }
00321 continue;
00322 }
00323
00324 if(pattr->IsStateCondition()) {
00325
00326 bool satisfied;
00327 if(pattr->StateCondition().mAllFlag) {
00328
00329 satisfied=true;
00330 for(Idx i=0; i<Size(); i++) {
00331 Idx state = CurrentParallelState().at(i);
00332 const StateSet& set = pattr->StateCondition().mStateSets.at(i);
00333 if(set.Empty()) continue;
00334 if(!set.Exists(state)) {
00335 satisfied=false;
00336 break;
00337 }
00338 }
00339 } else {
00340
00341 satisfied=false;
00342 for(Idx i=0; i<Size(); i++) {
00343 Idx state = CurrentParallelState().at(i);
00344 if(pattr->StateCondition().mStateSets.at(i).Exists(state)) {
00345 satisfied=true;
00346 break;
00347 }
00348 }
00349 }
00350
00351 if(!pattr->Satisfied() && satisfied) {
00352 FD_DX("LoggingExecutor(" << this << ")::ConditionsProcess(): " <<
00353 mConditions.SymbolicName(**citit) << " satisfied");
00354 pattr->Satisfied(true,CurrentTime());
00355 if(pattr->IsBreakCondition()) mBreakCondition=true;
00356 }
00357 if(pattr->Satisfied() && !satisfied) {
00358 FD_DX("LoggingExecutor(" << this << ")::ConditionsProcess(): " <<
00359 mConditions.SymbolicName(**citit) << " failed");
00360 pattr->Satisfied(false,CurrentTime());
00361 }
00362 continue;
00363 }
00364 }
00365 }
00366
00367
00368
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
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
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
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<SimConditionAttribute*>::iterator ait=mEnabledConditions.begin();
00421 for(; ait != mEnabledConditions.end(); ++ait) {
00422 SimConditionAttribute* 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
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
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
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
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
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
00491 void LoggingExecutor::TraceClear(int length) {
00492 FD_DX("LoggingExecutor(" << this << ")::TraceClear(" << length <<")");
00493
00494 mTraceBuffer.clear();
00495 mTraceTimeToStep.clear();
00496
00497 if(length>-2) mTraceMax=length;
00498
00499 mTraceFirstStep=CurrentStep();
00500
00501 if(mTraceMax==0) return;
00502
00503 TraceAddSample();
00504 }
00505
00506
00507 LoggingExecutor::TraceIterator LoggingExecutor::TraceBegin(void) const {
00508 return mTraceBuffer.begin();
00509 }
00510
00511
00512 LoggingExecutor::TraceIterator LoggingExecutor::TraceEnd(void) const {
00513 return mTraceBuffer.end();
00514 }
00515
00516
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
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
00534 const LoggingExecutor::TraceSample* LoggingExecutor::TraceCurrent(void) const {
00535 if(mTraceBuffer.size()==0) return 0;
00536 return &mTraceBuffer.back();
00537 }
00538
00539
00540 const LoggingExecutor::TraceSample* LoggingExecutor::TraceRecent(void) const {
00541 if(mTraceBuffer.size()<2) return 0;
00542 return &mTraceBuffer[mTraceBuffer.size()-2];
00543 }
00544
00545
00546 void LoggingExecutor::TraceAddSample(void) {
00547
00548 TraceSample sample;
00549 sample.mState=CurrentParallelTimedState();
00550 sample.mStep=CurrentStep();
00551 sample.mTime=CurrentTime();
00552 sample.mDuration=0;
00553 sample.mEvent=0;
00554
00555 mTraceBuffer.push_back(sample);
00556
00557 if(mTraceMax>0)
00558 while(mTraceBuffer.size()> (unsigned int) mTraceMax)
00559 mTraceBuffer.pop_front();
00560
00561 if(mTraceMax>0)
00562 mTraceFirstStep=mTraceBuffer.front().mStep;
00563
00564 }
00565
00566
00567 void LoggingExecutor::TraceUpdateTransition(Idx event) {
00568
00569 if(mTraceMax==0) return;
00570
00571 TraceSample& sample=mTraceBuffer.back();
00572 sample.mEvent=event;
00573 sample.mDuration=CurrentTime()-sample.mTime;
00574
00575 TraceAddSample();
00576 }
00577
00578
00579 void LoggingExecutor::TraceUpdateTime(void) {
00580
00581 if(mTraceMax==0) return;
00582
00583 TraceSample& sample=mTraceBuffer.back();
00584 sample.mDuration=CurrentTime()-sample.mTime;
00585 }
00586
00587
00588
00589
00590 void LoggingExecutor::TraceWrite(TokenWriter& rTw, const TraceSample& sample) const {
00591 rTw.WriteBegin("Sample");
00592 rTw.WriteComment(" State " + PTSStr(sample.mState));
00593 rTw << sample.mStep;
00594 rTw << sample.mTime;
00595 rTw << sample.mDuration;
00596 rTw << "\n";
00597 if(sample.mEvent>0)
00598 rTw << EventName(sample.mEvent);
00599 rTw.WriteEnd("Sample");
00600 }
00601
00602
00603 void LoggingExecutor::TraceWrite(const TraceSample& sample) const {
00604 TokenWriter tw(TokenWriter::Stdout);
00605 TraceWrite(tw, sample);
00606 }
00607
00608
00609 void LoggingExecutor::TraceWrite() const {
00610 for(TraceIterator sit=TraceBegin(); sit!=TraceEnd(); sit++) {
00611 TraceWrite(*sit);
00612 };
00613 }
00614
00615
00616 std::string LoggingExecutor::TraceToString(const TraceSample& sample) const {
00617 TokenWriter tw(TokenWriter::String);
00618 TraceWrite(tw, sample);
00619 return tw.Str();
00620 }
00621
00622
00623 bool LoggingExecutor::RevertToStep(Idx step) {
00624 FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << ")");
00625 bool res=true;
00626 const TraceSample* samplep = TraceAtStep(step);
00627 if(!samplep) return false;
00628 FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << "): found step");
00629
00630 res=ParallelExecutor::CurrentParallelTimedState(samplep->mState);
00631 if(!res) return false;
00632
00633 LogWritePause();
00634
00635 ParallelExecutor::CurrentTime(samplep->mTime);
00636 ParallelExecutor::CurrentStep(samplep->mStep);
00637 LogWriteResume();
00638
00639 FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << "): fixing trace");
00640 while(mTraceBuffer.size()>0) {
00641 const TraceSample& lsample= mTraceBuffer.back();
00642 if(lsample.mStep<=step) break;
00643 mTraceBuffer.pop_back();
00644 }
00645
00646 if(mTraceBuffer.size()>0) {
00647 TraceSample& lsample= mTraceBuffer.back();
00648 lsample.mEvent=0;
00649 lsample.mDuration=0;
00650 }
00651
00652 mConditions.Reset();
00653 FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << "): done");
00654 return true;
00655 }
00656
00657 }
00658
00659