libFAUDES
Sections
Index
|
sp_dplpexecutor.cppGo to the documentation of this file.00001 /** @file sp_dplpexecutor.cpp Executor with IO device */ 00002 00003 /* 00004 FAU Discrete Event Systems Library (libfaudes) 00005 00006 Copyright (C) 2008 Thomas Moor 00007 00008 */ 00009 00010 00011 // load configuration 00012 #include "corefaudes.h" 00013 00014 00015 #include "sp_dplpexecutor.h" 00016 #include <iostream> 00017 00018 namespace faudes { 00019 00020 // std faudes type 00021 FAUDES_TYPE_IMPLEMENTATION(DeviceExecutor,DeviceExecutor,LoggingExecutor) 00022 00023 // constructor 00024 DeviceExecutor::DeviceExecutor(void) : ProposingExecutor() , pDevice(0) { 00025 mMaxSyncGap=10*tpTime::Step; 00026 mSyncMode=0x0; 00027 } 00028 00029 // constructor 00030 DeviceExecutor::DeviceExecutor(const DeviceExecutor& rOther) : ProposingExecutor() , pDevice(0) { 00031 mMaxSyncGap=10*tpTime::Step; 00032 mSyncMode=0x0; 00033 DoAssign(rOther); 00034 } 00035 00036 // destructor 00037 DeviceExecutor::~DeviceExecutor(void) { 00038 } 00039 00040 00041 00042 // DoAssign(other) 00043 void DeviceExecutor::DoAssign(const DeviceExecutor& rOther) { 00044 FD_DX("LoggingExecutor(" << this << ")::DoAssign(other)"); 00045 // my members 00046 Devicep(NULL); 00047 // base 00048 ProposingExecutor::DoAssign(rOther); 00049 } 00050 00051 // set io device 00052 void DeviceExecutor::Devicep(vDevice* dev) { 00053 pDevice=dev; 00054 mSyncError=false; 00055 #ifdef FAUDES_PLUGIN_IODEVICE 00056 if(!dev) return; 00057 pDevice->Reset(); 00058 #endif 00059 } 00060 00061 // reset the device 00062 void DeviceExecutor::DeviceReset(void) { 00063 #ifdef FAUDES_PLUGIN_IODEVICE 00064 if(!pDevice) return; 00065 pDevice->Reset(); 00066 #endif 00067 } 00068 00069 // start the device 00070 void DeviceExecutor::DeviceStart(void) { 00071 #ifdef FAUDES_PLUGIN_IODEVICE 00072 if(!pDevice) return; 00073 pDevice->Start(); 00074 #endif 00075 } 00076 00077 // stop the device 00078 void DeviceExecutor::DeviceStop(void) { 00079 #ifdef FAUDES_PLUGIN_IODEVICE 00080 if(!pDevice) return; 00081 pDevice->Stop(); 00082 #endif 00083 } 00084 00085 // clear static data 00086 void DeviceExecutor::Clear(void){ 00087 Reset(); 00088 ProposingExecutor::Clear(); 00089 } 00090 00091 // clear dynamic data 00092 void DeviceExecutor::Reset(long int seed){ 00093 FD_DS("DeviceExecutor::Reset()"); 00094 #ifdef FAUDES_PLUGIN_IODEVICE 00095 // reset the device 00096 if(pDevice) 00097 pDevice->Reset(); 00098 // overwrite input attributes 00099 if(pDevice) { 00100 SimPriorityEventAttribute neverpa; 00101 neverpa.mPriority=-9999; // todo: have a never-priority 00102 SimEventAttribute never; 00103 never.Priority(neverpa); 00104 EventSet::Iterator eit=pDevice->Inputs().Begin(); 00105 for(;eit!=pDevice->Inputs().End(); eit++) { 00106 if(Alphabet().Exists(*eit)) EventAttribute(*eit,never); 00107 } 00108 } 00109 #endif 00110 // call base 00111 ProposingExecutor::Reset(seed); 00112 mSyncError=false; 00113 FD_DS("DeviceExecutor::Reset(): done"); 00114 } 00115 00116 // Convenience 00117 bool DeviceExecutor::DeviceResetRequest(void) { 00118 #ifdef FAUDES_PLUGIN_IODEVICE 00119 // bail out 00120 if(!pDevice) return false; 00121 // pass on to device 00122 return pDevice->ResetRequest(); 00123 #else 00124 return false; 00125 #endif 00126 } 00127 00128 //ExecuteEvent 00129 bool DeviceExecutor::ExecuteEvent(Idx event){ 00130 FD_DS("DeviceExecutor::ExecuteEvent(): "<< EventName(event)); 00131 /* 00132 #ifdef FAUDES_PLUGIN_IODEVICE 00133 // sync time 00134 if(pDevice) SyncStep(0); 00135 #endif 00136 */ 00137 // execute event 00138 bool res=ProposingExecutor::ExecuteEvent(event); 00139 /* 00140 #ifdef FAUDES_PLUGIN_IODEVICE 00141 // pass on to callbacks 00142 if(res && pDevice) pDevice->WriteOutput(event); 00143 #endif 00144 */ 00145 // report 00146 return res; 00147 } 00148 00149 00150 //SyncTime() 00151 bool DeviceExecutor::SyncTime(void){ 00152 00153 // no plugin, no run 00154 #ifndef FAUDES_PLUGIN_IODEVICE 00155 return false; 00156 #else 00157 00158 // no device, no run 00159 if(!pDevice) return false; 00160 00161 // figure situation 00162 tpTime::Type devNow=pDevice->CurrentTime(); 00163 tpTime::Type genNow=CurrentTime(); 00164 tpTime::Type syncTime=devNow-genNow; 00165 tpTime::Type propTime=ProposeNextTransition().Time; 00166 00167 // report 00168 FD_DS_SYNC("DeviceExecutor::SyncTime(): device time " << devNow << " gen time " << genNow); 00169 00170 // time sync: no chance since generator is ahead 00171 if(mSyncMode & SyncStrictTime) 00172 if(syncTime < -mMaxSyncGap) { 00173 FD_DS_SYNC("DeviceExecutor::SyncTime(): sync error: gen time ahead"); 00174 mSyncError=true; 00175 pDevice->Reset(); 00176 return false; 00177 } 00178 00179 // time sync: check whether proposal allows for sync 00180 if(mSyncMode & SyncStrictTime) 00181 if(syncTime - mMaxSyncGap > propTime || propTime==tpTime::UnDef) { 00182 FD_DS_SYNC("DeviceExecutor::SyncTime(): sync error: cannot sync enough time"); 00183 mSyncError=true; 00184 pDevice->Reset(); 00185 return false; 00186 } 00187 00188 // fix undef time (aka deadlock) 00189 // note: this is pointless, since the executor will not recover 00190 if(propTime==tpTime::UnDef) propTime=tpTime::Max; 00191 00192 // adjust by proposal 00193 if(syncTime > propTime) { 00194 FD_DS_SYNC("DeviceExecutor::SyncTime(): adjust by proposal"); 00195 syncTime=propTime; 00196 } 00197 00198 // time sync: pass generator time 00199 FD_DS_SYNC("DeviceExecutor::SyncTime(): generator to pass " << syncTime); 00200 if(!ProposingExecutor::ExecuteTime(syncTime)) { 00201 tpTime::Type maxsync=EnabledTime().UB(); 00202 if(maxsync >= syncTime-mMaxSyncGap) { 00203 syncTime=maxsync; 00204 } 00205 FD_DS_SYNC("DeviceExecutor::SyncTime(): retry: generator to pass " << syncTime); 00206 if(!ProposingExecutor::ExecuteTime(syncTime)) 00207 if(mSyncMode & SyncStrictTime) { 00208 FD_DS_SYNC("DeviceExecutor::SyncTime(): exec error"); 00209 mSyncError=true; 00210 pDevice->Reset(); 00211 return false; 00212 } 00213 }; 00214 00215 // done 00216 FD_DS_SYNC("DeviceExecutor::SyncTime(): ok: device time " << 00217 pDevice->CurrentTime() << " gen time " << CurrentTime()); 00218 return true; 00219 00220 #endif 00221 } 00222 00223 00224 //SyncEvents() 00225 Idx DeviceExecutor::SyncEvents(void){ 00226 00227 // no plugin, no run 00228 #ifndef FAUDES_PLUGIN_IODEVICE 00229 return 0; 00230 #else 00231 00232 // no device, no run 00233 if(!pDevice) return 0; 00234 00235 // ignore alien hardware event 00236 if(Idx sev=pDevice->PeekInput()) { 00237 if(!ParallelExecutor::Alphabet().Exists(sev)) { 00238 FD_DS_SYNC("DeviceExecutor::SyncEvents(): input event " << EStr(sev) << "ignored"); 00239 pDevice->ReadInput(); 00240 } 00241 } 00242 00243 // get and execute hardware events, if accepted 00244 if(Idx sev=pDevice->PeekInput()) { 00245 if(EnabledEvents().Exists(sev)) { 00246 pDevice->ReadInput(); 00247 ProposingExecutor::ExecuteEvent(sev); 00248 FD_DS_SYNC("DeviceExecutor::SyncEvents(): input event " << EStr(sev) << " accepted"); 00249 return sev; 00250 } 00251 FD_DS_SYNC("DeviceExecutor::SyncEvents(): input event " << EStr(sev) << " postponed"); 00252 } 00253 00254 // check and execute scheduled event 00255 const TimedEvent& proposedTrans=ProposeNextTransition(); 00256 if(proposedTrans.Time==0 && proposedTrans.Event!=0) { 00257 FD_DS_SYNC("DeviceExecutor::SyncEvents(): scheduled event: " << EventName(proposedTrans.Event)); 00258 ProposingExecutor::ExecuteEvent(proposedTrans.Event); 00259 if(pDevice->Outputs().Exists(proposedTrans.Event)) 00260 pDevice->WriteOutput(proposedTrans.Event); 00261 FD_DS_SYNC("DeviceExecutor::SyncEvents(): scheduled event: execueted"); 00262 return proposedTrans.Event; 00263 } 00264 00265 // get and execute hardware events 00266 if(Idx sev=pDevice->ReadInput()) { 00267 bool exec = ProposingExecutor::ExecuteEvent(sev); 00268 if(!exec && (mSyncMode & SyncStrictEvents)) { 00269 FD_DS_SYNC("DeviceExecutor::SyncEvents(): sync error: invalid input event"); 00270 mSyncError=true; 00271 pDevice->Reset(); 00272 } 00273 return (exec ? sev : 0); 00274 } 00275 00276 00277 FD_DS_SYNC("DeviceExecutor::SyncEvents(): no events ready"); 00278 return 0; 00279 00280 #endif 00281 } 00282 00283 //SyncWait() 00284 bool DeviceExecutor::SyncWait(tpTime::Type duration){ 00285 00286 // no plugin, no run 00287 #ifndef FAUDES_PLUGIN_IODEVICE 00288 return false; 00289 #else 00290 00291 // no device, no run 00292 if(!pDevice) return false; 00293 00294 // report 00295 FD_DS_SYNC("DeviceExecutor::SyncWait(): sleep " << tpTime::Str(duration) ); 00296 00297 // adjust 00298 const TimedEvent& proposedTrans=ProposeNextTransition(); 00299 if(proposedTrans.Time<duration) duration=proposedTrans.Time; 00300 if(duration <0) duration=0; 00301 00302 // report 00303 FD_DS_SYNC("DeviceExecutor::SyncWait(): adjusted by proposal: " << tpTime::Str(duration) ); 00304 00305 // doit 00306 bool res=pDevice->WaitInputs(duration); 00307 00308 // done 00309 return res; 00310 00311 #endif // io plugin 00312 } 00313 00314 00315 //SyncWaitMs() 00316 bool DeviceExecutor::SyncWaitMs(int durationms) { 00317 00318 // no plugin, no run 00319 #ifndef FAUDES_PLUGIN_IODEVICE 00320 return false; 00321 #else 00322 00323 // no device, no run 00324 if(!pDevice) return false; 00325 00326 // report 00327 FD_DS_SYNC("DeviceExecutor::SyncWaitMs(): sleep " << durationms ); 00328 00329 // adjust 00330 const TimedEvent& proposedTrans=ProposeNextTransition(); 00331 if(proposedTrans.Time*pDevice->TimeScale() <durationms) durationms=proposedTrans.Time *pDevice->TimeScale(); 00332 if(durationms <0) durationms=0; 00333 00334 // report 00335 FD_DS_SYNC("DeviceExecutor::SyncWaitMs(): adjusted by proposal: " << durationms ); 00336 00337 // doit 00338 bool res=pDevice->WaitInputsMs(durationms); 00339 00340 // done 00341 return res; 00342 00343 #endif // io plugin 00344 } 00345 00346 00347 //SyncStep(duartion) 00348 Idx DeviceExecutor::SyncStep(tpTime::Type duration){ 00349 FD_DS_SYNC("DeviceExecutor::SyncStep("<< tpTime::Str(duration) << ")"); 00350 00351 // no plugin, no run 00352 #ifndef FAUDES_PLUGIN_IODEVICE 00353 return 0; 00354 #else 00355 00356 // no device, no run 00357 if(!pDevice) return 0; 00358 00359 // result 00360 Idx res=0; 00361 00362 // doit 00363 if(!SyncTime()) return res; 00364 if((res=SyncEvents())!=0) return res; 00365 if(!SyncWait(duration)) return res; 00366 if(!SyncTime()) return res; 00367 res=SyncEvents(); 00368 00369 // done 00370 return res; 00371 00372 #endif // io plugin 00373 } 00374 00375 //SyncRun(duartion) 00376 bool DeviceExecutor::SyncRun(tpTime::Type duration){ 00377 FD_DS_SYNC("DeviceExecutor::SyncRun("<< tpTime::Str(duration) << ")"); 00378 00379 // prepare 00380 tpTime::Type genNow=CurrentTime(); 00381 tpTime::Type genStop=genNow+duration; 00382 tpTime::Type genLeft=genStop-genNow; 00383 if(duration==tpTime::Max) { 00384 genStop=tpTime::Max; 00385 genLeft=tpTime::Max; 00386 } 00387 00388 // loop time 00389 while(genLeft>0) { 00390 // step 00391 if(SyncStep(genLeft)==0) return false; 00392 // update 00393 genNow=CurrentTime(); 00394 genLeft=genStop-genNow; 00395 if(duration==tpTime::Max) genLeft=tpTime::Max; 00396 } 00397 // done 00398 return true; 00399 } 00400 00401 } // namespace 00402 |
libFAUDES 2.20d --- 2011.04.26 --- c++ source docu by doxygen