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

libFAUDES 2.23h --- 2014.04.03 --- c++ api documentaion by doxygen