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 for (auto copy = to_vector(queue); auto& s : copy) {
27 s.getDevice()->schedulerDeleted();
28 }
29 assert(queue.empty());
30}
31
32void Scheduler::setSyncPoint(EmuTime::param time, Schedulable& device)
33{
34 assert(Thread::isMainThread());
35 assert(time >= scheduleTime);
36
37 // Push sync point into queue.
38 queue.insert(SynchronizationPoint(time, &device),
39 [](SynchronizationPoint& sp) { sp.setTime(EmuTime::infinity()); },
40 [](const SynchronizationPoint& x, const SynchronizationPoint& y) {
41 return x.getTime() < y.getTime(); });
42
43 if (!scheduleInProgress && cpu) {
44 // only when scheduleHelper() is not being executed
45 // otherwise getNext() doesn't return the correct time and
46 // scheduleHelper() anyway calls setNextSyncPoint() at the end
48 }
49}
50
51Scheduler::SyncPoints Scheduler::getSyncPoints(const Schedulable& device) const
52{
53 SyncPoints result;
54 ranges::copy_if(queue, back_inserter(result), EqualSchedulable(device));
55 return result;
56}
57
58bool Scheduler::removeSyncPoint(const Schedulable& device)
59{
60 assert(Thread::isMainThread());
61 return queue.remove(EqualSchedulable(device));
62}
63
64void Scheduler::removeSyncPoints(const Schedulable& device)
65{
66 assert(Thread::isMainThread());
67 queue.remove_all(EqualSchedulable(device));
68}
69
70bool Scheduler::pendingSyncPoint(const Schedulable& device,
71 EmuTime& result) const
72{
73 assert(Thread::isMainThread());
74 if (auto it = ranges::find(queue, &device, &SynchronizationPoint::getDevice);
75 it != std::end(queue)) {
76 result = it->getTime();
77 return true;
78 }
79 return false;
80}
81
82EmuTime::param Scheduler::getCurrentTime() const
83{
84 assert(Thread::isMainThread());
85 return scheduleTime;
86}
87
88void Scheduler::scheduleHelper(EmuTime::param limit, EmuTime next)
89{
90 assert(!scheduleInProgress);
91 scheduleInProgress = true;
92 while (true) {
93 assert(scheduleTime <= next);
94 scheduleTime = next;
95
96 const auto& sp = queue.front();
97 auto* device = sp.getDevice();
98
99 queue.remove_front();
100
101 device->executeUntil(next);
102
103 next = getNext();
104 if (next > limit) [[likely]] break;
105 }
106 scheduleInProgress = false;
107
108 cpu->setNextSyncPoint(next);
109}
110
111
112template<typename Archive>
113void SynchronizationPoint::serialize(Archive& ar, unsigned /*version*/)
114{
115 // SynchronizationPoint is always serialized via Schedulable. A
116 // Schedulable has a collection of SynchronizationPoints, all with the
117 // same Schedulable. So there's no need to serialize 'device'.
118 //Schedulable* device;
119 ar.serialize("time", timeStamp);
120}
122
123template<typename Archive>
124void Scheduler::serialize(Archive& ar, unsigned /*version*/)
125{
126 ar.serialize("currentTime", scheduleTime);
127 // don't serialize 'queue', each Schedulable serializes its own
128 // sync-points
129}
131
132} // namespace openmsx
void setNextSyncPoint(EmuTime::param time)
Definition MSXCPU.cc:143
Every class that wants to get scheduled at some point must inherit from this class.
EmuTime::param getCurrentTime() const
Get the current scheduler time.
Definition Scheduler.cc:82
void serialize(Archive &ar, unsigned version)
Definition Scheduler.cc:124
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:113
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:11
auto find(InputRange &&range, const T &value)
Definition ranges.hh:162
auto copy_if(InputRange &&range, OutputIter out, UnaryPredicate pred)
Definition ranges.hh:265
#define INSTANTIATE_SERIALIZE_METHODS(CLASS)
auto to_vector(Range &&range) -> std::vector< detail::ToVectorType< T, decltype(std::begin(range))> >
Definition stl.hh:275
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