sp_lpexecutor.h

Go to the documentation of this file.
00001 /** @file sp_lpexecutor.h 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 #ifndef FAUDES_LPEXECUTOR_H
00014 #define FAUDES_LPEXECUTOR_H
00015 
00016 
00017 #include "corefaudes.h"
00018 #include "tp_include.h"
00019 #include "sp_pexecutor.h"
00020 #include "sp_simconditionset.h"
00021 
00022 
00023 namespace faudes {
00024 
00025 /**
00026  * Executor with logging facilities.
00027  *
00028  * \section SecSimulatorLPEX1 Logging to Token IO
00029  *
00030  * Logging destination in general is a TokenWriter, which may be initialised to a
00031  * file or console output.
00032  * Logging can be configured to include
00033  * - the external behaviour (timed event sequence), 
00034  * - the internal behaviour (state sequence) and/or 
00035  * - timing statistics of conditions specified by AttributeSimCondition. 
00036  *
00037  *
00038  * \section SecSimulatorLPEX2 Logging to Internal FIFO Buffer
00039  *
00040  * The state- and event-sequence can be logged to a internal FIFO Buffer.
00041  * Methods to revert to a previous state are provided. This feature is meant to
00042  * facilitate user interaction in simulator applications. 
00043  *
00044  * Technical detail: since the trace buffer only covers the dynamic state of the parallel executor,
00045  * the RevertToStep method cannot recover the condition status. Including stochastic states
00046  * with the trace buffer is considered to expensive. 
00047  *
00048  * \section SecSimulatorLPEX3 File IO
00049  *
00050  * For token IO, the LoggingExecutor reads and writes a section with default label 
00051  * "Executor". It contains a ParallelExecutor section to define a vector of generators and
00052  * a SimConditionSet section to define the relevant conditions. Example:
00053  *
00054  * \code
00055  * <Executor> 
00056  *
00057  * <Generators> 
00058  * "./some_generator.gen"
00059  * "./other_generator.gen" 
00060  * </Generators> 
00061  *
00062  * <Conditions> 
00063  *
00064  * "IdleCond"      
00065  * <EventCondition>
00066  * <StartEvents> "beta" "mue" </StartEvents>
00067  * <StopEvents>  "alpha"      </StopEvents>
00068  * </EventCondition>
00069  *
00070  * "DownCond"     
00071  * <StateCondition>
00072  * <StateSet> "down" </StateSet>           % refers to first generator
00073  * <StateSet> "down" "repair" </StateSet>  % refers to second generator
00074  * </StateCondition>
00075  *
00076  * </Conditions> 
00077  * 
00078  * </Executor> 
00079  * \endcode
00080  *
00081  *
00082  * @ingroup SimulatorPlugin 
00083  */
00084 
00085 class LoggingExecutor : public ParallelExecutor {    
00086 
00087 FAUDES_TYPE_DECLARATION(LogginExecutor,LoggingExecutor,ParallelExecutor)
00088 
00089  public:
00090 
00091   /*****************************************
00092    *****************************************
00093    *****************************************
00094    *****************************************/
00095 
00096   /** @name Constructors & Destructor */
00097   /** @{ doxygen group */
00098 
00099 
00100   /**
00101    * Construct an emtpy LoggingExecuter
00102    */
00103   LoggingExecutor(void);
00104 
00105   /**
00106    * Copy constructor
00107    */
00108   LoggingExecutor(const LoggingExecutor& rOther);
00109 
00110   /**
00111    * Construct from file.
00112    *
00113    * See ParallelExecutor::Insert(const std::string& rFileName) for details.
00114    *
00115    * @param rFileName
00116    *   Filename
00117    *
00118    * @exception Exception
00119    *   - Non-deteministic generator (id 501)
00120    *   - IO errors (id 1)
00121    *   - token mismatch (id see TimedGenerator)
00122    */
00123   LoggingExecutor(const std::string& rFileName);
00124 
00125 
00126   /**
00127    * Explicit destructor.
00128    */
00129   virtual ~LoggingExecutor(void);
00130 
00131 
00132    /** @} doxygen group */
00133 
00134   /*****************************************
00135    *****************************************
00136    *****************************************
00137    *****************************************/
00138 
00139   /** @name Re-implemenented from ParallelExecutor */
00140   /** @{ doxygen group */
00141 
00142   /**
00143    * Clear all data. Removes  all generators/executors, all conditions, and resets the
00144    * current state to a void value.
00145    *
00146    */
00147   virtual void Clear(void);
00148 
00149   /** 
00150    * Goto initial state. Reset all clock values to zero, assign initial states to each executor, 
00151    * reset condition states to not-satisfied, invalidate timing samples.
00152    */
00153   virtual void Reset(void);
00154 
00155   /** 
00156    * Check validity of executors.
00157    *
00158    * This is currently not implemented. It should
00159    * include tests on the state based conditions.
00160    *
00161    * @return 
00162    *   True on success
00163    */
00164    virtual bool Valid(void) const {return true;};
00165 
00166   /** 
00167    * Let time pass without executing a transition. 
00168    * Return false if the specified duration   
00169    * cannot elapse without an event being executed.
00170    *
00171    * @param duration
00172    *    Amount of time that shall elapse.
00173    * @return
00174    *   True for success
00175    */
00176   virtual bool ExecuteTime(tpTime::Type duration);
00177 
00178   /** 
00179    * Execute transition.
00180    *
00181    * Returns false if the transition
00182    * cannot be executed at the current time.
00183    *
00184    * @param event
00185    *   Indicate transition to execute
00186    * @return
00187    *   True on success
00188    */
00189   virtual bool ExecuteEvent(Idx event);
00190 
00191 
00192   /** 
00193    * Get clock time.
00194    *
00195    */
00196    tpTime::Type CurrentTime(void) const { return ParallelExecutor::CurrentTime();} ;
00197 
00198   /** 
00199    * Set clock time. 
00200    * This does not affect clocks and, hence, is purely cosmetic.
00201    * The trace buffer is cleared. You should pause/resume logging
00202    * befor/after interfering with the executors state.
00203    *
00204    *  @param time
00205    *  New clock time 
00206    */
00207   void CurrentTime(tpTime::Type time);
00208 
00209   /** 
00210    * Get logical time, ie number of transitions so far,
00211    *
00212    */
00213   int CurrentStep(void) const { return ParallelExecutor::CurrentStep();};
00214 
00215   /** 
00216    * Set logical time (# of steps)
00217    *
00218    * This does not affect clocks and, hence, is purely cosmetic.
00219    * Note that, in contrast to clock time, the individual
00220    * generators do not agree in logical time. 
00221    * The trace buffer is cleared. You should pause/resume logging
00222    * befor/after interfering with the executors state.
00223    *
00224    *  @param step
00225    *   New logical time 
00226    */
00227   void CurrentStep(int step);
00228 
00229   /** 
00230    * Set current state of the ParallelExecutor.
00231    *
00232    * This resets the parallel executor to the given state, incl clock values.
00233    * The trace buffer is cleared. You should pause/resume logging
00234    * befor/after interfering with the executors state.
00235    *
00236    *  @return 
00237    *    True for success
00238    */
00239    bool CurrentParallelTimedState(const ParallelTimedState& ptstate);
00240 
00241   /** 
00242    * Get current state of the ParallelExecutor.
00243    *
00244    *
00245    *  @return 
00246    *    Discrete state vector and clock value maps
00247    */
00248   const ParallelTimedState& CurrentParallelTimedState(void) const
00249   { return ParallelExecutor::CurrentParallelTimedState();};
00250 
00251   /** @} doxygen group */
00252 
00253   /*****************************************
00254    *****************************************
00255    *****************************************
00256    *****************************************/
00257 
00258   /** @name Simulation Conditions */
00259   /** @{ doxygen group */
00260 
00261   /** Read-only access to simulation conditions */
00262   const SimConditionSet& Conditions(void) const;
00263 
00264   /** Set all simulation conditions */
00265   void Conditions(const SimConditionSet&);
00266 
00267   /** Read-only access to a simulation condition by name */
00268   const AttributeSimCondition& Condition(const std::string& rName) const;
00269 
00270   /** Read-only access to a simulation condition by index */
00271   const AttributeSimCondition& Condition(Idx cond) const;
00272 
00273   /** Set (or add) a condition by name */
00274   Idx SetCondition(const std::string& rName, const AttributeSimCondition& rCondition);
00275 
00276   /** Set a condition by index  */
00277   void SetCondition(Idx cond, const AttributeSimCondition& rCondition);
00278 
00279   /** Remove a condition by name  */
00280   void ClrCondition(const std::string& rName);
00281 
00282   /** Remove a condition by index  */
00283   void ClrCondition(Idx cond);
00284 
00285   /** Write conditions so labled section  */
00286   void ConditionsWrite(TokenWriter& rTw, const std::string& rLabel="SimConditions") const;
00287 
00288   /** Read conditions from labled section  */
00289   void ConditionsRead(TokenReader& rTr, const std::string& rLabel="SimConditions");
00290             
00291   /** Condition iterator: typedef */
00292   typedef SimConditionSet::Iterator ConditionIterator;
00293 
00294   /** Condition iterator: begin */
00295   ConditionIterator ConditionsBegin(void) const;
00296 
00297   /** Condition iterator: end  */
00298   ConditionIterator ConditionsEnd(void) const;
00299 
00300   /** Simulation state: true if some break condition is currently satisfied */
00301   bool BreakCondition(void) const {return mBreakCondition;};
00302 
00303   /** @} doxygen group */
00304 
00305   /*****************************************
00306    *****************************************
00307    *****************************************
00308    *****************************************/
00309 
00310   /** @name Logging to Token I/O */
00311   /** @{ doxygen group */
00312 
00313   /** Logging mode flags, to specify what data to log */
00314   typedef enum { Statistics=0x01, States=0x02, Events=0x04, Time=0x08} LogMode;
00315 
00316   /** Start logging to TokenWriter */
00317   void LogOpen(TokenWriter& rTw, int mode);   
00318 
00319   /** Start logging to file */
00320   void LogOpen(const std::string& rFileName, int logmode, std::ios::openmode openmode = std::ios::out|std::ios::trunc);
00321 
00322   /** Stop logging */
00323   void LogClose(void);
00324 
00325   /** @} doxygen group */
00326  
00327   /*****************************************
00328    *****************************************
00329    *****************************************
00330    *****************************************/
00331 
00332   /** @name Trace to FIFO buffer */
00333   /** @{ doxygen group */
00334 
00335   /** 
00336    * Clear buffer and set max buffer 
00337    *
00338    * @param length
00339    *   Max length of buffer, or: -2 <> keep length, -1<>infinite, 0<> no buffer
00340    */
00341   void TraceClear(int length=-2);
00342 
00343   /** Buffer data entry */
00344   typedef struct {
00345     ParallelTimedState mState;   //// state of pexecutor
00346     Idx mStep;                   //// faudes step (no of event to occur)
00347     tpTime::Type mTime;          //// faudes time (when entered mState)
00348     tpTime::Type mDuration;      //// faudes duration (how long we reside mState);
00349     Idx mEvent;                  //// event index (if an event occured, else 0)
00350   } TraceSample;
00351 
00352   /** Access buffer: current length */
00353   int TraceLength(void) const;
00354 
00355   /** Access buffer: iterator */
00356   typedef std::deque<TraceSample>::const_iterator TraceIterator;
00357 
00358   /** Condition iterator: begin */
00359   TraceIterator TraceBegin(void) const;
00360 
00361   /** Condition iterator: end  */
00362   TraceIterator TraceEnd(void) const;
00363 
00364   /** Access buffer: sample by faudes time (returns first sample) */
00365   const TraceSample* TraceAtTime(tpTime::Type time) const;
00366 
00367   /** Access buffer: sample by step */
00368   const TraceSample* TraceAtStep(int step) const;
00369 
00370   /** Access buffer: first sample */
00371   const TraceSample* TraceFirst(void) const;
00372 
00373   /** Access buffer: recent sample */
00374   const TraceSample* TraceRecent(void) const;
00375 
00376   /** Access buffer: current sample */
00377   const TraceSample* TraceCurrent(void) const;
00378 
00379   /** Access buffer: tokenwriter output */
00380   void TraceWrite(TokenWriter& rTw, const TraceSample& sample) const;
00381 
00382   /** Access buffer: console output */
00383   void TraceWrite(const TraceSample& sample) const;
00384 
00385   /** Access buffer: convert to string */
00386   std::string TraceToString(const TraceSample& sample) const;
00387 
00388   /** Access buffer: console output (list all) */
00389   void TraceWrite(void) const;
00390 
00391   /** Revert executors state to past step from buffer */
00392   virtual bool RevertToStep(Idx step);
00393   
00394 
00395   /** @} doxygen group */
00396 
00397 protected:
00398 
00399   /** Compile internal data (all) */
00400   virtual void Compile();
00401 
00402   /**
00403    * Reads logging executor from TokenReader, see also public wrappers in faudes::Type.
00404    *
00405    * @param rTr
00406    *   TokenReader to read from
00407    * @param rLabel
00408    *   Section to read, defaults to "Executor"
00409    * @param pContext
00410    *   Read context to provide contextual information (ignored)
00411    *
00412    * @exception Exception
00413    *   - non-deterministic generator(s) (id 501)
00414    *   - token mismatch (id 502)
00415    *   - IO error (id 1)
00416    */
00417   virtual void DoRead(TokenReader& rTr,  const std::string& rLabel = "", const Type* pContext=0);
00418  
00419   /**
00420    * Write to TokenWriter, see also public wrappers in faudes::Type.
00421    *
00422    * @param rTw
00423    *   Reference to TokenWriter
00424    * @param rLabel
00425    *   Label of section to write, defaults to "Executor"
00426    * @param pContext
00427    *   Write context to provide contextual information (ignored)
00428    *
00429    * @exception Exception 
00430    *   - IO errors (id 2)
00431    */
00432   virtual void DoWrite(TokenWriter& rTw, const std::string& rLabel="", const Type* pContext=0) const;
00433 
00434   /**
00435    * Assignment method
00436    *
00437    * @param rSrc
00438    *    Source to assign from
00439    */
00440   virtual void DoAssign(const LoggingExecutor& rSrc);
00441 
00442 
00443 private:
00444      
00445 
00446   /** Simulation conditions */
00447   SimConditionSet mConditions;
00448 
00449   /** Enabled simulation conditions */
00450   std::vector<AttributeSimCondition*> mEnabledConditions;
00451 
00452   /** Indicate break */
00453   bool mBreakCondition;
00454 
00455   /** Compile condition internal data */
00456   void CompileConditions(void);
00457 
00458   /** Reset condition simulation state */
00459   void ConditionsReset(void);
00460 
00461   /** Process condition hook */
00462   void ConditionsProcess(void);
00463         
00464   /** Logging: tokenwriter ref */
00465   TokenWriter* pLogTokenWriter;
00466 
00467   /** Logging: file name */
00468   std::string mLogFile;
00469 
00470   /** Logging: mode */
00471   int mLogMode;
00472   
00473   /** Logging hook: dump statistics */
00474   void LogWriteStatistics(void);
00475 
00476   /** Logging hook: dump current state */
00477   void LogWriteState(void);
00478 
00479   /** Logging hook: dump recent event */
00480   void LogWriteEvent(void);
00481 
00482   /** Logging hook: dump current time */
00483   void LogWriteTime(void);
00484 
00485   /** Logging hook: halt simulation */
00486   void LogWritePause(void);
00487 
00488   /** Logging hook: continue simulation */
00489   void LogWriteResume(void);
00490 
00491   /** Trace data: max fifo length */
00492   int mTraceMax;
00493 
00494   /** Trace data: step no of first sample */
00495   int mTraceFirstStep;
00496 
00497   /** Trace data: fifo buffer */
00498   std::deque<TraceSample> mTraceBuffer;
00499 
00500   /** Trace data: time to step mapping (first step) */
00501   std::map<tpTime::Type,int> mTraceTimeToStep;
00502 
00503   /** Trace: helper, append one void sample */
00504   void TraceAddSample(void);
00505 
00506   /** Trace: append sample (if necessary) and update to current time  */
00507   void TraceUpdateTime(void);
00508 
00509   /** Trace: append sample (if necessary) and update to current state via given event  */
00510   void TraceUpdateTransition(Idx event);
00511 
00512 
00513 }; // end class LoggingExecutor
00514 
00515 
00516 
00517 } // namespace faudes
00518 
00519 
00520 #endif
00521 

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen