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