| |
libFAUDES
Sections
Index
|
sp_lpexecutor.hGo 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