|
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 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.16b --- 2010-9-8 --- c++ source docu by doxygen 1.6.3