INET Framework for OMNeT++/OMNEST
inet::RealTimeScheduler Class Reference

This class implements the event scheduler interface of OMNeT++ to provide a real time scheduling mechanism. More...

#include <RealTimeScheduler.h>

Inheritance diagram for inet::RealTimeScheduler:

Classes

class  BeginSimulationEvent
 
class  Entry
 
class  ICallback
 

Public Member Functions

 RealTimeScheduler ()
 
virtual ~RealTimeScheduler ()
 
void addCallback (int fd, ICallback *callback)
 To be called from the module which wishes to receive data from the fd. More...
 
void removeCallback (int fd, ICallback *callback)
 
virtual void startRun () override
 Called at the beginning of a simulation run. More...
 
virtual void endRun () override
 Called at the end of a simulation run. More...
 
virtual void executionResumed () override
 Recalculates "base time" from current wall clock time. More...
 
virtual cEvent * guessNextEvent () override
 Returns the first event in the Future Event Set. More...
 
virtual cEvent * takeNextEvent () override
 Scheduler function – it comes from the cScheduler interface. More...
 
virtual void putBackEvent (cEvent *event) override
 Scheduler function – it comes from the cScheduler interface. More...
 

Public Attributes

int64_t baseTime = 0
 

Protected Member Functions

virtual void advanceSimTime ()
 
virtual bool receiveWithTimeout (int64_t timeout)
 
virtual int receiveUntil (int64_t targetTime)
 

Protected Attributes

std::vector< EntrycallbackEntries
 

Detailed Description

This class implements the event scheduler interface of OMNeT++ to provide a real time scheduling mechanism.

The events are scheduled so that the events are executed according to the time of the underlying operating system. All time values are measured in nanoseconds.

Constructor & Destructor Documentation

◆ RealTimeScheduler()

inet::RealTimeScheduler::RealTimeScheduler ( )
33  : cScheduler()
34 {
35 }

◆ ~RealTimeScheduler()

inet::RealTimeScheduler::~RealTimeScheduler ( )
virtual
38 {
39 }

Member Function Documentation

◆ addCallback()

void inet::RealTimeScheduler::addCallback ( int  fd,
ICallback callback 
)

To be called from the module which wishes to receive data from the fd.

The method must be called from the module's initialize() function.

42 {
43  if (fd < 0)
44  throw cRuntimeError("RealTimeScheduler::addCallback(): fd is invalid");
45  if (!callback)
46  throw cRuntimeError("RealTimeScheduler::addCallback(): callback must be non-nullptr");
47  callbackEntries.push_back(Entry(fd, callback));
48 }

Referenced by inet::ExtLowerUdp::open().

◆ advanceSimTime()

void inet::RealTimeScheduler::advanceSimTime ( )
protectedvirtual
77 {
78  int64_t curTime = opp_get_monotonic_clock_nsecs();
79  simtime_t t(curTime - baseTime, SIMTIME_NS);
80  if (!sim->getFES()->isEmpty())
81  t = std::min(t, sim->getFES()->peekFirst()->getArrivalTime());
82  sim->setSimTime(t);
83 }

Referenced by guessNextEvent(), and receiveWithTimeout().

◆ endRun()

void inet::RealTimeScheduler::endRun ( )
overridevirtual

Called at the end of a simulation run.

66 {
67  callbackEntries.clear();
68 }

◆ executionResumed()

void inet::RealTimeScheduler::executionResumed ( )
overridevirtual

Recalculates "base time" from current wall clock time.

71 {
72  baseTime = opp_get_monotonic_clock_nsecs();
73  baseTime = baseTime - sim->getSimTime().inUnit(SIMTIME_NS);
74 }

◆ guessNextEvent()

cEvent * inet::RealTimeScheduler::guessNextEvent ( )
overridevirtual

Returns the first event in the Future Event Set.

152 {
153  advanceSimTime();
154  return sim->getFES()->peekFirst();
155 }

◆ putBackEvent()

void inet::RealTimeScheduler::putBackEvent ( cEvent *  event)
overridevirtual

Scheduler function – it comes from the cScheduler interface.

194 {
195  sim->getFES()->putBackFirst(event);
196 }

◆ receiveUntil()

int inet::RealTimeScheduler::receiveUntil ( int64_t  targetTime)
protectedvirtual
130 {
131  // if there's more than 2*UI_REFRESH_TIME to wait, wait in UI_REFRESH_TIME chunks
132  // in order to keep UI responsiveness by invoking getEnvir()->idle()
133  int64_t curTime = opp_get_monotonic_clock_nsecs();
134 
135  while ((targetTime - curTime) >= 2 * UI_REFRESH_TIME) {
137  return 1;
138  if (getEnvir()->idle())
139  return -1;
140  curTime = opp_get_monotonic_clock_nsecs();
141  }
142 
143  // difference is now at most UI_REFRESH_TIME, do it at once
144  int64_t remaining = targetTime - curTime;
145  if (remaining > 0)
146  if (receiveWithTimeout(remaining))
147  return 1;
148  return 0;
149 }

