OXYGENHUB
◆ main openmsx / src / Scheduler.hh
2.7 KiB · C++ · last changed chore(): initial commit 1 month ago source blame history raw
1
#ifndef SCHEDULER_HH
2
#define SCHEDULER_HH
3
4
#include "EmuTime.hh"
5
#include "SchedulerQueue.hh"
6
7
#include <optional>
8
#include <vector>
9
10
namespace openmsx {
11
12
class Schedulable;
13
class MSXCPU;
14
15
class SynchronizationPoint
16
{
17
public:
18
	SynchronizationPoint() = default;
19
	SynchronizationPoint(EmuTime time, Schedulable* dev)
20
		: timeStamp(time), device(dev) {}
21
	[[nodiscard]] EmuTime getTime() const { return timeStamp; }
22
	void setTime(EmuTime time) { timeStamp = time; }
23
	[[nodiscard]] Schedulable* getDevice() const { return device; }
24
25
	template<typename Archive>
26
	void serialize(Archive& ar, unsigned version);
27
28
private:
29
	EmuTime timeStamp = EmuTime::zero();
30
	Schedulable* device = nullptr;
31
};
32
33
34
class Scheduler
35
{
36
public:
37
	using SyncPoints = std::vector<SynchronizationPoint>;
38
39
	Scheduler() = default;
40
	~Scheduler();
41
42
	void setCPU(MSXCPU* cpu_)
43
	{
44
		cpu = cpu_;
45
	}
46
47
	/**
48
	 * Get the current scheduler time.
49
	 */
50
	[[nodiscard]] EmuTime getCurrentTime() const;
51
52
	/**
53
	 * TODO
54
	 */
55
	[[nodiscard]] EmuTime getNext() const
56
	{
57
		return queue.front().getTime();
58
	}
59
60
	/**
61
	 * Schedule till a certain moment in time.
62
	 */
63
	void schedule(EmuTime limit)
64
	{
65
		if (EmuTime next = getNext(); limit >= next) [[unlikely]] {
66
			scheduleHelper(limit, next); // slow path not inlined
67
		}
68
		scheduleTime = limit;
69
	}
70
71
	template<typename Archive>
72
	void serialize(Archive& ar, unsigned version);
73
74
private: // -> intended for Schedulable
75
	friend class Schedulable;
76
77
	/**
78
	 * Register a syncPoint. When the emulation reaches "timestamp",
79
	 * the executeUntil() method of "device" gets called.
80
	 * SyncPoints are ordered: smaller EmuTime -> scheduled
81
	 * earlier.
82
	 * The supplied EmuTime may not be smaller than the current CPU
83
	 * time.
84
	 * A device may register several syncPoints.
85
	 */
86
	void setSyncPoint(EmuTime timestamp, Schedulable& device);
87
88
	[[nodiscard]] SyncPoints getSyncPoints(const Schedulable& device) const;
89
90
	/**
91
	 * Removes a syncPoint of a given device.
92
	 * If there is more than one match only one will be removed,
93
	 * there is no guarantee that the earliest syncPoint is
94
	 * removed.
95
	 * Returns false <=> if there was no match (so nothing removed)
96
	 */
97
	bool removeSyncPoint(const Schedulable& device);
98
99
	/** Remove all sync-points for the given device.
100
	  */
101
	void removeSyncPoints(const Schedulable& device);
102
103
	/**
104
	 * Is there a pending syncPoint for this device?
105
	 */
106
	[[nodiscard]] std::optional<EmuTime> isPending(const Schedulable& device) const;
107
108
private:
109
	void scheduleHelper(EmuTime limit, EmuTime next);
110
111
private:
112
	/** Vector used as heap, not a priority queue because that
113
	  * doesn't allow removal of non-top element.
114
	  */
115
	SchedulerQueue<SynchronizationPoint> queue;
116
	EmuTime scheduleTime = EmuTime::zero();
117
	MSXCPU* cpu = nullptr;
118
	bool scheduleInProgress = false;
119
};
120
121
} // namespace openmsx
122
123
#endif