openMSX
RTScheduler.cc
Go to the documentation of this file.
1 #include "RTScheduler.hh"
2 #include "RTSchedulable.hh"
3 #include "ranges.hh"
4 #include <limits>
5 
6 namespace openmsx {
7 
9  explicit EqualRTSchedulable(const RTSchedulable& schedulable_)
10  : schedulable(schedulable_) {}
11  bool operator()(const RTSyncPoint& sp) const {
12  return sp.schedulable == &schedulable;
13  }
15 };
16 
17 void RTScheduler::add(uint64_t delta, RTSchedulable& schedulable)
18 {
19  queue.insert(RTSyncPoint{Timer::getTime() + delta, &schedulable},
20  [](RTSyncPoint& sp) {
22  [](const RTSyncPoint& x, const RTSyncPoint& y) {
23  return x.time < y.time; });
24 }
25 
26 bool RTScheduler::remove(RTSchedulable& schedulable)
27 {
28  return queue.remove(EqualRTSchedulable(schedulable));
29 }
30 
31 bool RTScheduler::isPending(const RTSchedulable& schedulable) const
32 {
33  return ranges::any_of(queue, EqualRTSchedulable(schedulable));
34 }
35 
36 void RTScheduler::scheduleHelper(uint64_t limit)
37 {
38  // Process at most this many events to prevent getting stuck in an
39  // infinite loop when a RTSchedulable keeps on rescheduling itself in
40  // the (too) near future.
41  auto count = queue.size();
42  while (true) {
43  auto* schedulable = queue.front().schedulable;
44  queue.remove_front();
45 
46  schedulable->executeRT();
47 
48  // It's possible RTSchedulables are canceled in the mean time,
49  // so we can't rely on 'count' to replace this empty check.
50  if (queue.empty()) break;
51  if (likely(queue.front().time > limit)) break;
52  if (--count == 0) break;
53  }
54 }
55 
56 } // namespace openmsx
openmsx::RTSchedulable
Definition: RTSchedulable.hh:10
openmsx::RTSyncPoint::schedulable
RTSchedulable * schedulable
Definition: RTScheduler.hh:16
openmsx::RTSyncPoint
Definition: RTScheduler.hh:13
ranges::any_of
bool any_of(InputRange &&range, UnaryPredicate pred)
Definition: ranges.hh:125
LZ4::count
ALWAYS_INLINE unsigned count(const uint8_t *pIn, const uint8_t *pMatch, const uint8_t *pInLimit)
Definition: lz4.cc:207
ranges.hh
openmsx::Timer::getTime
uint64_t getTime()
Get current (real) time in us.
Definition: Timer.cc:7
RTSchedulable.hh
openmsx::EqualRTSchedulable::EqualRTSchedulable
EqualRTSchedulable(const RTSchedulable &schedulable_)
Definition: RTScheduler.cc:9
RTScheduler.hh
likely
#define likely(x)
Definition: likely.hh:14
openmsx::x
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:1377
openmsx::EqualRTSchedulable::schedulable
const RTSchedulable & schedulable
Definition: RTScheduler.cc:14
openmsx::EqualRTSchedulable
Definition: RTScheduler.cc:8
gl::max
vecN< N, T > max(const vecN< N, T > &x, const vecN< N, T > &y)
Definition: gl_vec.hh:292
openmsx::EqualRTSchedulable::operator()
bool operator()(const RTSyncPoint &sp) const
Definition: RTScheduler.cc:11
openmsx
Thanks to enen for testing this on a real cartridge:
Definition: Autofire.cc:5