libFAUDES

Sections

Index

sp_pexecutor.cpp

Go to the documentation of this file.
00001 /** @file sp_pexecutor.cpp 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 #include "sp_pexecutor.h"
00014 
00015 namespace faudes {
00016 
00017 
00018 
00019 // ParallelExecutor(void)
00020 ParallelExecutor::ParallelExecutor(void) {
00021   FD_DX("ParallelExecutor(" << this << ")::ParallelExecutor()");
00022 }
00023 
00024 // ParallelExecutor(rFileName)
00025 ParallelExecutor::ParallelExecutor(const std::string& rFileName) {
00026   FD_DX("ParallelExecutor(" << this << ")::ParallelExecutor(" << rFileName << ")");
00027   Read(rFileName);
00028 }
00029 
00030 // ParallelExecutor(void)
00031 ParallelExecutor::~ParallelExecutor(void) { 
00032   FD_DX("ParallelExecutor(" << this << ")::~ParallelExecutor()");
00033 }
00034 
00035 //UpdateParallelTimedState()
00036 void ParallelExecutor::UpdateParallelTimedState(void) {
00037   mCurrentParallelTimedState.State.clear();
00038   mCurrentParallelTimedState.Clock.clear();
00039   for(Iterator xit=Begin(); xit!=End(); xit++){
00040     mCurrentParallelTimedState.State.push_back(xit->CurrentTimedState().State);
00041     mCurrentParallelTimedState.Clock.push_back(xit->CurrentTimedState().ClockValue);
00042   }
00043 }
00044 
00045 // Compile()
00046 void ParallelExecutor::Compile(void) {
00047   iterator xit;
00048   FD_DX("ParallelExecutor(" << this << ")::Compile(): with #" << Size() << " generators");
00049   // reset executors, incl compile
00050   for(xit=mExecutors.begin(); xit!=mExecutors.end(); xit++) 
00051     xit->Reset();
00052   // update state
00053   UpdateParallelTimedState();
00054   // compute alphabet
00055   mAlphabet.Clear();
00056   mAlphabet.Name("Alphabet");
00057   for(xit=mExecutors.begin(); xit!=mExecutors.end(); xit++) 
00058     mAlphabet.InsertSet(xit->Generator().Alphabet());
00059   // reset other members
00060   mCurrentTime=0;
00061   mCurrentStep=0;
00062   mRecentEvent=0;
00063   mEValid=false;
00064   FD_DX("ParallelExecutor(" << this << ")::Compile(): done");
00065 }
00066 
00067 // Reset()
00068 void ParallelExecutor::Reset(void) {
00069   FD_DX("ParallelExecutor(" << this << ")::Reset()");
00070   // compile includes reset 
00071   Compile();
00072 }
00073 
00074 // Insert(rFileName)
00075 void ParallelExecutor::Insert(const std::string& rFileName) {
00076   FD_DX("ParallelExecutor(" << this << ")::Insert(" << rFileName << ")" );
00077   TokenReader tr(rFileName);
00078   // create executor and read generator
00079   mExecutors.push_back(Executor());
00080   mExecutorNames.push_back(rFileName);
00081   // read generator
00082   mExecutors.back().Read(tr);
00083   FD_DX("ParallelExecutor(" << this << ")::Insert(" << rFileName 
00084         << "): found " << mExecutors.back().Name());
00085   // compile (incl check determinism)
00086   Compile();
00087 }
00088 
00089 // Insert(rGen)
00090 void ParallelExecutor::Insert(const tGenerator& rGen) {
00091   FD_DX("ParallelExecutor(" << this << ")::Insert(rGen): " << rGen.Name() << " at #" << Size());
00092   mExecutors.push_back(Executor(rGen));
00093   mExecutorNames.push_back("");
00094   // compile (incl check determinism)
00095   Compile();
00096 }
00097 
00098 // Clear()
00099 void ParallelExecutor::Clear(void) {
00100   FD_DX("ParallelExecutor(" << this << ")::Clear()");
00101   mExecutors.clear();
00102   mExecutorNames.clear();
00103   Compile();
00104 }
00105 
00106 // Size()
00107 Idx ParallelExecutor::Size(void) const {
00108   return (Idx) mExecutors.size();
00109 }
00110 
00111 
00112 
00113 //DoWrite(rTr,rLabel)
00114 void ParallelExecutor::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
00115   (void) pContext;
00116   std::string label=rLabel;
00117   if(label=="") label = "Executor";
00118   rTw.WriteBegin(label);
00119   DoWriteGenerators(rTw);
00120   rTw.WriteEnd(label);
00121 }
00122 
00123 //DoWriteGenerators(rTr,rLabel)
00124 void ParallelExecutor::DoWriteGenerators(TokenWriter& rTw) const {
00125   rTw.WriteBegin("Generators");
00126   for(Idx i=0; i<Size(); i++) {
00127     // write filename
00128     if(mExecutorNames.at(i)!="") {
00129       rTw.WriteString(mExecutorNames.at(i));
00130     }
00131     // write generator
00132     if(mExecutorNames.at(i)=="") {
00133       mExecutors.at(i).Write(rTw);
00134     }
00135   }
00136   rTw.WriteEnd("Generators");
00137 }
00138 
00139 //DoRead(rTr,rLabel)
00140 void ParallelExecutor::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
00141   (void) pContext;
00142   // report
00143   FD_DX("ParallelExecutor(" << this << ")::DoRead(tr, " << rLabel << ")");
00144   // get my section
00145   std::string label=rLabel;
00146   if(label=="") label = "Executor";
00147   // read section
00148   rTr.ReadBegin(label);
00149   // read generators
00150   DoReadGenerators(rTr);
00151   // done
00152   rTr.ReadEnd(label);
00153   // reset
00154   Reset();
00155 }
00156 
00157 
00158 //DoReadGenerators(rTr,rLabel)
00159 void ParallelExecutor::DoReadGenerators(TokenReader& rTr) {
00160   // get relevant directory
00161   std::string dirname="";
00162   if(rTr.SourceMode()==TokenReader::File) 
00163     dirname=ExtractDirectory(rTr.FileName());
00164   // report
00165   FD_DX("ParallelExecutor(" << this << ")::DoReadGenerators(tr): dirname " << dirname);
00166   // read section
00167   rTr.ReadBegin("Generators");
00168   Token token;
00169   while(!rTr.Eos("Generators")) {
00170     rTr.Peek(token);
00171     // is it a file name?
00172     if(token.Type()==Token::String) {
00173       Insert(PrependDirectory(dirname,token.StringValue()));
00174       rTr.Get(token);
00175       continue;
00176     }
00177     // is it a generator?
00178     if(token.Type()==Token::Begin) 
00179     if(token.StringValue()=="Generator") {
00180       tGenerator gen;
00181       gen.Read(rTr);
00182       Insert(gen);
00183       continue;
00184     }
00185     // else report error
00186     std::stringstream errstr;
00187     errstr << "Invalid token" << rTr.FileLine();
00188     throw Exception("ParallelExecutor::DoReadGenerators", errstr.str(), 502);
00189   }
00190   rTr.ReadEnd("Generators");
00191 }
00192 
00193 // Alphabet()
00194 const EventSet& ParallelExecutor::Alphabet(void) const {
00195   return mAlphabet;
00196 }
00197 
00198 // ComputeEnabled() fake const
00199 void ParallelExecutor::ComputeEnabled(void) const {
00200   ParallelExecutor* fakeconst = const_cast<ParallelExecutor*>(this);
00201   fakeconst->ComputeEnabledNonConst();
00202 }
00203 
00204 // ComputeEnabled()
00205 void ParallelExecutor::ComputeEnabledNonConst(void) {
00206   iterator xit;
00207   // compute members (may remove this)
00208   FD_DX("ParallelExecutor(" << this << ")::ComputeEnabled(): members");
00209   for(xit=mExecutors.begin(); xit != mExecutors.end(); xit++) 
00210     xit->IsDeadlocked();
00211   // compute etime
00212   FD_DX("ParallelExecutor(" << this << ")::ComputeEnabled(): time");
00213   mETime.SetPositive();
00214   for(xit=mExecutors.begin(); xit != mExecutors.end(); xit++) 
00215     mETime.Intersect(xit->EnabledTime());
00216   // compute e/d events
00217   FD_DX("ParallelExecutor(" << this << ")::ComputeEnabled(): e/d events");
00218   mDEvents.Name("DisabledEvents");
00219   mDEvents.Clear();
00220   for(xit=mExecutors.begin(); xit != mExecutors.end(); xit++) 
00221     mDEvents.InsertSet(xit->DisabledEvents());
00222   mEEvents=mAlphabet;
00223   mEEvents.Name("EnabledEvents");
00224   mEEvents.EraseSet(mDEvents);  
00225   // compute einterval // TODO: this is conservative
00226   FD_DX("ParallelExecutor(" << this << ")::ComputeEnabled(): interval");
00227   mEInterval.SetPositive();
00228   for(xit=mExecutors.begin(); xit != mExecutors.end(); xit++) 
00229     mEInterval.Intersect(xit->EnabledInterval());
00230   // done
00231   mEValid=true; 
00232 }
00233 
00234 // EnabledTime(void)  
00235 const TimeInterval& ParallelExecutor::EnabledTime(void) const {
00236   if(!mEValid) ComputeEnabled();
00237   return mETime;
00238 
00239 }
00240 
00241 // EnabledEvents(void)  
00242 const EventSet& ParallelExecutor::EnabledEvents(void) const {
00243   if(!mEValid) ComputeEnabled();
00244   return mEEvents;
00245 }
00246 
00247 // DisabledEvents(void)  
00248 const EventSet& ParallelExecutor::DisabledEvents(void) const {
00249   if(!mEValid) ComputeEnabled();
00250   return mDEvents;
00251 }
00252 
00253 // EnabledInterval(void)  
00254 const TimeInterval& ParallelExecutor::EnabledInterval(void) const {
00255   if(!mEValid) ComputeEnabled();
00256   return mEInterval;
00257 }
00258 
00259 // EnabledEventInterval(event)                
00260 TimeInterval ParallelExecutor::EnabledEventTime(Idx event) const {
00261   TimeInterval retInterval;
00262   retInterval.SetPositive();
00263   Iterator xit;
00264   for(xit=Begin(); xit != End(); xit++){
00265     retInterval.Intersect(xit->EnabledEventTime(event));
00266   }
00267   FD_DX("ParalelExecutor(" << this << ")::EnabledEventTime(" << event << "):"<< retInterval.Str());
00268   return retInterval;
00269 }
00270 
00271 // EnabledGuardInterval(event)                
00272 TimeInterval ParallelExecutor::EnabledGuardTime(Idx event) const {
00273   TimeInterval retInterval;
00274   retInterval.SetPositive();
00275   Iterator xit;
00276   for(xit=Begin(); xit != End(); xit++){
00277     retInterval.Intersect(xit->EnabledGuardTime(event));
00278   }
00279   FD_DX("ParalelExecutor(" << this << ")::EnabledGuardTime(" << event << "):"<< retInterval.Str());
00280   return retInterval;
00281 }
00282 
00283 //GetCurrentStateVec
00284 const ParallelExecutor::ParallelState& ParallelExecutor::CurrentParallelState(void) const {
00285   return mCurrentParallelTimedState.State;
00286 }
00287   
00288 // get current state
00289 const ParallelExecutor::ParallelTimedState& ParallelExecutor::CurrentParallelTimedState(void) const {
00290   return mCurrentParallelTimedState;
00291 }
00292 
00293 // set current state
00294 bool ParallelExecutor::CurrentParallelTimedState(const ParallelTimedState& ptstate) {
00295   FD_DX("ParalelExecutor(" << this << ")::CurrentParallelState(ptstate): set " << PTSStr(ptstate));
00296   // prepare
00297   if(ptstate.State.size()!=Size()) return false;
00298   if(ptstate.Clock.size()!=Size()) return false;
00299   bool res=true;
00300   ParallelTimedState oldstate=CurrentParallelTimedState();
00301   // loop and set for all executors
00302   int i=0;
00303   for(iterator xit=mExecutors.begin(); xit!=mExecutors.end(); xit++, i++){
00304     TimedState tstate;
00305     tstate.State=ptstate.State[i];
00306     tstate.ClockValue=ptstate.Clock[i];
00307     res = res && xit->CurrentTimedState(tstate);
00308   } 
00309   // reject
00310   if(!res) {
00311     ParallelExecutor::CurrentParallelTimedState(oldstate);
00312     return false;
00313   }
00314   // reset time (dont call the virtual fncts here)
00315   ParallelExecutor::CurrentTime(0);
00316   ParallelExecutor::CurrentStep(0);
00317   // fix state rep
00318   UpdateParallelTimedState();
00319   // invalidate
00320   mEValid=false;
00321   mRecentEvent=0;
00322   FD_DX("ParalelExecutor(" << this << ")::CurrentParallelState(ptstate): done");
00323   return true;
00324 }
00325 
00326 
00327 
00328 // ExecuteTime(time) 
00329 bool ParallelExecutor::ExecuteTime(tpTime::Type time) {
00330   if(mCurrentTime>=tpTime::Max) return false;
00331   if(time==0) return true;
00332   if(!mEValid) ComputeEnabled();
00333   if(!mETime.In(time) && !((time==tpTime::Max) && mETime.UBinf()) ) {
00334     FD_DX("ParalelExecutor(" << this << ")::ExecuteTime(time): execution of  " << time 
00335        << " conflicts with enabled status " );
00336     return false; 
00337   }
00338   // progress current time
00339   mCurrentTime += time;
00340   // fix infinity
00341   if(time==tpTime::Max) mCurrentTime=tpTime::Max;
00342   // progress members 
00343   bool success=true;
00344   for(iterator xit=mExecutors.begin(); xit != mExecutors.end(); xit++) 
00345     success &= xit->ExecuteTime(time);
00346   // update state
00347   UpdateParallelTimedState();
00348   // indicate invalid (conservative)
00349   mEValid=false;
00350   return success;
00351 }
00352 
00353 // ExecuteEvent(event) 
00354 bool ParallelExecutor::ExecuteEvent(Idx event) {
00355   if(!mEValid) ComputeEnabled();
00356   if(!mEEvents.Exists(event)) {
00357     FD_DX("ParallelExecutor(" << this << ")::ExecuteEvent(): execution of event " << EStr(event) 
00358        << " conflicts with enabled status " );
00359     return false; 
00360   }
00361   // progress members
00362   bool success=true;
00363   for(iterator xit=mExecutors.begin(); xit != mExecutors.end(); xit++) 
00364     if(xit->Generator().ExistsEvent(event))
00365       success &= xit->ExecuteEvent(event);
00366   if(!success) {
00367     // should throw exception
00368     FD_DX("ParallelExecutor(" << this << ")::ExecuteEvent(): execution of event " << EStr(event) 
00369        << " conflicts with internal state data " );
00370     return false;
00371   }
00372   // progress current time
00373   mCurrentStep += 1;
00374   // update state
00375   UpdateParallelTimedState();
00376   // record event
00377   mRecentEvent=event;
00378   // invalidate
00379   mEValid=false;
00380   return true;
00381 }  
00382 
00383 // CurrentTime(time)
00384 void ParallelExecutor::CurrentTime(tpTime::Type time) {
00385   mCurrentTime=time;
00386   for(iterator xit=mExecutors.begin(); xit != mExecutors.end(); xit++) 
00387     xit->CurrentTime(time);
00388   mEValid=false;
00389 }
00390   
00391 // CurrentTime()
00392 tpTime::Type ParallelExecutor::CurrentTime(void) const {
00393   return mCurrentTime;
00394 }
00395   
00396 // CurrentStep(step)
00397 void ParallelExecutor::CurrentStep(int step) {
00398   mCurrentStep=step;
00399   for(iterator xit=mExecutors.begin(); xit != mExecutors.end(); xit++) 
00400     xit->CurrentStep(0);
00401   mEValid=false;
00402 }
00403   
00404 // CurrentStep()
00405 int ParallelExecutor::CurrentStep(void) const {
00406   return mCurrentStep;
00407 }
00408   
00409 // IsDeadlocked() 
00410 bool ParallelExecutor::IsDeadlocked(void) const {
00411   if(!mEValid) ComputeEnabled();
00412   if(!mEEvents.Empty()) return false;
00413   if(!(mETime.UB()<=0)) return false;
00414   return true;
00415 }
00416 
00417 // PTSStr(ptstate)
00418 std::string ParallelExecutor::PTSStr(const ParallelTimedState& ptstate) const {
00419   if(Size()!=ptstate.State.size()) return("(undef)");
00420   std::stringstream res;
00421   res << "(state ";
00422   for(unsigned int i=0; i< Size(); i++){
00423     res << mExecutors[i].Generator().SStr(ptstate.State[i]); 
00424     if(i+1<Size()) res << " x ";
00425   }
00426   res << ")  (clocks (";
00427   for(unsigned int i=0; i< Size(); i++){
00428     const Executor* execp=&mExecutors[i];
00429     ClockSet::Iterator cit;
00430     for(cit=execp->Generator().ClocksBegin();cit!=execp->Generator().ClocksEnd();cit++){
00431       if(cit!=execp->Generator().ClocksBegin()) res << " ";
00432       res << CStr(*cit) << "=";
00433       std::map<Idx,tpTime::Type>::const_iterator cvit=ptstate.Clock[i].find(*cit);
00434       if(cvit!=ptstate.Clock[i].end()) res << cvit->second;
00435       else res << "undef";
00436     }
00437     res<<")";
00438     if(i+1<Size()) res << " x (";
00439   }
00440   res << ")";
00441   return res.str();
00442 }
00443 
00444 // PSStr(pstate)                                                            
00445 std::string ParallelExecutor::PSStr(const ParallelState& pstate) const {
00446   if(Size()!=pstate.size()) return("(undef)");
00447   std::stringstream res;
00448   res << "(state ";
00449   for(unsigned int i=0; i< Size(); i++){
00450     res << mExecutors[i].Generator().SStr(pstate[i]); 
00451     if(i+1<Size()) res << " x ";
00452   }
00453   res << ")";
00454   return res.str();
00455 }
00456 
00457 // TEStr(tevent)
00458 std::string ParallelExecutor::TEStr(const TimedEvent& tevent) const {
00459   if(Size()==0) return "(undef)";
00460   return Begin()->TEStr(tevent);
00461 }
00462 
00463 // EStr(event)
00464 std::string ParallelExecutor::EStr(Idx event) const {
00465   if(Size()==0) return "(undef)";
00466   return Begin()->EStr(event);
00467 }
00468 
00469 // CStr(clock)
00470 std::string ParallelExecutor::CStr(Idx clock) const {
00471   if(Size()==0) return "(undef)";
00472   return Begin()->CStr(clock);
00473 }
00474 
00475 // CurrentParallelTimedStateStr()
00476 std::string ParallelExecutor::CurrentParallelTimedStateStr(void) const {
00477   return PTSStr(mCurrentParallelTimedState);
00478 }
00479 
00480 // CurrentParallelTimedStateStr()
00481 std::string ParallelExecutor::CurrentParallelStateStr(void) const {     
00482   return PSStr(mCurrentParallelTimedState.State);
00483 }
00484 
00485 //ActiveEventSet     
00486 EventSet ParallelExecutor::ActiveEventSet(const ParallelState& stateVec) const {
00487   EventSet retEventSet=Alphabet();
00488   Iterator xit;
00489   int i;
00490   for(i=0, xit=Begin(); xit!=End(); xit++, i++) {
00491     retEventSet.EraseSet( xit->Generator().Alphabet() - xit->Generator().ActiveEventSet(stateVec[i]));      
00492   }
00493   return retEventSet;  
00494 }
00495 
00496 //Active(Idx)   
00497 bool ParallelExecutor::Active(Idx ev) const{
00498   return Active(ev, mCurrentParallelTimedState.State);
00499 }
00500 
00501 //Active(Idx, ParallelState) 
00502 bool ParallelExecutor::Active(Idx ev, const ParallelState& stateVec) const {
00503   Iterator xit;
00504   int i;
00505   for(xit=Begin(), i=0; xit!=End(); ++xit, i++){
00506     if(xit->Generator().Alphabet().Exists(ev))
00507     if(xit->Generator().TransRelBegin(stateVec[i],ev)
00508        == xit->Generator().TransRelEnd(stateVec[i],ev))
00509       return false;
00510   }
00511   return true;
00512 }
00513 
00514 
00515 //DoWrite(rTr,rLabel,pContext)
00516 void ParallelExecutor::ParallelTimedState::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
00517   // allow for two versions only
00518   std::string label=rLabel;
00519   if(label!="DiscreteState") 
00520   if(label!="TimedState") 
00521     label="TimedState";
00522   FD_DC("ParallelExecutor::ParallelTimedState::DoWrite(): section " << rLabel << " context " << pContext);
00523   // figure context
00524   const ParallelExecutor* exe=dynamic_cast<const ParallelExecutor*>(pContext);
00525   if(exe) if(exe->Size()!=State.size()) exe=0;
00526   if(exe) if(exe->Size()!=Clock.size()) exe=0;
00527   // do write
00528   if(rLabel=="TimedState") rTw.WriteBegin("TimedState");
00529   // discrete state
00530   rTw.WriteBegin("DiscreteState");
00531   for(unsigned int i=0; i< State.size(); i++) {
00532     std::string name="";
00533     if(exe) name=exe->At(i).StateName(State.at(i));
00534     if(name!="") rTw.WriteString(name);
00535     else rTw.WriteInteger(State.at(i));
00536   };
00537   rTw.WriteEnd("DiscreteState");
00538   // figure whether to write clocks
00539   bool doclocks=false;
00540   if(rLabel=="TimedState") 
00541     for(unsigned int i=0; i< Clock.size(); i++) 
00542       if(Clock.at(i).size()>0) doclocks=true;
00543   // write clocks
00544   if(doclocks) {
00545     rTw.WriteBegin("ClockMaps");
00546     for(unsigned int i=0; i< Clock.size(); i++) {    
00547       rTw.WriteBegin("ClockMap");
00548       std::map<Idx,tpTime::Type>::const_iterator cit;
00549       for(cit=Clock.at(i).begin(); cit!=Clock.at(i).end(); cit++) {
00550         std::string name="";
00551         if(exe) name=exe->At(i).Generator().ClockName(cit->first);
00552         if(name!="") rTw.WriteString(name);
00553         else rTw.WriteInteger(cit->first);
00554         rTw.WriteInteger(cit->second);
00555       }
00556       rTw.WriteEnd("ClockMap");
00557     }
00558     rTw.WriteEnd("ClockMaps");
00559   }
00560   // do write end
00561   if(rLabel=="TimedState") rTw.WriteEnd("TimedState");
00562 }
00563 
00564 //DoRead(rTr,rLabel,pContext)
00565   void ParallelExecutor::ParallelTimedState::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
00566   (void) rLabel; (void) pContext; (void) rTr;
00567   FD_DC("ParallelExecutor::ParallelTimedState::DoRead()");
00568 }
00569 
00570 
00571 } // namespace faudes
00572 
00573 

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