Referenced by takeNextEvent().

◆ receiveWithTimeout()

bool inet::RealTimeScheduler::receiveWithTimeout ( int64_t  timeout)
protectedvirtual
86 {
87 #ifdef __linux__
88  bool found = false;
89  timeval tv;
90  tv.tv_sec = 0;
91  tv.tv_usec = timeout / 1000;
92 
93  int32_t fdVec[FD_SETSIZE], maxfd;
94  fd_set rdfds;
95  FD_ZERO(&rdfds);
96  maxfd = -1;
97  for (uint16_t i = 0; i < callbackEntries.size(); i++) {
98  fdVec[i] = callbackEntries.at(i).fd;
99  if (fdVec[i] > maxfd)
100  maxfd = fdVec[i];
101  FD_SET(fdVec[i], &rdfds);
102  }
103  if (select(maxfd + 1, &rdfds, nullptr, nullptr, &tv) < 0)
104  return found;
105  advanceSimTime();
106  for (uint16_t i = 0; i < callbackEntries.size(); i++) {
107  if (!(FD_ISSET(fdVec[i], &rdfds)))
108  continue;
109  if (callbackEntries.at(i).callback->notify(fdVec[i]))
110  found = true;
111  }
112  return found;
113 #else
114  bool found = false;
115  timeval tv;
116  tv.tv_sec = 0;
117  tv.tv_usec = timeout / 1000;
118  advanceSimTime();
119  for (uint16_t i = 0; i < callbackEntries.size(); i++) {
120  if (callbackEntries.at(i).callback->notify(callbackEntries.at(i).fd))
121  found = true;
122  }
123  if (!found)
124  select(0, nullptr, nullptr, nullptr, &tv);
125  return found;
126 #endif
127 }

Referenced by receiveUntil().

◆ removeCallback()

void inet::RealTimeScheduler::removeCallback ( int  fd,
ICallback callback 
)
51 {
52  for (auto it = callbackEntries.begin(); it != callbackEntries.end();) {
53  if (fd == it->fd && callback == it->callback)
54  it = callbackEntries.erase(it);
55  else
56  ++it;
57  }
58 }

Referenced by inet::ExtLowerUdp::close().

◆ startRun()

void inet::RealTimeScheduler::startRun ( )
overridevirtual

Called at the beginning of a simulation run.

61 {
62  baseTime = opp_get_monotonic_clock_nsecs();
63 }

◆ takeNextEvent()

cEvent * inet::RealTimeScheduler::takeNextEvent ( )
overridevirtual

Scheduler function – it comes from the cScheduler interface.

158 {
159  int64_t targetTime;
160 
161  // calculate target time
162  cEvent *event = sim->getFES()->peekFirst();
163  if (!event)
164  // as far into the future as reasonable (hoping we will never overflow - it is unlikely)
165  targetTime = INT64_MAX;
166  else {
167  // use time of next event
168  simtime_t eventSimtime = event->getArrivalTime();
169  targetTime = baseTime + eventSimtime.inUnit(SIMTIME_NS);
170  }
171 
172  // if needed, wait until that time arrives
173  int64_t curTime = opp_get_monotonic_clock_nsecs();
174 
175  if (targetTime > curTime) {
176  int status = receiveUntil(targetTime);
177  if (status == -1)
178  return nullptr; // interrupted by user
179  if (status == 1)
180  event = sim->getFES()->peekFirst(); // received something
181  }
182  else {
183  // we're behind -- customized versions of this class may
184  // alert if we're too much behind, whatever that means
185  int64_t diffTime = curTime - targetTime;
186  EV_TRACE << "We are behind: " << diffTime * 1e-9 << " seconds\n";
187  }
188  cEvent *tmp = sim->getFES()->removeFirst();
189  ASSERT(tmp == event);
190  return event;
191 }

Member Data Documentation

◆ baseTime

int64_t inet::RealTimeScheduler::baseTime = 0

◆ callbackEntries

std::vector<Entry> inet::RealTimeScheduler::callbackEntries
protected

The documentation for this class was generated from the following files:
inet::RealTimeScheduler::receiveWithTimeout
virtual bool receiveWithTimeout(int64_t timeout)
Definition: RealTimeScheduler.cc:85
inet::sctp::min
double min(const double a, const double b)
Returns the minimum of a and b.
Definition: SctpAssociation.h:261
inet::units::constants::e
const value< double, units::C > e(1.602176487e-19)
inet::RealTimeScheduler::callbackEntries
std::vector< Entry > callbackEntries
Definition: RealTimeScheduler.h:54
inet::RealTimeScheduler::baseTime
int64_t baseTime
Definition: RealTimeScheduler.h:42
UI_REFRESH_TIME
#define UI_REFRESH_TIME
Definition: RealTimeScheduler.cc:26
inet::RealTimeScheduler::advanceSimTime
virtual void advanceSimTime()
Definition: RealTimeScheduler.cc:76
inet::RealTimeScheduler::receiveUntil
virtual int receiveUntil(int64_t targetTime)
Definition: RealTimeScheduler.cc:129