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 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  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 AttributeSimCondition& Condition(const std::string& rName) const;
00261 
00262   /** Read-only access to a simulation condition by index */
00263   const AttributeSimCondition& Condition(Idx cond) const;
00264 
00265   /** Set (or add) a condition by name */
00266   Idx SetCondition(const std::string& rName, const AttributeSimCondition& rCondition);
00267 
00268   /** Set a condition by index  */
00269   void SetCondition(Idx cond, const AttributeSimCondition& 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 buffer, 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: first sample */
00363   const TraceSample* TraceFirst(void) const;
00364 
00365   /** Access buffer: recent sample */
00366   const TraceSample* TraceRecent(void) const;
00367 
00368   /** Access buffer: current sample */
00369   const TraceSample* TraceCurrent(void) const;
00370 
00371   /** Access buffer: tokenwriter output */
00372   void TraceWrite(TokenWriter& rTw, const TraceSample& sample) const;
00373 
00374   /** Access buffer: console output */
00375   void TraceWrite(const TraceSample& sample) const;
00376 
00377   /** Access buffer: convert to string */
00378   std::string TraceToString(const TraceSample& sample) const;
00379 
00380   /** Access buffer: console output (list all) */
00381   void TraceWrite(void) const;
00382 
00383   /** Revert executors state to past step from buffer */
00384   virtual bool RevertToStep(Idx step);
00385   
00386 
00387   /** @} doxygen group */
00388 
00389 protected:
00390 
00391   /** Compile internal data (all) */
00392   virtual void Compile();
00393 
00394 private:
00395      
00396 
00397   /** Simulation conditions */
00398   SimConditionSet mConditions;
00399 
00400   /** Enabled simulation conditions */
00401   std::vector<AttributeSimCondition*> mEnabledConditions;
00402 
00403   /** Indicate break */
00404   bool mBreakCondition;
00405 
00406   /** Compile condition internal data */
00407   void CompileConditions(void);
00408 
00409   /** Reset condition simulation state */
00410   void ConditionsReset(void);
00411 
00412   /** Process condition hook */
00413   void ConditionsProcess(void);
00414         
00415   /** Logging: tokenwriter ref */
00416   TokenWriter* pLogTokenWriter;
00417 
00418   /** Logging: file name */
00419   std::string mLogFile;
00420 
00421   /** Logging: mode */
00422   int mLogMode;
00423   
00424   /** Logging hook: dump statistics */
00425   void LogWriteStatistics(void);
00426 
00427   /** Logging hook: dump current state */
00428   void LogWriteState(void);
00429 
00430   /** Logging hook: dump recent event */
00431   void LogWriteEvent(void);
00432 
00433   /** Logging hook: dump current time */
00434   void LogWriteTime(void);
00435 
00436   /** Logging hook: halt simulation */
00437   void LogWritePause(void);
00438 
00439   /** Logging hook: continue simulation */
00440   void LogWriteResume(void);
00441 
00442   /** Trace data: max fifo length */
00443   int mTraceMax;
00444 
00445   /** Trace data: step no of first sample */
00446   int mTraceFirstStep;
00447 
00448   /** Trace data: fifo buffer */
00449   std::deque<TraceSample> mTraceBuffer;
00450 
00451   /** Trace data: time to step mapping (first step) */
00452   std::map<tpTime::Type,int> mTraceTimeToStep;
00453 
00454   /** Trace: helper, append one void sample */
00455   void TraceAddSample(void);
00456 
00457   /** Trace: append sample (if necessary) and update to current time  */
00458   void TraceUpdateTime(void);
00459 
00460   /** Trace: append sample (if necessary) and update to current state via given event  */
00461   void TraceUpdateTransition(Idx event);
00462 
00463   /**
00464    * Reads logging executor from TokenReader, see also public wrappers in faudes::Type.
00465    *
00466    * @param rTr
00467    *   TokenReader to read from
00468    * @param rLabel
00469    *   Section to read, defaults to "Executor"
00470    * @param pContext
00471    *   Read context to provide contextual information (ignored)
00472    *
00473    * @exception Exception
00474    *   - non-deterministic generator(s) (id 501)
00475    *   - token mismatch (id 502)
00476    *   - IO error (id 1)
00477    */
00478   virtual void DoRead(TokenReader& rTr,  const std::string& rLabel = "", const Type* pContext=0);
00479  
00480   /**
00481    * Write to TokenWriter, see also public wrappers in faudes::Type.
00482    *
00483    * @param rTw
00484    *   Reference to TokenWriter
00485    * @param rLabel
00486    *   Label of section to write, defaults to "Executor"
00487    * @param pContext
00488    *   Write context to provide contextual information (ignored)
00489    *
00490    * @exception Exception 
00491    *   - IO errors (id 2)
00492    */
00493   virtual void DoWrite(TokenWriter& rTw, const std::string& rLabel="", const Type* pContext=0) const;
00494 
00495 
00496 
00497 }; // end class LoggingExecutor
00498 
00499 
00500 
00501 } // namespace faudes
00502 
00503 
00504 #endif
00505 

libFAUDES 2.18b --- 2010-12-17 --- c++ source docu by doxygen 1.6.3