sp_dplpexecutor.cpp
Go to the documentation of this file.
1/** @file sp_dplpexecutor.cpp Executor with IO device */
2
3/*
4 FAU Discrete Event Systems Library (libfaudes)
5
6 Copyright (C) 2008 Thomas Moor
7
8*/
9
10
11// load configuration
12#include "corefaudes.h"
13
14
15#include "sp_dplpexecutor.h"
16#include <iostream>
17
18namespace faudes {
19
20// std faudes type
21FAUDES_TYPE_IMPLEMENTATION(DeviceExecutor,DeviceExecutor,LoggingExecutor)
22
23// constructor
25 mMaxSyncGap=10*Time::Step();
26 mSyncMode=0x0;
27}
28
29// constructor
32 mSyncMode=0x0;
33 DoAssign(rOther);
34}
35
36// destructor
39
40
41
42// DoAssign(other)
44 FD_DX("LoggingExecutor(" << this << ")::DoAssign(other)");
45 // my members
46 Devicep(NULL);
47 // base
49}
50
51// set io device
53 pDevice=dev;
54 mSyncError=false;
55#ifdef FAUDES_PLUGIN_IODEVICE
56 if(!dev) return;
57 pDevice->Reset();
58#endif
59}
60
61// reset the device
63#ifdef FAUDES_PLUGIN_IODEVICE
64 if(!pDevice) return;
65 pDevice->Reset();
66#endif
67}
68
69// start the device
71#ifdef FAUDES_PLUGIN_IODEVICE
72 if(!pDevice) return;
73 pDevice->Start();
74#endif
75}
76
77// stop the device
79#ifdef FAUDES_PLUGIN_IODEVICE
80 if(!pDevice) return;
81 pDevice->Stop();
82#endif
83}
84
85// clear static data
90
91// clear dynamic data
92void DeviceExecutor::Reset(long int seed){
93 FD_DS("DeviceExecutor::Reset()");
94#ifdef FAUDES_PLUGIN_IODEVICE
95 // reset the device
96 if(pDevice)
97 pDevice->Reset();
98 // overwrite input attributes
99 if(pDevice) {
101 neverpa.mPriority=-9999; // todo: have a never-priority
102 SimEventAttribute never;
103 never.Priority(neverpa);
104 EventSet::Iterator eit=pDevice->Inputs().Begin();
105 for(;eit!=pDevice->Inputs().End(); eit++) {
106 if(Alphabet().Exists(*eit)) EventAttribute(*eit,never);
107 }
108 }
109#endif
110 // call base
112 mSyncError=false;
113 FD_DS("DeviceExecutor::Reset(): done");
114}
115
116// Convenience
118#ifdef FAUDES_PLUGIN_IODEVICE
119 // bail out
120 if(!pDevice) return false;
121 // pass on to device
122 return pDevice->ResetRequest();
123#else
124 return false;
125#endif
126}
127
128//ExecuteEvent
130 FD_DS("DeviceExecutor::ExecuteEvent(): "<< EventName(event));
131 /*
132#ifdef FAUDES_PLUGIN_IODEVICE
133 // sync time
134 if(pDevice) SyncStep(0);
135#endif
136 */
137 // execute event
138 bool res=ProposingExecutor::ExecuteEvent(event);
139 /*
140#ifdef FAUDES_PLUGIN_IODEVICE
141 // pass on to callbacks
142 if(res && pDevice) pDevice->WriteOutput(event);
143#endif
144 */
145 // report
146 return res;
147}
148
149
150//SyncTime()
152
153 // no plugin, no run
154#ifndef FAUDES_PLUGIN_IODEVICE
155 return false;
156#else
157
158 // no device, no run
159 if(!pDevice) return false;
160
161 // figure situation
163 Time::Type genNow=CurrentTime();
164 Time::Type syncTime=devNow-genNow;
166
167
168 // time sync: no chance since generator is ahead
170 if(syncTime < -mMaxSyncGap) {
171 FD_DS_SYNC("DeviceExecutor::SyncTime(): device time " << devNow << " gen time " << genNow);
172 FD_DS_SYNC("DeviceExecutor::SyncTime(): sync error: gen time ahead");
173 mSyncError=true;
174 pDevice->Reset();
175 return false;
176 }
177
178 // time sync: check whether proposal allows for sync
180 if(syncTime - mMaxSyncGap > propTime || propTime==Time::UnDef()) {
181 FD_DS_SYNC("DeviceExecutor::SyncTime(): device time " << devNow << " gen time " << genNow);
182 FD_DS_SYNC("DeviceExecutor::SyncTime(): sync error: cannot sync enough time");
183 mSyncError=true;
184 pDevice->Reset();
185 return false;
186 }
187
188 // fix undef time (aka deadlock)
189 // note: this is pointless, since the executor will not recover
190 if(propTime==Time::UnDef()) propTime=Time::Max();
191
192 // adjust by proposal
193 if(syncTime > propTime) {
194 FD_DS_SYNC("DeviceExecutor::SyncTime(): device time " << devNow << " gen time " << genNow);
195 FD_DS_SYNC("DeviceExecutor::SyncTime(): adjust by proposal");
196 syncTime=propTime;
197 }
198
199 // time sync: pass generator time
200 if(syncTime>0) {
201 FD_DS_SYNC("DeviceExecutor::SyncTime(): generator to pass " << syncTime);
202 if(!ProposingExecutor::ExecuteTime(syncTime)) {
203 Time::Type maxsync=EnabledTime().UB();
204 if(maxsync >= syncTime-mMaxSyncGap) {
205 syncTime=maxsync;
206 }
207 FD_DS_SYNC("DeviceExecutor::SyncTime(): retry: generator to pass " << syncTime);
208 if(!ProposingExecutor::ExecuteTime(syncTime))
210 FD_DS_SYNC("DeviceExecutor::SyncTime(): exec error");
211 mSyncError=true;
212 pDevice->Reset();
213 return false;
214 }
215 };
216 }
217
218 // done
219 /*
220 FD_DS_SYNC("DeviceExecutor::SyncTime(): ok: device time " <<
221 pDevice->CurrentTime() << " gen time " << CurrentTime());
222 */
223 return true;
224
225#endif
226}
227
228
229//SyncEvents()
231
232 // no plugin, no run
233#ifndef FAUDES_PLUGIN_IODEVICE
234 return 0;
235#else
236
237 // no device, no run
238 if(!pDevice) return 0;
239
240 // ignore alien hardware event
241 if(Idx sev=pDevice->PeekInput()) {
242 if(!ParallelExecutor::Alphabet().Exists(sev)) {
243 FD_DS_SYNC("DeviceExecutor::SyncEvents(): input event " << EStr(sev) << " ignored");
245 }
246 }
247
248 // get and execute hardware events, if accepted
249 if(Idx sev=pDevice->PeekInput()) {
250 if(EnabledEvents().Exists(sev)) {
253 FD_DS_SYNC("DeviceExecutor::SyncEvents(): input event " << EStr(sev) << " accepted");
254 return sev;
255 }
256 FD_DS_SYNC("DeviceExecutor::SyncEvents(): input event " << EStr(sev) << " postponed");
257 }
258
259 // check and execute scheduled event
260 const TimedEvent& proposedTrans=ProposeNextTransition();
261 if(proposedTrans.mTime==0 && proposedTrans.mEvent!=0) {
262 FD_DS_SYNC("DeviceExecutor::SyncEvents(): scheduled event: " << EventName(proposedTrans.mEvent));
264 if(pDevice->Outputs().Exists(proposedTrans.mEvent))
265 pDevice->WriteOutput(proposedTrans.mEvent);
266 FD_DS_SYNC("DeviceExecutor::SyncEvents(): scheduled event: execueted");
267 return proposedTrans.mEvent;
268 }
269
270 // get and execute hardware events
271 if(Idx sev=pDevice->ReadInput()) {
272 bool exec = ProposingExecutor::ExecuteEvent(sev);
273 if(!exec && (mSyncMode & SyncStrictEvents)) {
274 FD_DS_SYNC("DeviceExecutor::SyncEvents(): sync error: invalid input event");
275 mSyncError=true;
276 pDevice->Reset();
277 }
278 return (exec ? sev : 0);
279 }
280
281
282 /*
283 FD_DS_SYNC("DeviceExecutor::SyncEvents(): no events ready");
284 */
285 return 0;
286
287#endif
288}
289
290//SyncWait()
292
293 // no plugin, no run
294#ifndef FAUDES_PLUGIN_IODEVICE
295 return false;
296#else
297
298 // no device, no run
299 if(!pDevice) return false;
300
301 // report
302 FD_DS_SYNC("DeviceExecutor::SyncWait(): sleep " << Time::Str(duration) );
303
304 // adjust
305 const TimedEvent& proposedTrans=ProposeNextTransition();
306 if(proposedTrans.mTime<duration) duration=proposedTrans.mTime;
307 if(duration <0) duration=0;
308
309 // report
310 FD_DS_SYNC("DeviceExecutor::SyncWait(): adjusted by proposal: " << Time::Str(duration) );
311
312 // doit
313 bool res=pDevice->WaitInputs(duration);
314
315 // done
316 return res;
317
318#endif // io plugin
319}
320
321
322//SyncWaitMs()
323bool DeviceExecutor::SyncWaitMs(int durationms) {
324
325 // no plugin, no run
326#ifndef FAUDES_PLUGIN_IODEVICE
327 return false;
328#else
329
330 // no device, no run
331 if(!pDevice) return false;
332
333 // report
334 /*
335 FD_DS_SYNC("DeviceExecutor::SyncWaitMs(): sleep " << durationms );
336 */
337
338 // adjust
339 const TimedEvent& proposedTrans=ProposeNextTransition();
340 if(proposedTrans.mTime*pDevice->TimeScale() <durationms) durationms=proposedTrans.mTime *pDevice->TimeScale();
341 if(durationms <0) durationms=0;
342
343 // report
344 /*
345 FD_DS_SYNC("DeviceExecutor::SyncWaitMs(): adjusted by proposal: " << durationms );
346 */
347
348 // doit
349 bool res=pDevice->WaitInputsMs(durationms);
350
351 // done
352 return res;
353
354#endif // io plugin
355}
356
357
358//SyncStep(duartion)
360 FD_DS_SYNC("DeviceExecutor::SyncStep("<< Time::Str(duration) << ")");
361
362 // no plugin, no run
363#ifndef FAUDES_PLUGIN_IODEVICE
364 return 0;
365#else
366
367 // no device, no run
368 if(!pDevice) return 0;
369
370 // result
371 Idx res=0;
372
373 // doit
374 if(!SyncTime()) return res;
375 if((res=SyncEvents())!=0) return res;
376 if(!SyncWait(duration)) return res;
377 if(!SyncTime()) return res;
378 res=SyncEvents();
379
380 // done
381 return res;
382
383#endif // io plugin
384}
385
386//SyncRun(duartion)
388 FD_DS_SYNC("DeviceExecutor::SyncRun("<< Time::Str(duration) << ")");
389
390 // prepare
391 Time::Type genNow=CurrentTime();
392 Time::Type genStop=genNow+duration;
393 Time::Type genLeft=genStop-genNow;
394 if(duration==Time::Max()) {
395 genStop=Time::Max();
396 genLeft=Time::Max();
397 }
398
399 // loop time
400 while(genLeft>0) {
401 // step
402 if(SyncStep(genLeft)==0) return false;
403 // update
404 genNow=CurrentTime();
405 genLeft=genStop-genNow;
406 if(duration==Time::Max()) genLeft=Time::Max();
407 }
408 // done
409 return true;
410}
411
412} // namespace
413
#define FAUDES_TYPE_IMPLEMENTATION(ftype, ctype, cbase)
Definition cfl_types.h:958
bool SyncWaitMs(int durationms)
virtual void Clear(void)
bool SyncRun(Time::Type duration=Time::Max())
Idx SyncStep(Time::Type duration=Time::Max())
void DoAssign(const DeviceExecutor &rSrc)
virtual bool DeviceResetRequest(void)
bool SyncWait(Time::Type duration=Time::Max())
Time::Type CurrentTime(void) const
virtual void Reset(void)
bool Exists(const Idx &rIndex) const
const EventSet & EnabledEvents() const
const TimeInterval & EnabledTime() const
std::string EStr(Idx event) const
Iterator End(void) const
const EventSet & Alphabet(void) const
std::string EventName(Idx index) const
virtual void Reset(void)
bool ExecuteTime(Time::Type duration)
const sEventSet & Alphabet(void) const
const SimEventAttribute & EventAttribute(Idx index) const
void DoAssign(const ProposingExecutor &rSrc)
const TimedEvent & ProposeNextTransition()
void Priority(const SimPriorityEventAttribute &rPriorityAttribute)
void UB(Time::Type time)
static Type UnDef(void)
static std::string Str(Type time)
static Type Step(void)
static Type Max(void)
virtual Idx PeekInput(void)
virtual bool WaitInputsMs(long int duration)
virtual const EventSet & Inputs(void) const
virtual void TimeScale(unsigned int scale)
virtual bool ResetRequest(void)
virtual void Stop(void)
virtual void Start(void)
virtual void WriteOutput(Idx output)=0
virtual void Reset(void)
virtual Idx ReadInput(void)
virtual bool WaitInputs(Time::Type duration)
virtual Time::Type CurrentTime(void)
virtual const EventSet & Outputs(void) const
Iterator Begin(void) const
uint32_t Idx
#define FD_DS(message)
Definition sp_executor.h:34
#define FD_DX(message)
Definition sp_executor.h:27
#define FD_DS_SYNC(message)
Definition sp_executor.h:39

libFAUDES 2.33k --- 2025.09.16 --- c++ api documentaion by doxygen