OXYGENHUB
◆ main openmsx / src / RTScheduler.cc
1.6 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#include "RTScheduler.hh"
2
3
#include "RTSchedulable.hh"
4
5
#include <algorithm>
6
#include <limits>
7
8
namespace openmsx {
9
10
struct EqualRTSchedulable {
11
	explicit EqualRTSchedulable(const RTSchedulable& schedulable_)
12
		: schedulable(schedulable_) {}
13
	bool operator()(const RTSyncPoint& sp) const {
14
		return sp.schedulable == &schedulable;
15
	}
16
	const RTSchedulable& schedulable;
17
};
18
19
void RTScheduler::add(uint64_t delta, RTSchedulable& schedulable)
20
{
21
	queue.insert(RTSyncPoint{.time = Timer::getTime() + delta, .schedulable = &schedulable},
22
	             [](RTSyncPoint& sp) {
23
	                     sp.time = std::numeric_limits<uint64_t>::max(); },
24
	             [](const RTSyncPoint& x, const RTSyncPoint& y) {
25
	                     return x.time < y.time; });
26
}
27
28
bool RTScheduler::remove(RTSchedulable& schedulable)
29
{
30
	return queue.remove(EqualRTSchedulable(schedulable));
31
}
32
33
bool RTScheduler::isPending(const RTSchedulable& schedulable) const
34
{
35
	return std::ranges::any_of(queue, EqualRTSchedulable(schedulable));
36
}
37
38
void RTScheduler::scheduleHelper(uint64_t limit)
39
{
40
	// Process at most this many events to prevent getting stuck in an
41
	// infinite loop when a RTSchedulable keeps on rescheduling itself in
42
	// the (too) near future.
43
	auto count = queue.size();
44
	while (true) {
45
		auto* schedulable = queue.front().schedulable;
46
		queue.remove_front();
47
48
		schedulable->executeRT();
49
50
		// It's possible RTSchedulables are canceled in the mean time,
51
		// so we can't rely on 'count' to replace this empty check.
52
		if (queue.empty()) break;
53
		if (queue.front().time > limit) [[likely]] break;
54
		if (--count == 0) break;
55
	}
56
}
57
58
} // namespace openmsx