sp_pexecutor.cpp

Go to the documentation of this file.
00001 
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.SeekBegin(label);
00149   // read generators
00150   DoReadGenerators(rTr);
00151   // done
00152   rTr.SeekEnd(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=ExtractPath(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(PrependPath(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(!mEValid) ComputeEnabled();
00332   if(!mETime.In(time) && !((time==tpTime::Max) && mETime.UBinf()) ) {
00333     FD_DX("ParalelExecutor(" << this << ")::ExecuteTime(time): execution of  " << time 
00334        << " conflicts with enabled status " );
00335     return false; 
00336   }
00337   // progress current time
00338   mCurrentTime += time;
00339   // fix infinity
00340   if(time==tpTime::Max) mCurrentTime=tpTime::Max;
00341   // progress members 
00342   bool success=true;
00343   for(iterator xit=mExecutors.begin(); xit != mExecutors.end(); xit++) 
00344     success &= xit->ExecuteTime(time);
00345   // update state
00346   UpdateParallelTimedState();
00347   // indicate invalid (conservative)
00348   mEValid=false;
00349   return success;
00350 }
00351 
00352 // ExecuteEvent(event) 
00353 bool ParallelExecutor::ExecuteEvent(Idx event) {
00354   if(!mEValid) ComputeEnabled();
00355   if(!mEEvents.Exists(event)) {
00356     FD_DX("ParallelExecutor(" << this << ")::ExecuteEvent(): execution of event " << EStr(event) 
00357        << " conflicts with enabled status " );
00358     return false; 
00359   }
00360   // progress members
00361   bool success=true;
00362   for(iterator xit=mExecutors.begin(); xit != mExecutors.end(); xit++) 
00363     if(xit->Generator().ExistsEvent(event))
00364       success &= xit->ExecuteEvent(event);
00365   if(!success) {
00366     // should throw exception
00367     FD_DX("ParallelExecutor(" << this << ")::ExecuteEvent(): execution of event " << EStr(event) 
00368        << " conflicts with internal state data " );
00369     return false;
00370   }
00371   // progress current time
00372   mCurrentStep += 1;
00373   // update state
00374   UpdateParallelTimedState();
00375   // record event
00376   mRecentEvent=event;
00377   // invalidate
00378   mEValid=false;
00379   return true;
00380 }  
00381 
00382 // CurrentTime(time)
00383 void ParallelExecutor::CurrentTime(tpTime::Type time) {
00384   mCurrentTime=time;
00385   for(iterator xit=mExecutors.begin(); xit != mExecutors.end(); xit++) 
00386     xit->CurrentTime(time);
00387   mEValid=false;
00388 }
00389   
00390 // CurrentTime()
00391 tpTime::Type ParallelExecutor::CurrentTime(void) const {
00392   return mCurrentTime;
00393 }
00394   
00395 // CurrentStep(step)
00396 void ParallelExecutor::CurrentStep(int step) {
00397   mCurrentStep=step;
00398   for(iterator xit=mExecutors.begin(); xit != mExecutors.end(); xit++) 
00399     xit->CurrentStep(0);
00400   mEValid=false;
00401 }
00402   
00403 // CurrentStep()
00404 int ParallelExecutor::CurrentStep(void) const {
00405   return mCurrentStep;
00406 }
00407   
00408 // IsDeadlocked() 
00409 bool ParallelExecutor::IsDeadlocked(void) const {
00410   if(!mEValid) ComputeEnabled();
00411   if(!mEEvents.Empty()) return false;
00412   if(!(mETime.UB()<=0)) return false;
00413   return true;
00414 }
00415 
00416 // PTSStr(ptstate)
00417 std::string ParallelExecutor::PTSStr(const ParallelTimedState& ptstate) const {
00418   if(Size()!=ptstate.State.size()) return("(undef)");
00419   std::stringstream res;
00420   res << "(state ";
00421   for(unsigned int i=0; i< Size(); i++){
00422     res << mExecutors[i].Generator().SStr(ptstate.State[i]); 
00423     if(i+1<Size()) res << " x ";
00424   }
00425   res << ")  (clocks (";
00426   for(unsigned int i=0; i< Size(); i++){
00427     const Executor* execp=&mExecutors[i];
00428     ClockSet::Iterator cit;
00429     for(cit=execp->Generator().ClocksBegin();cit!=execp->Generator().ClocksEnd();cit++){
00430       if(cit!=execp->Generator().ClocksBegin()) res << " ";
00431       res << CStr(*cit) << "=";
00432       std::map<Idx,tpTime::Type>::const_iterator cvit=ptstate.Clock[i].find(*cit);
00433       if(cvit!=ptstate.Clock[i].end()) res << cvit->second;
00434       else res << "undef";
00435     }
00436     res<<")";
00437     if(i+1<Size()) res << " x (";
00438   }
00439   res << ")";
00440   return res.str();
00441 }
00442 
00443 // PSStr(pstate)                                                            
00444 std::string ParallelExecutor::PSStr(const ParallelState& pstate) const {
00445   if(Size()!=pstate.size()) return("(undef)");
00446   std::stringstream res;
00447   res << "(state ";
00448   for(unsigned int i=0; i< Size(); i++){
00449     res << mExecutors[i].Generator().SStr(pstate[i]); 
00450     if(i+1<Size()) res << " x ";
00451   }
00452   res << ")";
00453   return res.str();
00454 }
00455 
00456 // TEStr(tevent)
00457 std::string ParallelExecutor::TEStr(const TimedEvent& tevent) const {
00458   if(Size()==0) return "(undef)";
00459   return Begin()->TEStr(tevent);
00460 }
00461 
00462 // EStr(event)
00463 std::string ParallelExecutor::EStr(Idx event) const {
00464   if(Size()==0) return "(undef)";
00465   return Begin()->EStr(event);
00466 }
00467 
00468 // CStr(clock)
00469 std::string ParallelExecutor::CStr(Idx clock) const {
00470   if(Size()==0) return "(undef)";
00471   return Begin()->CStr(clock);
00472 }
00473 
00474 // CurrentParallelTimedStateStr()
00475 std::string ParallelExecutor::CurrentParallelTimedStateStr(void) const {
00476   return PTSStr(mCurrentParallelTimedState);
00477 }
00478 
00479 // CurrentParallelTimedStateStr()
00480 std::string ParallelExecutor::CurrentParallelStateStr(void) const {     
00481   return PSStr(mCurrentParallelTimedState.State);
00482 }
00483 
00484 //ActiveEventSet     
00485 EventSet ParallelExecutor::ActiveEventSet(const ParallelState& stateVec) const {
00486   EventSet retEventSet=Alphabet();
00487   Iterator xit;
00488   int i;
00489   for(i=0, xit=Begin(); xit!=End(); xit++, i++) {
00490     retEventSet.EraseSet( xit->Generator().Alphabet() - xit->Generator().ActiveEventSet(stateVec[i]));      
00491   }
00492   return retEventSet;  
00493 }
00494 
00495 //Active(Idx)   
00496 bool ParallelExecutor::Active(Idx ev) const{
00497   return Active(ev, mCurrentParallelTimedState.State);
00498 }
00499 
00500 //Active(Idx, ParallelState) 
00501 bool ParallelExecutor::Active(Idx ev, const ParallelState& stateVec) const {
00502   Iterator xit;
00503   int i;
00504   for(xit=Begin(), i=0; xit!=End(); ++xit, i++){
00505     if(xit->Generator().Alphabet().Exists(ev))
00506     if(xit->Generator().TransRelBegin(stateVec[i],ev)
00507        == xit->Generator().TransRelEnd(stateVec[i],ev))
00508       return false;
00509   }
00510   return true;
00511 }
00512 
00513 
00514 //DoWrite(rTr,rLabel,pContext)
00515 void ParallelExecutor::ParallelTimedState::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
00516   // allow for two versions only
00517   std::string label=rLabel;
00518   if(label!="DiscreteState") 
00519   if(label!="TimedState") 
00520     label="TimedState";
00521   FD_DC("ParallelExecutor::ParallelTimedState::DoWrite(): section " << rLabel);
00522   // figure context
00523   const ParallelExecutor* exe=dynamic_cast<const ParallelExecutor*>(pContext);
00524   if(exe) if(exe->Size()!=State.size()) exe=0;
00525   if(exe) if(exe->Size()!=Clock.size()) exe=0;
00526   // do write
00527   if(rLabel=="TimedState") rTw.WriteBegin("TimedState");
00528   // discrete state
00529   rTw.WriteBegin("DiscreteState");
00530   for(unsigned int i=0; i< State.size(); i++) {
00531     std::string name="";
00532     if(exe) name=exe->At(i).StateName(State.at(i));
00533     if(name!="") rTw.WriteString(name);
00534     else rTw.WriteInteger(State.at(i));
00535   };
00536   rTw.WriteEnd("DiscreteState");
00537   // figure whether to write clocks
00538   bool doclocks=false;
00539   if(rLabel=="TimedState") 
00540     for(unsigned int i=0; i< Clock.size(); i++) 
00541       if(Clock.at(i).size()>0) doclocks=true;
00542   // write clocks
00543   if(doclocks) {
00544     rTw.WriteBegin("ClockMaps");
00545     for(unsigned int i=0; i< Clock.size(); i++) {    
00546       rTw.WriteBegin("ClockMap");
00547       std::map<Idx,tpTime::Type>::const_iterator cit;
00548       for(cit=Clock.at(i).begin(); cit!=Clock.at(i).end(); cit++) {
00549         std::string name="";
00550         if(exe) name=exe->At(i).Generator().ClockName(cit->first);
00551         if(name!="") rTw.WriteString(name);
00552         else rTw.WriteInteger(cit->first);
00553         rTw.WriteInteger(cit->second);
00554       }
00555       rTw.WriteEnd("ClockMap");
00556     }
00557     rTw.WriteEnd("ClockMaps");
00558   }
00559   // do write end
00560   if(rLabel=="TimedState") rTw.WriteEnd("TimedState");
00561 }
00562 
00563 //DoRead(rTr,rLabel,pContext)
00564   void ParallelExecutor::ParallelTimedState::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
00565   (void) rLabel; (void) pContext; (void) rTr;
00566   FD_DC("ParallelExecutor::ParallelTimedState::DoRead()");
00567 }
00568 
00569 
00570 } // namespace faudes
00571 
00572 

Generated on Mon Nov 10 08:13:15 2008 for libFAUDES 2.11v by  doxygen 1.4.4