00001
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "sp_pexecutor.h"
00014
00015 namespace faudes {
00016
00017
00018
00019
00020 ParallelExecutor::ParallelExecutor(void) {
00021 FD_DX("ParallelExecutor(" << this << ")::ParallelExecutor()");
00022 }
00023
00024
00025 ParallelExecutor::ParallelExecutor(const std::string& rFileName) {
00026 FD_DX("ParallelExecutor(" << this << ")::ParallelExecutor(" << rFileName << ")");
00027 Read(rFileName);
00028 }
00029
00030
00031 ParallelExecutor::~ParallelExecutor(void) {
00032 FD_DX("ParallelExecutor(" << this << ")::~ParallelExecutor()");
00033 }
00034
00035
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
00046 void ParallelExecutor::Compile(void) {
00047 iterator xit;
00048 FD_DX("ParallelExecutor(" << this << ")::Compile(): with #" << Size() << " generators");
00049
00050 for(xit=mExecutors.begin(); xit!=mExecutors.end(); xit++)
00051 xit->Reset();
00052
00053 UpdateParallelTimedState();
00054
00055 mAlphabet.Clear();
00056 mAlphabet.Name("Alphabet");
00057 for(xit=mExecutors.begin(); xit!=mExecutors.end(); xit++)
00058 mAlphabet.InsertSet(xit->Generator().Alphabet());
00059
00060 mCurrentTime=0;
00061 mCurrentStep=0;
00062 mRecentEvent=0;
00063 mEValid=false;
00064 FD_DX("ParallelExecutor(" << this << ")::Compile(): done");
00065 }
00066
00067
00068 void ParallelExecutor::Reset(void) {
00069 FD_DX("ParallelExecutor(" << this << ")::Reset()");
00070
00071 Compile();
00072 }
00073
00074
00075 void ParallelExecutor::Insert(const std::string& rFileName) {
00076 FD_DX("ParallelExecutor(" << this << ")::Insert(" << rFileName << ")" );
00077 TokenReader tr(rFileName);
00078
00079 mExecutors.push_back(Executor());
00080 mExecutorNames.push_back(rFileName);
00081
00082 mExecutors.back().Read(tr);
00083 FD_DX("ParallelExecutor(" << this << ")::Insert(" << rFileName
00084 << "): found " << mExecutors.back().Name());
00085
00086 Compile();
00087 }
00088
00089
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
00095 Compile();
00096 }
00097
00098
00099 void ParallelExecutor::Clear(void) {
00100 FD_DX("ParallelExecutor(" << this << ")::Clear()");
00101 mExecutors.clear();
00102 mExecutorNames.clear();
00103 Compile();
00104 }
00105
00106
00107 Idx ParallelExecutor::Size(void) const {
00108 return (Idx) mExecutors.size();
00109 }
00110
00111
00112
00113
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
00124 void ParallelExecutor::DoWriteGenerators(TokenWriter& rTw) const {
00125 rTw.WriteBegin("Generators");
00126 for(Idx i=0; i<Size(); i++) {
00127
00128 if(mExecutorNames.at(i)!="") {
00129 rTw.WriteString(mExecutorNames.at(i));
00130 }
00131
00132 if(mExecutorNames.at(i)=="") {
00133 mExecutors.at(i).Write(rTw);
00134 }
00135 }
00136 rTw.WriteEnd("Generators");
00137 }
00138
00139
00140 void ParallelExecutor::DoRead(TokenReader& rTr, const std::string& rLabel, const Type* pContext) {
00141 (void) pContext;
00142
00143 FD_DX("ParallelExecutor(" << this << ")::DoRead(tr, " << rLabel << ")");
00144
00145 std::string label=rLabel;
00146 if(label=="") label = "Executor";
00147
00148 rTr.SeekBegin(label);
00149
00150 DoReadGenerators(rTr);
00151
00152 rTr.SeekEnd(label);
00153
00154 Reset();
00155 }
00156
00157
00158
00159 void ParallelExecutor::DoReadGenerators(TokenReader& rTr) {
00160
00161 std::string dirname="";
00162 if(rTr.SourceMode()==TokenReader::File)
00163 dirname=ExtractPath(rTr.FileName());
00164
00165 FD_DX("ParallelExecutor(" << this << ")::DoReadGenerators(tr): dirname " << dirname);
00166
00167 rTr.ReadBegin("Generators");
00168 Token token;
00169 while(!rTr.Eos("Generators")) {
00170 rTr.Peek(token);
00171
00172 if(token.Type()==Token::String) {
00173 Insert(PrependPath(dirname,token.StringValue()));
00174 rTr.Get(token);
00175 continue;
00176 }
00177
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
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
00194 const EventSet& ParallelExecutor::Alphabet(void) const {
00195 return mAlphabet;
00196 }
00197
00198
00199 void ParallelExecutor::ComputeEnabled(void) const {
00200 ParallelExecutor* fakeconst = const_cast<ParallelExecutor*>(this);
00201 fakeconst->ComputeEnabledNonConst();
00202 }
00203
00204
00205 void ParallelExecutor::ComputeEnabledNonConst(void) {
00206 iterator xit;
00207
00208 FD_DX("ParallelExecutor(" << this << ")::ComputeEnabled(): members");
00209 for(xit=mExecutors.begin(); xit != mExecutors.end(); xit++)
00210 xit->IsDeadlocked();
00211
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
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
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
00231 mEValid=true;
00232 }
00233
00234
00235 const TimeInterval& ParallelExecutor::EnabledTime(void) const {
00236 if(!mEValid) ComputeEnabled();
00237 return mETime;
00238
00239 }
00240
00241
00242 const EventSet& ParallelExecutor::EnabledEvents(void) const {
00243 if(!mEValid) ComputeEnabled();
00244 return mEEvents;
00245 }
00246
00247
00248 const EventSet& ParallelExecutor::DisabledEvents(void) const {
00249 if(!mEValid) ComputeEnabled();
00250 return mDEvents;
00251 }
00252
00253
00254 const TimeInterval& ParallelExecutor::EnabledInterval(void) const {
00255 if(!mEValid) ComputeEnabled();
00256 return mEInterval;
00257 }
00258
00259
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
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
00284 const ParallelExecutor::ParallelState& ParallelExecutor::CurrentParallelState(void) const {
00285 return mCurrentParallelTimedState.State;
00286 }
00287
00288
00289 const ParallelExecutor::ParallelTimedState& ParallelExecutor::CurrentParallelTimedState(void) const {
00290 return mCurrentParallelTimedState;
00291 }
00292
00293
00294 bool ParallelExecutor::CurrentParallelTimedState(const ParallelTimedState& ptstate) {
00295 FD_DX("ParalelExecutor(" << this << ")::CurrentParallelState(ptstate): set " << PTSStr(ptstate));
00296
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
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
00310 if(!res) {
00311 ParallelExecutor::CurrentParallelTimedState(oldstate);
00312 return false;
00313 }
00314
00315 ParallelExecutor::CurrentTime(0);
00316 ParallelExecutor::CurrentStep(0);
00317
00318 UpdateParallelTimedState();
00319
00320 mEValid=false;
00321 mRecentEvent=0;
00322 FD_DX("ParalelExecutor(" << this << ")::CurrentParallelState(ptstate): done");
00323 return true;
00324 }
00325
00326
00327
00328
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
00338 mCurrentTime += time;
00339
00340 if(time==tpTime::Max) mCurrentTime=tpTime::Max;
00341
00342 bool success=true;
00343 for(iterator xit=mExecutors.begin(); xit != mExecutors.end(); xit++)
00344 success &= xit->ExecuteTime(time);
00345
00346 UpdateParallelTimedState();
00347
00348 mEValid=false;
00349 return success;
00350 }
00351
00352
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
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
00367 FD_DX("ParallelExecutor(" << this << ")::ExecuteEvent(): execution of event " << EStr(event)
00368 << " conflicts with internal state data " );
00369 return false;
00370 }
00371
00372 mCurrentStep += 1;
00373
00374 UpdateParallelTimedState();
00375
00376 mRecentEvent=event;
00377
00378 mEValid=false;
00379 return true;
00380 }
00381
00382
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
00391 tpTime::Type ParallelExecutor::CurrentTime(void) const {
00392 return mCurrentTime;
00393 }
00394
00395
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
00404 int ParallelExecutor::CurrentStep(void) const {
00405 return mCurrentStep;
00406 }
00407
00408
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
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
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
00457 std::string ParallelExecutor::TEStr(const TimedEvent& tevent) const {
00458 if(Size()==0) return "(undef)";
00459 return Begin()->TEStr(tevent);
00460 }
00461
00462
00463 std::string ParallelExecutor::EStr(Idx event) const {
00464 if(Size()==0) return "(undef)";
00465 return Begin()->EStr(event);
00466 }
00467
00468
00469 std::string ParallelExecutor::CStr(Idx clock) const {
00470 if(Size()==0) return "(undef)";
00471 return Begin()->CStr(clock);
00472 }
00473
00474
00475 std::string ParallelExecutor::CurrentParallelTimedStateStr(void) const {
00476 return PTSStr(mCurrentParallelTimedState);
00477 }
00478
00479
00480 std::string ParallelExecutor::CurrentParallelStateStr(void) const {
00481 return PSStr(mCurrentParallelTimedState.State);
00482 }
00483
00484
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
00496 bool ParallelExecutor::Active(Idx ev) const{
00497 return Active(ev, mCurrentParallelTimedState.State);
00498 }
00499
00500
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
00515 void ParallelExecutor::ParallelTimedState::DoWrite(TokenWriter& rTw, const std::string& rLabel, const Type* pContext) const {
00516
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
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
00527 if(rLabel=="TimedState") rTw.WriteBegin("TimedState");
00528
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
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
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
00560 if(rLabel=="TimedState") rTw.WriteEnd("TimedState");
00561 }
00562
00563
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 }
00571
00572