sp_lpexecutor.cpp
Go to the documentation of this file.
1/** @file sp_lpexecutor.cpp Executor with logging facilities */
2
3/*
4 FAU Discrete Event Systems Library (libfaudes)
5
6 Copyright (C) 2007, 2008 Thomas Moor
7 Copyright (C) 2007 Ruediger Berndt
8 Exclusive copyright is granted to Klaus Schmidt
9
10*/
11
12
13#include "sp_lpexecutor.h"
14
15namespace faudes {
16
17
18// std faudes type
19FAUDES_TYPE_IMPLEMENTATION(LoggingExecutor,LoggingExecutor,ParallelExecutor)
20
21// LoggingExecutor(void)
23 : ParallelExecutor(), pLogTokenWriter(0), mLogFile(""), mLogMode(0)
24{
25 FD_DX("LoggingExecutor(" << this << ")::LoggingExecutor()");
26 TraceClear(0);
27}
28
29// LoggingExecutor(void)
31 : ParallelExecutor(), pLogTokenWriter(0), mLogFile(""), mLogMode(0)
32{
33 FD_DX("LoggingExecutor(" << this << ")::LoggingExecutor()");
34 TraceClear(0);
35 DoAssign(rOther);
36}
37
38// LoggingExecutor(rFileName)
39LoggingExecutor::LoggingExecutor(const std::string& rFileName)
40 : ParallelExecutor(), pLogTokenWriter(0), mLogFile(""), mLogMode(0)
41{
42 FD_DX("LoggingExecutor(" << this << ")::LoggingExecutor(" << rFileName << ")");
43 TraceClear(0);
44 Read(rFileName);
45}
46
47// LoggingExecutor
49 FD_DX("LoggingExecutor(" << this << ")::~LoggingExecutor()");
50 LogClose();
51}
52
53// DoAssign(other)
55 FD_DX("LoggingExecutor(" << this << ")::DoAssign(other)");
56 // my members
58 // base
60}
61
62// Compile()
64 FD_DX("LoggingExecutor(" << this << ")::Compile(): #" << Size());
65 // call base
67 // care about my members
69 FD_DX("LoggingExecutor(" << this << ")::Compile(): done");
70}
71
72// Reset()
74 FD_DX("LoggingExecutor(" << this << ")::Reset()");
75 // log trace
77 // call base (incl compile)
79 // log trace
81 // clear and initialise trace (base was called first)
82 TraceClear();
83 // figure initial state
85}
86
87
88// Clear()
90 FD_DX("LoggingExecutor(" << this << ")::Clear()");
91 // clear my members
92 LogClose();
94 mBreakCondition=false;
95 TraceClear();
96 // call base
98}
99
100//DoWrite(rTr,rLabel)
101void LoggingExecutor::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
102 (void) pContext;
103 std::string label=rLabel;
104 if(label=="") label = "Executor";
105 rTw.WriteBegin(label);
106 ParallelExecutor::DoWrite(rTw,"Generators");
107 mConditions.Write(rTw,"Conditions",this);
108 rTw.WriteEnd(label);
109}
110
111//DoRead(rTr,rLabel)
112void LoggingExecutor::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
113 (void) pContext;
114 FD_DC("LoggingExecutor::DoRead(rTr, " << rLabel<<")");
115 std::string label=rLabel;
116 if(label=="") label = "Executor";
117 rTr.ReadBegin(label);
118 while(!rTr.Eos(label)) {
119 // peek token
120 Token token;
121 rTr.Peek(token);
122 // case 1: generators
123 if(token.Type()==Token::Begin)
124 if(token.StringValue()=="Generators") {
126 continue;
127 }
128 // case 2: conditions
129 if(token.Type()==Token::Begin)
130 if(token.StringValue()=="Conditions") {
131 mConditions.Read(rTr,"Conditions",this);
132 continue;
133 }
134 // else report error
135 std::stringstream errstr;
136 errstr << "Invalid token, generators or conditions section expected, " << rTr.FileLine();
137 throw Exception("LoggingExecutor::DoRead", errstr.str(), 502);
138 }
139 rTr.ReadEnd(label);
140 Reset();
141}
142
143
144
145// ExecuteTime(time)
147 // call base
148 bool res=ParallelExecutor::ExecuteTime(time);
149 // bail out
150 if(!res) return false;
151 // update trace (after base)
153 // done
154 return res;
155}
156
157// ExecuteEvent(event)
159 // call base
160 bool res=ParallelExecutor::ExecuteEvent(event);
161 // bail out
162 if(!res) return false;
163 // process conditions
165 // record log
166 LogWriteTime();
169 // record trace
171 return true;
172}
173
174
175// set logic time
177 FD_DX("LoggingExecutor(" << this << ")::CurrentStep(step)");
178 // call base
180 // clear trace
181 TraceClear();
183}
184
185// set physical time
187 FD_DX("LoggingExecutor(" << this << ")::CurrentTime(time)");
188 // call base
190 // clear trace
191 TraceClear();
193}
194
195// set current state (clear trace)
197 FD_DX("LoggingExecutor(" << this << ")::CurrentParallelTimedState(ptstate)");
198 // call base
200 // clear trace
201 TraceClear();
203 return res;
204}
205
206
207
208// get conditions
210 return mConditions;
211}
212
213// set conditions
215 FD_DC("ProposingExecutor::DoRead(rTr,): loop X");
216 mConditions=rConditions;
217 FD_DC("ProposingExecutor::DoRead(rTr, ): loop Y");
219 FD_DC("ProposingExecutor::DoRead(rTr, loop Z");
220}
221
222// get condition
223const AttributeSimCondition& LoggingExecutor::Condition(const std::string& rName) const {
224 return mConditions.Attribute(mConditions.Index(rName));
225}
226
227// get condition
231
232/*
233// get condition pointer
234AttributeSimCondition* LoggingExecutor::Conditionp(const std::string& rName) {
235 return mConditions.Attributep(mConditions.Index(rName));
236}
237*/
238
239/*
240// get condition pointer
241AttributeSimCondition* LoggingExecutor::Conditionp(Idx cond) {
242 return mConditions.Attributep(cond);
243}
244*/
245
246// add/edit one condition
247Idx LoggingExecutor::SetCondition(const std::string& rName, const AttributeSimCondition& rCondition) {
248 Idx cond=mConditions.Insert(rName,rCondition);
250 return cond;
251}
252
253// edit one condition
255 mConditions.Insert(cond,rCondition);
257}
258
259// remove condition
260void LoggingExecutor::ClrCondition(const std::string& rName) {
261 mConditions.Erase(rName);
263}
264
265// remove condition
270
271// token io
272void LoggingExecutor::ConditionsWrite(TokenWriter& rTw, const std::string& rLabel) const {
273 mConditions.Write(rTw,rLabel);
274}
275
276// token io
277void LoggingExecutor::ConditionsRead(TokenReader& rTr, const std::string& rLabel) {
278 mConditions.Read(rTr,rLabel);
280}
281
282
283// iterators
287
288// iterators
292
293// set up internal datastructure
295 FD_DX("LoggingExecutor::CompileConditions()");
296 // need a lock to prevent realocation of attributes
298 // have a minmal copy to avoid pointless iterations
299 mEnabledConditions.clear();
301 for(; cit != mConditions.End(); ++cit) {
302 FD_DX("LoggingExecutor::CompileConditions(): compile " << mConditions.Str(*cit));
305 // reject if not enabled
306 if(!pattr->Enabled()) continue;
307 // reject incompatible dims
308 if(pattr->IsStateCondition())
309 if(pattr->StateCondition().mStateSets.size()!=Size()) continue;
310 // have it
311 mEnabledConditions.push_back(pattr);
312 }
313 // reset all states (incl disabled)
315 mBreakCondition=false;
316 FD_DX("LoggingExecutor(" << this << ")::CompileConditions(): #" << mEnabledConditions.size());
317}
318
319// logging: reset
321 FD_DX("LoggingExecutor(" << this << ")::ConditionsReset()");
324}
325
326// logging: test
328 FD_DX("LoggingExecutor(" << this << ")::ConditionsProcess()");
329 mBreakCondition=false;
330 std::vector<AttributeSimCondition*>::iterator ait=mEnabledConditions.begin();
331 // loop over all enabled conditions
332 for(; ait != mEnabledConditions.end(); ++ait) {
333 AttributeSimCondition* pattr= *ait;
334 // case 1: event condition
335 if(pattr->IsEventCondition()) {
336 // positive edge
337 if(!pattr->Satisfied())
338 if(pattr->EventCondition().mStart.Exists(mRecentEvent)) {
339 pattr->Satisfied(true,CurrentTime());
340 if(pattr->Breakpoint()) mBreakCondition=true;
341 }
342 // negative edge
343 if(pattr->Satisfied())
344 if(pattr->EventCondition().mStop.Exists(mRecentEvent)) {
345 pattr->Satisfied(false,CurrentTime());
346 }
347 continue;
348 }
349 // case 2: state condition
350 if(pattr->IsStateCondition()) {
351 // stage a: figure state
352 bool satisfied;
353 if(pattr->StateCondition().mAllFlag) {
354 // conjunctive
355 satisfied=true;
356 for(Idx i=0; i<Size(); i++) {
357 Idx state = CurrentParallelState().at(i);
358 const StateSet& set = pattr->StateCondition().mStateSets.at(i);
359 if(set.Empty()) continue;
360 if(!set.Exists(state)) {
361 satisfied=false;
362 break;
363 }
364 }
365 } else {
366 // disjunctive
367 satisfied=false;
368 for(Idx i=0; i<Size(); i++) {
369 Idx state = CurrentParallelState().at(i);
370 if(pattr->StateCondition().mStateSets.at(i).Exists(state)) {
371 satisfied=true;
372 break;
373 }
374 }
375 }
376 // state b: figure edge
377 if(!pattr->Satisfied() && satisfied) {
378 pattr->Satisfied(true,CurrentTime());
379 if(pattr->Breakpoint()) mBreakCondition=true;
380 }
381 if(pattr->Satisfied() && !satisfied) {
382 pattr->Satisfied(false,CurrentTime());
383 }
384 continue;
385 }
386 } // loop conditions
387}
388
389
390// logging io: start
391void LoggingExecutor::LogOpen(TokenWriter& rTw, int logmode) {
392 FD_DX("LoggingExecutor(" << this << ")::LogOpen()");
393 pLogTokenWriter= &rTw;
394 mLogFile="";
395 mLogMode=logmode;
396 pLogTokenWriter->WriteBegin("ExecutionLog");
402 pLogTokenWriter->WriteEnd("Mode");
403 LogWriteTime();
405}
406
407// logging io: start
408void LoggingExecutor::LogOpen(const std::string& rFileName, int logmode, std::ios::openmode openmode) {
409 FD_DX("LoggingExecutor(" << this << ")::LogOpen(" << rFileName << ")");
410 pLogTokenWriter= new TokenWriter(rFileName,openmode);
411 LogOpen(*pLogTokenWriter, logmode);
412 mLogFile=rFileName;
413}
414
415
416// logging io: stop
418 if(mLogMode & LogStatistics) {
420 }
421 if(mLogMode != 0) {
422 FD_DX("LoggingExecutor(" << this << ")::LogClose(" << mLogFile << ")");
423 *pLogTokenWriter << "\n";
424 *pLogTokenWriter << "\n";
425 pLogTokenWriter->WriteEnd("ExecutionLog");
426 }
427 if(mLogFile!="") {
428 delete pLogTokenWriter;
429 }
430 mLogFile="";
432 mLogMode=0;
433}
434
435// logging: report statistics
437 if(!(mLogMode & LogStatistics)) return;
438 FD_DX("LoggingExecutor(" << this << ")::LogWriteStatistics()");
439 *pLogTokenWriter << "\n";
440 *pLogTokenWriter << "\n";
441 pLogTokenWriter->WriteBegin("Statistics");
442 std::vector<AttributeSimCondition*>::iterator ait=mEnabledConditions.begin();
443 for(; ait != mEnabledConditions.end(); ++ait) {
444 AttributeSimCondition* pattr= *ait;
445 pattr->mSamplesPeriod.Compile();
447 pattr->mSamplesDuration.Compile();
449 *pLogTokenWriter << "\n";
450 }
451 pLogTokenWriter->WriteEnd("Statistics");
452 *pLogTokenWriter << "\n";
453 *pLogTokenWriter << "\n";
454}
455
456// logging: report state
458 if(!(mLogMode & LogStates)) return;
459 if(mLogMode & LogTime) {
460 CurrentParallelTimedState().Write(*pLogTokenWriter,"TimedState",this);
461 } else
462 CurrentParallelTimedState().Write(*pLogTokenWriter,"DiscreteState",this);
463 *pLogTokenWriter << "\n";
464}
465
466// logging: report event
468 if(!(mLogMode & LogEvents)) return;
469 if(!(mLogMode & LogStates)) {
471 *pLogTokenWriter << "\n";
472 } else {
473 pLogTokenWriter->WriteBegin("Event");
475 pLogTokenWriter->WriteEnd("Event");
476 }
477}
478
479// loggging report time
481 if(!(mLogMode & LogTime)) return;
482 if(!(mLogMode & LogStates)) {
484 *pLogTokenWriter << "\n";
485 } else {
488 pLogTokenWriter->WriteEnd("Time");
489 }
490}
491
492// logging: pause
494 FD_DX("LoggingExecutor(" << this << ")::LogWritePause()");
495 if(mLogMode == 0) return;
497 *pLogTokenWriter << "\n";
498 pLogTokenWriter->WriteEnd("ExecutionLog");
499 *pLogTokenWriter << "\n";
500 *pLogTokenWriter << "\n";
501 *pLogTokenWriter << "\n";
502}
503
504// logging report pause
506 FD_DX("LoggingExecutor(" << this << ")::LogWriteResume()");
507 if(mLogMode == 0) return;
508 pLogTokenWriter->WriteBegin("ExecutionLog");
510}
511
512// trace: clear all
514 FD_DX("LoggingExecutor(" << this << ")::TraceClear(" << length <<")");
515 // clear
516 mTraceBuffer.clear();
517 mTraceTimeToStep.clear();
518 // set max length
519 if(length>-2) mTraceMax=length;
520 // set first step
522 // bail out
523 if(mTraceMax==0) return;
524 // set first entry
526}
527
528// trace: access
532
533// trace: access
537
538// trace: access
540 int n = step-mTraceFirstStep;
541 if(n<0) return 0;
542 if(((unsigned int)n)>=mTraceBuffer.size()) return 0;
543 return &mTraceBuffer[n];
544}
545
546// trace: access
548 std::map<Time::Type,int>::const_iterator sit=mTraceTimeToStep.find(time);
549 if(sit== mTraceTimeToStep.end())
550 return 0;
551 int step = sit->second;
552 return TraceAtStep(step);
553}
554
555// trace: access
557 if(mTraceBuffer.size()==0) return 0;
558 return &mTraceBuffer.back();
559}
560
561// trace: access
563 if(mTraceBuffer.size()<2) return 0;
564 return &mTraceBuffer[mTraceBuffer.size()-2];
565}
566
567// trace: access
569 if(mTraceBuffer.size()<1) return 0;
570 return &mTraceBuffer[0];
571}
572
573// trace: access
575 return mTraceBuffer.size();
576}
577
578// trace: add empty sample
580 // initialize new sample
581 TraceSample sample;
583 sample.mStep=CurrentStep();
584 sample.mTime=CurrentTime();
585 sample.mDuration=0;
586 sample.mEvent=0;
587 // add to buffer
588 mTraceBuffer.push_back(sample);
589 // drop first sample
590 if(mTraceMax>0)
591 while(mTraceBuffer.size()> (unsigned int) mTraceMax)
592 mTraceBuffer.pop_front();
593 // fix timing
594 if(mTraceMax>0)
595 mTraceFirstStep=mTraceBuffer.front().mStep;
596 // todo: time map
597}
598
599// trace:: update after transition
601 // bail out
602 if(mTraceMax==0) return;
603 // fix last entry
604 TraceSample& sample=mTraceBuffer.back();
605 sample.mEvent=event;
606 sample.mDuration=CurrentTime()-sample.mTime;
607 // add entry
609}
610
611// trace:: update time
613 // bail out
614 if(mTraceMax==0) return;
615 // fix last entry
616 TraceSample& sample=mTraceBuffer.back();
617 sample.mDuration=CurrentTime()-sample.mTime;
618}
619
620
621
622// trace: tokenwriter output
623void LoggingExecutor::TraceWrite(TokenWriter& rTw, const TraceSample& sample) const {
624 rTw.WriteBegin("Sample");
625 rTw.WriteComment(" State " + PTSStr(sample.mState));
626 rTw << sample.mStep;
627 rTw << sample.mTime;
628 rTw << sample.mDuration;
629 rTw << "\n";
630 if(sample.mEvent>0)
631 rTw << EventName(sample.mEvent);
632 rTw.WriteEnd("Sample");
633}
634
635// trace: console output
636void LoggingExecutor::TraceWrite(const TraceSample& sample) const {
638 TraceWrite(tw, sample);
639}
640
641// trace: console output (all)
643 for(TraceIterator sit=TraceBegin(); sit!=TraceEnd(); sit++) {
644 TraceWrite(*sit);
645 };
646}
647
648// trace: string output
649std::string LoggingExecutor::TraceToString(const TraceSample& sample) const {
651 TraceWrite(tw, sample);
652 return tw.Str();
653}
654
655// Revert executors state to past step from buffer
657 FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << ")");
658 bool res=true;
659 const TraceSample* samplep = TraceAtStep(step);
660 if(!samplep) return false;
661 FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << "): found step");
662 // set state
664 if(!res) return false;
665 // care log trace
667 // set time
671 // care trace: remove
672 FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << "): fixing trace");
673 while(mTraceBuffer.size()>0) {
674 const TraceSample& lsample= mTraceBuffer.back();
675 if(lsample.mStep<=step) break;
676 mTraceBuffer.pop_back();
677 }
678 // care trace: invalidate last sample
679 if(mTraceBuffer.size()>0) {
680 TraceSample& lsample= mTraceBuffer.back();
681 lsample.mEvent=0;
682 lsample.mDuration=0;
683 }
684 // clear condition state
686 FD_DX("LoggingExecutor(" << this << ")::RevertToStep("<< step << "): done");
687 return true;
688}
689
690} // namespace faudes
691
692
#define FD_DC(message)
#define FAUDES_TYPE_IMPLEMENTATION(ftype, ctype, cbase)
Definition cfl_types.h:958
void StateCondition(const SimStateCondition &rStateConditionAttribute)
void EventCondition(const SimEventCondition &rEventConditionAttribute)
SampledDensityFunction mSamplesDuration
SampledDensityFunction mSamplesPeriod
void Write(TokenWriter &rTw) const
void TraceClear(int length=-2)
std::deque< TraceSample >::const_iterator TraceIterator
virtual ~LoggingExecutor(void)
std::vector< AttributeSimCondition * > mEnabledConditions
Idx SetCondition(const std::string &rName, const AttributeSimCondition &rCondition)
TraceIterator TraceEnd(void) const
virtual bool RevertToStep(Idx step)
const ParallelTimedState & CurrentParallelTimedState(void) const
virtual void DoWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
std::map< Time::Type, int > mTraceTimeToStep
int TraceLength(void) const
const TraceSample * TraceAtTime(Time::Type time) const
const TraceSample * TraceRecent(void) const
void DoAssign(const LoggingExecutor &rSrc)
ConditionIterator ConditionsEnd(void) const
virtual void Clear(void)
virtual void DoRead(TokenReader &rTr, const std::string &rLabel="", const Type *pContext=0)
virtual bool ExecuteTime(Time::Type duration)
void TraceWrite(void) const
const SimConditionSet & Conditions(void) const
SimConditionSet::Iterator ConditionIterator
void ConditionsRead(TokenReader &rTr, const std::string &rLabel="SimConditions")
int CurrentStep(void) const
const TraceSample * TraceFirst(void) const
const TraceSample * TraceAtStep(int step) const
void LogOpen(TokenWriter &rTw, int mode)
virtual bool ExecuteEvent(Idx event)
void ConditionsWrite(TokenWriter &rTw, const std::string &rLabel="SimConditions") const
SimConditionSet mConditions
std::string TraceToString(const TraceSample &sample) const
TokenWriter * pLogTokenWriter
Time::Type CurrentTime(void) const
virtual void Reset(void)
ConditionIterator ConditionsBegin(void) const
void ClrCondition(const std::string &rName)
void TraceUpdateTransition(Idx event)
TraceIterator TraceBegin(void) const
const AttributeSimCondition & Condition(const std::string &rName) const
const TraceSample * TraceCurrent(void) const
std::deque< TraceSample > mTraceBuffer
Idx Index(const std::string &rName) const
virtual void DoWrite(TokenWriter &rTw, const std::string &rLabel="", const Type *pContext=0) const
Time::Type CurrentTime(void) const
const ParallelState & CurrentParallelState(void) const
virtual bool ExecuteTime(Time::Type duration)
const ParallelTimedState & CurrentParallelTimedState(void) const
int CurrentStep(void) const
std::string PTSStr(const ParallelTimedState &ptstate) const
virtual void Clear(void)
virtual bool ExecuteEvent(Idx event)
virtual void Reset(void)
virtual void DoReadGenerators(TokenReader &rTr)
const EventSet & Alphabet(void) const
void DoAssign(const ParallelExecutor &rSrc)
std::string EventName(Idx index) const
virtual bool Insert(const Idx &rIndex)
Attr * Attributep(const Idx &rElem)
virtual std::string Str(const Idx &rIndex) const
const Attr & Attribute(const Idx &rElem) const
virtual bool Erase(const Idx &rIndex)
virtual TaNameSet & Assign(const TBaseSet< Idx > &rSrc)
std::string FileLine(void) const
bool Eos(const std::string &rLabel)
void ReadEnd(const std::string &rLabel)
void ReadBegin(const std::string &rLabel)
bool Peek(Token &token)
std::string Str(void)
void WriteFloat(const double &val)
void WriteComment(const std::string &rComment)
void WriteString(const std::string &rString)
void WriteEnd(const std::string &rLabel)
void WriteBegin(const std::string &rLabel)
void WriteOption(const std::string &rOpt)
const std::string & StringValue(void) const
@ Begin
<label> (begin of section)
Definition cfl_token.h:84
TokenType Type(void) const
void Read(const std::string &rFileName, const std::string &rLabel="", const Type *pContext=0)
void Write(const Type *pContext=0) const
void Lock(void) const
bool Empty(void) const
bool Exists(const T &rElem) const
virtual void Clear(void)
Iterator End(void) const
Iterator Begin(void) const
void DValid(const std::string &rMessage="") const
uint32_t Idx
#define FD_DX(message)
Definition sp_executor.h:27

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen