libFAUDES

Sections

Index

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

libFAUDES 2.14g --- 2009-12-3 --- c++ source docu by doxygen 1.5.6