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 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 |