libFAUDES
Sections
Index
|
sp_pexecutor.hGo to the documentation of this file.00001 /** @file sp_pexecutor.h Executor for multiple synchronized timed generators */ 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 00014 #ifndef FAUDES_PEXECUTOR_H 00015 #define FAUDES_PEXECUTOR_H 00016 00017 #include "corefaudes.h" 00018 #include "tp_include.h" 00019 #include "sp_executor.h" 00020 #include "sp_simconditionset.h" 00021 00022 00023 namespace faudes { 00024 00025 /** 00026 * Synchronized parallel execution of TimedGenerators 00027 * 00028 * \section SecSimulatorPEX1 Synchronisation 00029 * 00030 * The ParallelExecutor executes a family of timed generators with synchronized shared 00031 * events according to Alur semantics. That is, we assume disjoint clock sets and synchronize 00032 * shared events w.r.t. occurence at clock time. 00033 * 00034 * \section SecSimulatorPEX2 Implementation 00035 * 00036 * The external interface of a ParallelExecutor is the same as the single Executor, in that 00037 * it indicats enabled events and in that it provides methods for executing 00038 * events or letting time pass. 00039 * 00040 * Technically, a ParallelExecutor is a vector of executors. Clocks 00041 * are treated on a per executor basis. That is, values of clocks in one generator are 00042 * not effected by the reset of another generator, even if the respestive clock variables 00043 * have the same index and name. 00044 * 00045 * \section SecSimulatorPEX3 File IO 00046 * 00047 * For token IO, the ParallelExecutor reads and writes the generators to execute within a 00048 * section with default label "Executor". For disk space efficiency, the token IO 00049 * format will use refernces by (relative) filename if the latter is known. Since TimedGenerators 00050 * read any generator type from file, so does the ParallelExecutor. Example: 00051 * 00052 * \code 00053 * <Executor> 00054 * <Generators> 00055 * "./some_generator.gen" 00056 * "./other_generator.gen" 00057 * </Generators> 00058 * </Executor> 00059 * \endcode 00060 * 00061 * @ingroup SimulatorPlugin 00062 */ 00063 00064 class ParallelExecutor : public Type { 00065 00066 FAUDES_TYPE_DECLARATION(ParallelExecutor,ParallelExecutor,Type) 00067 00068 public: 00069 /** Typedef for parallel discrete state*/ 00070 typedef std::vector<Idx> ParallelState; 00071 00072 /** Typedef for parallel clock values */ 00073 typedef std::vector< std::map<Idx,tpTime::Type> > ParallelClock; 00074 00075 /** Typedef for parallel timed state, incl token io */ 00076 class ParallelTimedState : public Type { 00077 public: 00078 ParallelState State; 00079 ParallelClock Clock; 00080 protected: 00081 virtual void DoRead(TokenReader& rTr, const std::string& rLabel = "", const Type* pContext=0); 00082 virtual void DoWrite(TokenWriter& rTw, const std::string& rLabel="",const Type* pContext=0) const; 00083 }; 00084 00085 /** Provide typedef from Executor */ 00086 typedef Executor::TimedState TimedState; 00087 00088 /** 00089 * Construct an emtpy ParallelExecuter 00090 */ 00091 ParallelExecutor(void); 00092 00093 /** 00094 * Copy constructor 00095 */ 00096 ParallelExecutor(const ParallelExecutor& rOther); 00097 00098 /** 00099 * Construct from file. 00100 * 00101 * This constructor uses the DoRead method to initialize from file. 00102 * 00103 * @param rFileName 00104 * Filename 00105 * 00106 * @exception Exception 00107 * - non-deteministic generator (id 501) 00108 * - token mismatch (id 502) 00109 * - IO errors (id 1) 00110 */ 00111 ParallelExecutor(const std::string& rFileName); 00112 00113 00114 /** 00115 * Explicit destructor. 00116 */ 00117 virtual ~ParallelExecutor(void); 00118 00119 /** 00120 * Clear all data. Removes all generators/executors and resets the 00121 * current state to a void value. 00122 * 00123 */ 00124 virtual void Clear(void); 00125 00126 /** 00127 * Number of TimedGenerators 00128 * 00129 */ 00130 Idx Size(void) const; 00131 00132 00133 /** 00134 * Add a TimedGenerator from file. This method uses the TimedGenerator's read to 00135 * find the first generator in the file. If the generator found is not a TimedGenerator, 00136 * timing data defaults to infinite invariants/guards and empty resets. 00137 * After inserting generators and before starting to execute, you must call Reset() to update 00138 * internal datastructures. 00139 * 00140 * @param rFileName 00141 * File to read 00142 * 00143 * @exception Exception 00144 * - non-deteministic generator (id 501) 00145 * - token mismatch (id 502) 00146 * - IO errors (id 1) 00147 */ 00148 void Insert(const std::string& rFileName); 00149 00150 /** 00151 * Add a TimedGenerator. 00152 * After inserting generators and before starting to execute, you must call Reset() to update 00153 * internal datastructures. 00154 * 00155 * @param rGen 00156 * Generator to add 00157 * 00158 * @exception Exception 00159 * - non-deteministic generator (id 501) 00160 */ 00161 void Insert(const TimedGenerator& rGen); 00162 00163 /** 00164 * Overall alphabet. 00165 * 00166 */ 00167 const EventSet& Alphabet(void) const; 00168 00169 /** 00170 * Goto initial state. Reset all clock values to zero, assign initial states to each executor. 00171 */ 00172 virtual void Reset(void); 00173 00174 00175 00176 /** 00177 * Read-only access to individual executors. 00178 * 00179 */ 00180 typedef std::vector<Executor>::const_iterator Iterator; 00181 Iterator Begin(void) const { return mExecutors.begin(); }; 00182 Iterator End(void) const { return mExecutors.end(); }; 00183 const Executor& At(int i) const { return mExecutors.at(i); }; 00184 00185 00186 /** 00187 * Event index lookup. 00188 * 00189 * This convenience method refers to the global event symbol table. 00190 * 00191 * @param rName 00192 * Name of event to lookup 00193 * 00194 * @return 00195 * Valid index or 0 if non-existent 00196 */ 00197 Idx EventIndex(const std::string& rName) const { return mAlphabet.Index(rName); }; 00198 00199 /** 00200 * Event name lookup 00201 * 00202 * This convenience method refers to the global event symbol table. 00203 * 00204 * @param index 00205 * Index of event to look up 00206 * 00207 * @return 00208 * Name or empty std::string if non-existent 00209 */ 00210 std::string EventName(Idx index) const { return mAlphabet.SymbolicName(index); }; 00211 00212 /** 00213 * Get clock time. 00214 * 00215 */ 00216 tpTime::Type CurrentTime(void) const; 00217 00218 /** 00219 * Get logical time, ie number of transitions so far, 00220 * 00221 */ 00222 int CurrentStep(void) const; 00223 00224 /** 00225 * Test for deadlocked. 00226 * 00227 * The parallel executor is deadlocked if neither time can pass nor an event can 00228 * be executed. Prototypical examples for such a situation is that the indvidual 00229 * executers fail to agree on a common time interval, at which shaered events are 00230 * enabled. 00231 * 00232 * @return True/false 00233 */ 00234 bool IsDeadlocked() const; 00235 00236 /** 00237 * Check validity of executors. 00238 * 00239 * This is currently not implemented. 00240 * 00241 * @return 00242 * True on success 00243 */ 00244 virtual bool Valid(void) const {return true;}; 00245 00246 /** 00247 * Get current state of the ParallelExecutor. 00248 * 00249 * With "the current state" w refer to all data relevant for 00250 * events generated in future. This data consists of a discrete 00251 * state vector and a mapping from clocks to closk values. 00252 * 00253 * @return 00254 * Discrete state vector and clock value maps 00255 */ 00256 const ParallelTimedState& CurrentParallelTimedState(void) const; 00257 00258 /** 00259 * Get current discrete state vector of the ParallelExecutor 00260 * 00261 * By "the current discrete state" we refer to a vector of indices 00262 * that indicate the current state of the untimed transition structure. 00263 * 00264 * @return 00265 * Discrete state vector 00266 */ 00267 const ParallelState& CurrentParallelState(void) const; 00268 00269 /** 00270 * Set clock time. 00271 * This does not affect clocks and, hence, is purely cosmetic. 00272 * The trace buffer will record an invalid event. 00273 * 00274 * @param time 00275 * New clock time 00276 */ 00277 virtual void CurrentTime(tpTime::Type time); 00278 00279 /** 00280 * Set logical time (# of steps) 00281 * 00282 * This does not affect clocks and, hence, is purely cosmetic. 00283 * Note that, in contrast to clock time, the individual 00284 * generators do not agree in logical time. 00285 * The trace buffer will get out of order and should be cleared. 00286 * 00287 * @param step 00288 * New logical time 00289 */ 00290 virtual void CurrentStep(int step); 00291 00292 /** 00293 * Set current state of the ParallelExecutor. 00294 * 00295 * This resets the parallel executor to the given state, incl clock values. 00296 * Both, clock time and logical time is also reset (to 0). 00297 * 00298 * @return 00299 * True for success 00300 */ 00301 virtual bool CurrentParallelTimedState(const ParallelTimedState& ptstate); 00302 00303 /** 00304 * Let time pass without executing a transition. Return false if the duration specified 00305 * cannot elapse without an event being executed. 00306 * 00307 * @param duration 00308 * Amount of time that shall elapse. 00309 * @return 00310 * True for success 00311 */ 00312 virtual bool ExecuteTime(tpTime::Type duration); 00313 00314 /** 00315 * Execute transition. 00316 * 00317 * Returns false if the transition 00318 * cannot be executed at the current time. 00319 * 00320 * @param event 00321 * Indicate transition to execute 00322 * @return 00323 * True on success 00324 */ 00325 virtual bool ExecuteEvent(Idx event); 00326 00327 /** 00328 * Get maximal duration that can pass without executing an event. 00329 * 00330 * @return TimeInterval 00331 * 00332 */ 00333 const TimeInterval& EnabledTime() const; 00334 00335 /** 00336 * Get events that are enabled at current (timed) state. 00337 * 00338 * By "enabled" we refer to the synchronizes timed generators, 00339 * that is, we do care about clock values, invariants and guards. 00340 * 00341 * 00342 * @return 00343 * Set of enabled events 00344 */ 00345 const EventSet& EnabledEvents() const; 00346 00347 /** 00348 * Get events that are disabled at current (timed) state 00349 * 00350 * By "disabled" we refer to the synchronizes timed generators, 00351 * that is, we do care about clock values, invariants and guards. 00352 * 00353 * @return 00354 * Set of disabled events 00355 */ 00356 const EventSet& DisabledEvents() const; 00357 00358 /** 00359 * Get an interval on which the set of enabled events is constant. 00360 * Note: while this implementation tries to come up with a potentially large 00361 * interval, it is not guaranteed to be maximal. 00362 * 00363 * @return TimeInterval 00364 * 00365 */ 00366 const TimeInterval& EnabledInterval() const; 00367 00368 /** 00369 * Get interval on which the specified event is enabled. 00370 * 00371 * Returns empty, if the event is not active or never 00372 * simultanuosly enabled in all executors. 00373 * 00374 * @param event 00375 * 00376 * @return TimeInterval 00377 * 00378 */ 00379 TimeInterval EnabledEventTime(Idx event) const; 00380 00381 /** 00382 * Get interval on which the respective guard is satisfied. 00383 * 00384 * Returns empty, if the event is not active or if the guards 00385 * are never simultanuosly satisfied in all executors. 00386 * 00387 * @param event 00388 * 00389 * @return TimeInterval 00390 * 00391 */ 00392 TimeInterval EnabledGuardTime(Idx event) const; 00393 00394 /** 00395 * Get events that are active in all TimedGenerators. 00396 * 00397 * By "active" we refer to the untimed transition structure, 00398 * that is, we ignore clock values etc. 00399 * 00400 * @param stateVec 00401 * Discrete state 00402 * @return 00403 * Active EventSet 00404 */ 00405 EventSet ActiveEventSet(const ParallelState& stateVec) const; 00406 00407 /** 00408 * Test whether an event is active in a given discrete state. 00409 * 00410 * By "active" we refer to the untimed transition structure, 00411 * that is, we ignore clock values etc. 00412 * 00413 * @param ev 00414 * Event to test 00415 * @param stateVec 00416 * ParallelState 00417 * 00418 * @return 00419 * True for active in all generators 00420 */ 00421 bool Active(Idx ev, const ParallelState& stateVec) const; 00422 00423 /** 00424 * Test whether an event is active at current (discrete) state. 00425 * 00426 * By "active" we refer to the untimed transition structure, 00427 * that is, we ignore clock values etc. 00428 * 00429 * @param ev 00430 * Event ro test 00431 * 00432 * @return 00433 * True for active in all generators 00434 */ 00435 bool Active(Idx ev) const; 00436 00437 /** 00438 * Pretty printable string of timed parallel state 00439 */ 00440 std::string PTSStr(const ParallelTimedState& ptstate) const; 00441 00442 /** 00443 * Pretty printable string of parallel state 00444 */ 00445 std::string PSStr(const ParallelState& pstate) const; 00446 00447 /** 00448 * Pretty printable string of timed event 00449 */ 00450 std::string TEStr(const TimedEvent& tevent) const; 00451 00452 /** 00453 * Pretty printable string of clock name 00454 */ 00455 std::string CStr(Idx clock) const; 00456 00457 /** 00458 * Pretty printable string of event 00459 */ 00460 std::string EStr(Idx event) const; 00461 00462 /** 00463 * Pretty printable string of current state 00464 */ 00465 std::string CurrentParallelTimedStateStr(void) const; 00466 00467 /** 00468 * Pretty printable string of parallel state 00469 */ 00470 std::string CurrentParallelStateStr(void) const; 00471 00472 /** Compute enabled events and enabled interval (fake const) */ 00473 /** this is public only for performance experiments --- dont use */ 00474 void ComputeEnabled(void) const; 00475 00476 /** Compute enabled core routine (non const) */ 00477 void ComputeEnabledNonConst(void); 00478 00479 00480 00481 protected: 00482 00483 /** 00484 * Reads parallel executor from TokenReader, see also public wrappers Read() in faudes::Type. 00485 * 00486 * @param rTr 00487 * TokenReader to read from 00488 * @param rLabel 00489 * Section to read, defaults to "Executor" 00490 * @param pContext 00491 * Read context to provide contextual information (ignored) 00492 * 00493 * @exception Exception 00494 * - non-deterministic generator(s) (id 501) 00495 * - token mismatch (id 502) 00496 * - IO error (id 1) 00497 */ 00498 virtual void DoRead(TokenReader& rTr, const std::string& rLabel = "", const Type* pContext=0); 00499 00500 /** 00501 * Write to TokenWriter, see also public wrappers Write() in faudes::Type. 00502 * 00503 * 00504 * @param rTw 00505 * Reference to TokenWriter 00506 * @param rLabel 00507 * Label of section to write, defaults to "Executor" 00508 * @param pContext 00509 * Write context to provide contextual information (ignored) 00510 * 00511 * @exception Exception 00512 * - IO errors (id 2) 00513 */ 00514 virtual void DoWrite(TokenWriter& rTw, const std::string& rLabel="", const Type* pContext=0) const; 00515 00516 /** 00517 * Reads generator files section from TokenReader 00518 * 00519 * @param rTr 00520 * TokenReader to read from 00521 * 00522 * @exception Exception 00523 * - non-deterministic generator(s) (id 501) 00524 * - token mismatch (id 502) 00525 * - IO error (id 1) 00526 */ 00527 virtual void DoReadGenerators(TokenReader& rTr); 00528 00529 /** 00530 * Write generator files section to TokenWriter 00531 * 00532 * @param rTw 00533 * Reference to TokenWriter 00534 * 00535 * @exception Exception 00536 * - IO errors (id 2) 00537 */ 00538 virtual void DoWriteGenerators(TokenWriter& rTw) const; 00539 00540 00541 /** 00542 * Assignment method 00543 * 00544 * @param rSrc 00545 * Source to assign from 00546 */ 00547 virtual void DoAssign(const ParallelExecutor& rSrc); 00548 00549 /** compile internal data (eg overall alphabet) */ 00550 virtual void Compile(); 00551 00552 /** recent event */ 00553 Idx mRecentEvent; 00554 00555 private: 00556 00557 /** list of executors */ 00558 std::vector<Executor> mExecutors; 00559 00560 /** list of executors */ 00561 std::vector<std::string> mExecutorNames; 00562 00563 /** Internal non-const iterator */ 00564 typedef std::vector<Executor>::iterator iterator; 00565 00566 /** overall alphabet */ 00567 EventSet mAlphabet; 00568 00569 /** global time (real) */ 00570 tpTime::Type mCurrentTime; 00571 00572 /** global time (step)*/ 00573 int mCurrentStep; 00574 00575 /** enabled time */ 00576 TimeInterval mETime; 00577 00578 /** enabled events */ 00579 EventSet mEEvents; 00580 00581 /** disabled events */ 00582 EventSet mDEvents; 00583 00584 /** enabled interval */ 00585 TimeInterval mEInterval; 00586 00587 /** validity flag for fevents and ftime */ 00588 bool mEValid; 00589 00590 /** current state */ 00591 ParallelTimedState mCurrentParallelTimedState; 00592 00593 /** update parallel timed state() */ 00594 void UpdateParallelTimedState(void); 00595 00596 00597 00598 00599 }; // end class ParallelExecutor 00600 00601 00602 00603 } // namespace faudes 00604 00605 00606 #endif 00607 |
libFAUDES 2.20d --- 2011.04.26 --- c++ source docu by doxygen