sp_lpexecutor.h
Go to the documentation of this file.
1 /** @file sp_lpexecutor.h 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 #ifndef FAUDES_LPEXECUTOR_H
14 #define FAUDES_LPEXECUTOR_H
15 
16 
17 #include "corefaudes.h"
18 #include "tp_include.h"
19 #include "sp_pexecutor.h"
20 #include "sp_simconditionset.h"
21 
22 
23 namespace faudes {
24 
25 /**
26  * Executor with logging facilities.
27  *
28  * \section SecSimulatorLPEX1 Logging to Token IO
29  *
30  * Logging destination in general is a TokenWriter, which may be initialised to a
31  * file or console output.
32  * Logging can be configured to include
33  * - the external behaviour (timed event sequence),
34  * - the internal behaviour (state sequence) and/or
35  * - timing statistics of conditions specified by AttributeSimCondition.
36  *
37  *
38  * \section SecSimulatorLPEX2 Logging to Internal FIFO Buffer
39  *
40  * The state- and event-sequence can be logged to a internal FIFO Buffer.
41  * Methods to revert to a previous state are provided. This feature is meant to
42  * facilitate user interaction in simulator applications.
43  *
44  * Technical detail: since the trace buffer only covers the dynamic state of the parallel executor,
45  * the RevertToStep method cannot recover the condition status. Including stochastic states
46  * with the trace buffer is considered to expensive.
47  *
48  * \section SecSimulatorLPEX3 File IO
49  *
50  * For token IO, the LoggingExecutor reads and writes a section with default label
51  * "Executor". It contains a ParallelExecutor section to define a vector of generators and
52  * a SimConditionSet section to define the relevant conditions. Example:
53  *
54  * \code
55  * <Executor>
56  *
57  * <Generators>
58  * "./some_generator.gen"
59  * "./other_generator.gen"
60  * </Generators>
61  *
62  * <Conditions>
63  *
64  * "IdleCond"
65  * <EventCondition>
66  * <StartEvents> "beta" "mue" </StartEvents>
67  * <StopEvents> "alpha" </StopEvents>
68  * </EventCondition>
69  *
70  * "DownCond"
71  * <StateCondition>
72  * <StateSet> "down" </StateSet> % refers to first generator
73  * <StateSet> "down" "repair" </StateSet> % refers to second generator
74  * </StateCondition>
75  *
76  * </Conditions>
77  *
78  * </Executor>
79  * \endcode
80  *
81  *
82  * @ingroup SimulatorPlugin
83  */
84 
86 
88 
89  public:
90 
91  /*****************************************
92  *****************************************
93  *****************************************
94  *****************************************/
95 
96  /** @name Constructors & Destructor */
97  /** @{ doxygen group */
98 
99 
100  /**
101  * Construct an emtpy LoggingExecuter
102  */
103  LoggingExecutor(void);
104 
105  /**
106  * Copy constructor
107  */
108  LoggingExecutor(const LoggingExecutor& rOther);
109 
110  /**
111  * Construct from file.
112  *
113  * See ParallelExecutor::Insert(const std::string& rFileName) for details.
114  *
115  * @param rFileName
116  * Filename
117  *
118  * @exception Exception
119  * - Non-deteministic generator (id 501)
120  * - IO errors (id 1)
121  * - token mismatch (id see TimedGenerator)
122  */
123  LoggingExecutor(const std::string& rFileName);
124 
125 
126  /**
127  * Explicit destructor.
128  */
129  virtual ~LoggingExecutor(void);
130 
131 
132  /** @} doxygen group */
133 
134  /*****************************************
135  *****************************************
136  *****************************************
137  *****************************************/
138 
139  /** @name Re-implemenented from ParallelExecutor */
140  /** @{ doxygen group */
141 
142  /**
143  * Clear all data. Removes all generators/executors, all conditions, and resets the
144  * current state to a void value.
145  *
146  */
147  virtual void Clear(void);
148 
149  /**
150  * Goto initial state. Reset all clock values to zero, assign initial states to each executor,
151  * reset condition states to not-satisfied, invalidate timing samples.
152  */
153  virtual void Reset(void);
154 
155  /**
156  * Check validity of executors.
157  *
158  * This is currently not implemented. It should
159  * include tests on the state based conditions.
160  *
161  * @return
162  * True on success
163  */
164  virtual bool Valid(void) const {return true;};
165 
166  /**
167  * Let time pass without executing a transition.
168  * Return false if the specified duration
169  * cannot elapse without an event being executed.
170  *
171  * @param duration
172  * Amount of time that shall elapse.
173  * @return
174  * True for success
175  */
176  virtual bool ExecuteTime(Time::Type duration);
177 
178  /**
179  * Execute transition.
180  *
181  * Returns false if the transition
182  * cannot be executed at the current time.
183  *
184  * @param event
185  * Indicate transition to execute
186  * @return
187  * True on success
188  */
189  virtual bool ExecuteEvent(Idx event);
190 
191 
192  /**
193  * Get clock time.
194  *
195  */
197 
198  /**
199  * Set clock time.
200  * This does not affect clocks and, hence, is purely cosmetic.
201  * The trace buffer is cleared. You should pause/resume logging
202  * befor/after interfering with the executors state.
203  *
204  * @param time
205  * New clock time
206  */
207  void CurrentTime(Time::Type time);
208 
209  /**
210  * Get logical time, ie number of transitions so far,
211  *
212  */
213  int CurrentStep(void) const { return ParallelExecutor::CurrentStep();};
214 
215  /**
216  * Set logical time (# of steps)
217  *
218  * This does not affect clocks and, hence, is purely cosmetic.
219  * Note that, in contrast to clock time, the individual
220  * generators do not agree in logical time.
221  * The trace buffer is cleared. You should pause/resume logging
222  * befor/after interfering with the executors state.
223  *
224  * @param step
225  * New logical time
226  */
227  void CurrentStep(int step);
228 
229  /**
230  * Set current state of the ParallelExecutor.
231  *
232  * This resets the parallel executor to the given state, incl clock values.
233  * The trace buffer is cleared. You should pause/resume logging
234  * befor/after interfering with the executors state.
235  *
236  * @return
237  * True for success
238  */
239  bool CurrentParallelTimedState(const ParallelTimedState& ptstate);
240 
241  /**
242  * Get current state of the ParallelExecutor.
243  *
244  *
245  * @return
246  * Discrete state vector and clock value maps
247  */
250 
251  /** @} doxygen group */
252 
253  /*****************************************
254  *****************************************
255  *****************************************
256  *****************************************/
257 
258  /** @name Simulation Conditions */
259  /** @{ doxygen group */
260 
261  /** Read-only access to simulation conditions */
262  const SimConditionSet& Conditions(void) const;
263 
264  /** Set all simulation conditions */
265  void Conditions(const SimConditionSet&);
266 
267  /** Read-only access to a simulation condition by name */
268  const AttributeSimCondition& Condition(const std::string& rName) const;
269 
270  /** Read-only access to a simulation condition by index */
271  const AttributeSimCondition& Condition(Idx cond) const;
272 
273  /** Set (or add) a condition by name */
274  Idx SetCondition(const std::string& rName, const AttributeSimCondition& rCondition);
275 
276  /** Set a condition by index */
277  void SetCondition(Idx cond, const AttributeSimCondition& rCondition);
278 
279  /** Remove a condition by name */
280  void ClrCondition(const std::string& rName);
281 
282  /** Remove a condition by index */
283  void ClrCondition(Idx cond);
284 
285  /** Write conditions so labled section */
286  void ConditionsWrite(TokenWriter& rTw, const std::string& rLabel="SimConditions") const;
287 
288  /** Read conditions from labled section */
289  void ConditionsRead(TokenReader& rTr, const std::string& rLabel="SimConditions");
290 
291  /** Condition iterator: typedef */
292  typedef SimConditionSet::Iterator ConditionIterator;
293 
294  /** Condition iterator: begin */
295  ConditionIterator ConditionsBegin(void) const;
296 
297  /** Condition iterator: end */
298  ConditionIterator ConditionsEnd(void) const;
299 
300  /** Simulation state: true if some break condition is currently satisfied */
301  bool BreakCondition(void) const {return mBreakCondition;};
302 
303  /** @} doxygen group */
304 
305  /*****************************************
306  *****************************************
307  *****************************************
308  *****************************************/
309 
310  /** @name Logging to Token I/O */
311  /** @{ doxygen group */
312 
313  /** Logging mode flags, to specify what data to log */
314  typedef enum { LogStatistics=0x01, LogStates=0x02, LogEvents=0x04, LogTime=0x08} LogMode;
315 
316  /** Start logging to TokenWriter */
317  void LogOpen(TokenWriter& rTw, int mode);
318 
319  /** Start logging to file */
320  void LogOpen(const std::string& rFileName, int logmode, std::ios::openmode openmode = std::ios::out|std::ios::trunc);
321 
322  /** Stop logging */
323  void LogClose(void);
324 
325  /** @} doxygen group */
326 
327  /*****************************************
328  *****************************************
329  *****************************************
330  *****************************************/
331 
332  /** @name Trace to FIFO buffer */
333  /** @{ doxygen group */
334 
335  /**
336  * Clear buffer and set max buffer
337  *
338  * @param length
339  * Max length of buffer, or: -2 <> keep length, -1<>infinite, 0<> no buffer
340  */
341  void TraceClear(int length=-2);
342 
343  /** Buffer data entry */
344  typedef struct {
345  ParallelTimedState mState; //// state of pexecutor
346  Idx mStep; //// faudes step (no of event to occur)
347  Time::Type mTime; //// faudes time (when entered mState)
348  Time::Type mDuration; //// faudes duration (how long we reside mState);
349  Idx mEvent; //// event index (if an event occured, else 0)
350  } TraceSample;
351 
352  /** Access buffer: current length */
353  int TraceLength(void) const;
354 
355  /** Access buffer: iterator */
356  typedef std::deque<TraceSample>::const_iterator TraceIterator;
357 
358  /** Condition iterator: begin */
359  TraceIterator TraceBegin(void) const;
360 
361  /** Condition iterator: end */
362  TraceIterator TraceEnd(void) const;
363 
364  /** Access buffer: sample by faudes time (returns first sample) */
365  const TraceSample* TraceAtTime(Time::Type time) const;
366 
367  /** Access buffer: sample by step */
368  const TraceSample* TraceAtStep(int step) const;
369 
370  /** Access buffer: first sample */
371  const TraceSample* TraceFirst(void) const;
372 
373  /** Access buffer: recent sample */
374  const TraceSample* TraceRecent(void) const;
375 
376  /** Access buffer: current sample */
377  const TraceSample* TraceCurrent(void) const;
378 
379  /** Access buffer: tokenwriter output */
380  void TraceWrite(TokenWriter& rTw, const TraceSample& sample) const;
381 
382  /** Access buffer: console output */
383  void TraceWrite(const TraceSample& sample) const;
384 
385  /** Access buffer: convert to string */
386  std::string TraceToString(const TraceSample& sample) const;
387 
388  /** Access buffer: console output (list all) */
389  void TraceWrite(void) const;
390 
391  /** Revert executors state to past step from buffer */
392  virtual bool RevertToStep(Idx step);
393 
394 
395  /** @} doxygen group */
396 
397 protected:
398 
399  /** Compile internal data (all) */
400  virtual void Compile();
401 
402  /**
403  * Reads logging executor from TokenReader, see also public wrappers in faudes::Type.
404  *
405  * @param rTr
406  * TokenReader to read from
407  * @param rLabel
408  * Section to read, defaults to "Executor"
409  * @param pContext
410  * Read context to provide contextual information (ignored)
411  *
412  * @exception Exception
413  * - non-deterministic generator(s) (id 501)
414  * - token mismatch (id 502)
415  * - IO error (id 1)
416  */
417  virtual void DoRead(TokenReader& rTr, const std::string& rLabel = "", const Type* pContext=0);
418 
419  /**
420  * Write to TokenWriter, see also public wrappers in faudes::Type.
421  *
422  * @param rTw
423  * Reference to TokenWriter
424  * @param rLabel
425  * Label of section to write, defaults to "Executor"
426  * @param pContext
427  * Write context to provide contextual information (ignored)
428  *
429  * @exception Exception
430  * - IO errors (id 2)
431  */
432  virtual void DoWrite(TokenWriter& rTw, const std::string& rLabel="", const Type* pContext=0) const;
433 
434  /**
435  * Assignment method
436  *
437  * @param rSrc
438  * Source to assign from
439  */
440  void DoAssign(const LoggingExecutor& rSrc);
441 
442 
443 private:
444 
445 
446  /** Simulation conditions */
448 
449  /** Enabled simulation conditions */
450  std::vector<AttributeSimCondition*> mEnabledConditions;
451 
452  /** Indicate break */
454 
455  /** Compile condition internal data */
456  void CompileConditions(void);
457 
458  /** Reset condition simulation state */
459  void ConditionsReset(void);
460 
461  /** Process condition hook */
462  void ConditionsProcess(void);
463 
464  /** Logging: tokenwriter ref */
466 
467  /** Logging: file name */
468  std::string mLogFile;
469 
470  /** Logging: mode */
471  int mLogMode;
472 
473  /** Logging hook: dump statistics */
474  void LogWriteStatistics(void);
475 
476  /** Logging hook: dump current state */
477  void LogWriteState(void);
478 
479  /** Logging hook: dump recent event */
480  void LogWriteEvent(void);
481 
482  /** Logging hook: dump current time */
483  void LogWriteTime(void);
484 
485  /** Logging hook: halt simulation */
486  void LogWritePause(void);
487 
488  /** Logging hook: continue simulation */
489  void LogWriteResume(void);
490 
491  /** Trace data: max fifo length */
493 
494  /** Trace data: step no of first sample */
496 
497  /** Trace data: fifo buffer */
498  std::deque<TraceSample> mTraceBuffer;
499 
500  /** Trace data: time to step mapping (first step) */
501  std::map<Time::Type,int> mTraceTimeToStep;
502 
503  /** Trace: helper, append one void sample */
504  void TraceAddSample(void);
505 
506  /** Trace: append sample (if necessary) and update to current time */
507  void TraceUpdateTime(void);
508 
509  /** Trace: append sample (if necessary) and update to current state via given event */
510  void TraceUpdateTransition(Idx event);
511 
512 
513 }; // end class LoggingExecutor
514 
515 
516 
517 } // namespace faudes
518 
519 
520 #endif
521 
#define FAUDES_API
Definition: cfl_platform.h:80
#define FAUDES_TYPE_DECLARATION(ftype, ctype, cbase)
Definition: cfl_types.h:872
std::deque< TraceSample >::const_iterator TraceIterator
std::vector< AttributeSimCondition * > mEnabledConditions
std::map< Time::Type, int > mTraceTimeToStep
bool BreakCondition(void) const
SimConditionSet::Iterator ConditionIterator
virtual bool Valid(void) const
int CurrentStep(void) const
const ParallelTimedState & CurrentParallelTimedState(void) const
SimConditionSet mConditions
TokenWriter * pLogTokenWriter
Time::Type CurrentTime(void) const
std::deque< TraceSample > mTraceBuffer
Time::Type CurrentTime(void) const
const ParallelTimedState & CurrentParallelTimedState(void) const
int CurrentStep(void) const
uint32_t Idx

libFAUDES 2.33b --- 2025.05.07 --- c++ api documentaion by doxygen