openMSX
Scheduler.cc
Go to the documentation of this file.
1#include "Scheduler.hh"
2#include "Schedulable.hh"
3#include "Thread.hh"
4#include "MSXCPU.hh"
5#include "ranges.hh"
6#include "serialize.hh"
7#include "stl.hh"
8#include <cassert>
9#include <iterator> // for back_inserter
10
11namespace openmsx {
12
14 explicit EqualSchedulable(const Schedulable& schedulable_)
15 : schedulable(schedulable_) {}
16 [[nodiscard]] bool operator()(const SynchronizationPoint& sp) const {
17 return sp.getDevice() == &schedulable;
18 }
20};
21
22
24{
25 assert(!cpu);
26 auto copy = to_vector(queue);
27 for (auto& s : copy) {
28 s.getDevice()->schedulerDeleted();
29 }
30
31 assert(queue.empty());
32}
33
34void Scheduler::setSyncPoint(EmuTime::param time, Schedulable& device)
35{
36 assert(Thread::isMainThread());
37 assert(time >= scheduleTime);
38
39 // Push sync point into queue.
40 queue.insert(SynchronizationPoint(time, &device),
41 [](SynchronizationPoint& sp) { sp.setTime(EmuTime::infinity()); },
42 [](const SynchronizationPoint& x, const SynchronizationPoint& y) {
43 return x.getTime() < y.getTime(); });
44
45 if (!scheduleInProgress && cpu) {
46 // only when scheduleHelper() is not being executed
47 // otherwise getNext() doesn't return the correct time and
48 // scheduleHelper() anyway calls setNextSyncPoint() at the end
50 }
51}
52
53Scheduler::SyncPoints Scheduler::getSyncPoints(const Schedulable& device) const
54{
55 SyncPoints result;
56 ranges::copy_if(queue, back_inserter(result), EqualSchedulable(device));
57 return result;
58}
59
60bool Scheduler::removeSyncPoint(Schedulable& device)
61{
62 assert(Thread::isMainThread());
63 return queue.remove(EqualSchedulable(device));
64}
65
66void Scheduler::removeSyncPoints(Schedulable& device)
67{
68 assert(Thread::isMainThread());
69 queue.remove_all(EqualSchedulable(device));
70}
71
72bool Scheduler::pendingSyncPoint(const Schedulable& device,
73 EmuTime& result) const
74{
75 assert(Thread::isMainThread());
76 if (auto it = ranges::find(queue, &device, &SynchronizationPoint::getDevice);
77 it != std::end(queue)) {
78 result = it->getTime();
79 return true;
80 }
81 return false;
82}
83
84EmuTime::param Scheduler::getCurrentTime() const
85{
86 assert(Thread::isMainThread());
87 return scheduleTime;
88}
89
90void Scheduler::scheduleHelper(EmuTime::param limit, EmuTime next)
91{
92 assert(!scheduleInProgress);
93 scheduleInProgress = true;
94 while (true) {
95 assert(scheduleTime <= next);
96 scheduleTime = next;
97
98 const auto& sp = queue.front();
99 auto* device = sp.getDevice();
100
101 queue.remove_front();
102
103 device->executeUntil(next);
104
105 next = getNext();
106 if (next > limit) [[likely]] break;
107 }
108 scheduleInProgress = false;
109
110 cpu->setNextSyncPoint(next);
111}
112
113
114template<typename Archive>
115void SynchronizationPoint::serialize(Archive& ar, unsigned /*version*/)
116{
117 // SynchronizationPoint is always serialized via Schedulable. A
118 // Schedulable has a collection of SynchronizationPoints, all with the
119 // same Schedulable. So there's no need to serialize 'device'.
120 //Schedulable* device;
121 ar.serialize("time", timeStamp);
122}
124
125template<typename Archive>
126void Scheduler::serialize(Archive& ar, unsigned /*version*/)
127{
128 ar.serialize("currentTime", scheduleTime);
129 // don't serialize 'queue', each Schedulable serializes its own
130 // syncpoints
131}
133
134} // namespace openmsx
void setNextSyncPoint(EmuTime::param time)
Definition: MSXCPU.cc:145
Every class that wants to get scheduled at some point must inherit from this class.
Definition: Schedulable.hh:34
EmuTime::param getCurrentTime() const
Get the current scheduler time.
Definition: Scheduler.cc:84
void serialize(Archive &ar, unsigned version)
Definition: Scheduler.cc:126
std::vector< SynchronizationPoint > SyncPoints
Definition: Scheduler.hh:35
EmuTime::param getNext() const
TODO.
Definition: Scheduler.hh:53
void serialize(Archive &ar, unsigned version)
Definition: Scheduler.cc:115
void setTime(EmuTime::param time)
Definition: Scheduler.hh:20
Schedulable * getDevice() const
Definition: Scheduler.hh:21
bool isMainThread()
Returns true when called from the main thread.
Definition: Thread.cc:15
This file implemented 3 utility functions:
Definition: Autofire.cc:9
SynchronizationPoint
Definition: Scheduler.cc:123
constexpr KeyMatrixPosition x
Keyboard bindings.
Definition: Keyboard.cc:127
auto find(InputRange &&range, const T &value)
Definition: ranges.hh:144
auto copy_if(InputRange &&range, OutputIter out, UnaryPredicate pred)
Definition: ranges.hh:214
auto copy(InputRange &&range, OutputIter out)
Definition: ranges.hh:208
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
Definition: serialize.hh:1009
auto to_vector(Range &&range) -> std::vector< detail::ToVectorType< T, decltype(std::begin(range))> >
Definition: stl.hh:266
EqualSchedulable(const Schedulable &schedulable_)
Definition: Scheduler.cc:14
bool operator()(const SynchronizationPoint &sp) const
Definition: Scheduler.cc:16
const Schedulable & schedulable
Definition: Scheduler.cc:19
constexpr auto end(const zstring_view &x)