This commit is contained in:
2026-05-21 17:55:11 +02:00
parent 366637aba3
commit 5fbda03ceb
2 changed files with 74 additions and 60 deletions
+49 -36
View File
@@ -5,47 +5,60 @@ void Scheduler::EnqueueRelative(const u64 t, const EventType type) { EnqueueAbso
void Scheduler::EnqueueAbsolute(const u64 t, const EventType type) { events.push({t, type}); } void Scheduler::EnqueueAbsolute(const u64 t, const EventType type) { events.push({t, type}); }
u64 Scheduler::Remove(const EventType eventType) const { Event *Scheduler::Find(const EventType eventType) const {
for (auto &[time, type] : events) { for (auto &event : events) {
if (type == eventType) { if (event.type == eventType) {
const u64 ret = time - ticks; const u64 ret = event.time - ticks;
type = NONE; return &event;
time = ticks; }
return ret;
} }
}
return 0; return nullptr;
}
u64 Scheduler::Remove(const EventType eventType) const {
auto event = Find(eventType);
if (!event)
return 0;
const u64 ret = event->time - ticks;
event->type = NONE;
event->time = ticks;
return ret;
} }
void Scheduler::Tick(const u64 t) { void Scheduler::Tick(const u64 t) {
n64::Mem& mem = n64::Core::GetMem(); n64::Mem &mem = n64::Core::GetMem();
ticks += t; ticks += t;
n64::MI &mi = mem.mmio.mi; n64::MI &mi = mem.mmio.mi;
n64::SI &si = mem.mmio.si; n64::SI &si = mem.mmio.si;
n64::PI &pi = mem.mmio.pi; n64::PI &pi = mem.mmio.pi;
while (ticks >= events.top().time) { while (ticks >= events.top().time) {
switch (const auto type = events.top().type) { switch (const auto type = events.top().type) {
case SI_DMA: case SI_DMA:
si.DMA(); si.DMA();
break; break;
case PI_DMA_COMPLETE: case PI_DMA_COMPLETE:
mi.InterruptRaise(n64::MI::Interrupt::PI); mi.InterruptRaise(n64::MI::Interrupt::PI);
pi.dmaBusy = false; pi.dmaBusy = false;
break; break;
case PI_BUS_WRITE_COMPLETE: case PI_BUS_WRITE_COMPLETE:
pi.ioBusy = false; pi.ioBusy = false;
break; break;
case NONE: case NONE:
break; break;
case IMPOSSIBLE: case IMPOSSIBLE:
Util::Error::GetInstance().Throw({Util::Error::Severity::UNRECOVERABLE}, {Util::Error::Type::ROM_LOAD_ERROR}, {}, {}, "Unrecognized rom endianness"); Util::Error::GetInstance().Throw({Util::Error::Severity::UNRECOVERABLE},
return; {Util::Error::Type::ROM_LOAD_ERROR}, {}, {},
default: "Unrecognized rom endianness");
Util::Error::GetInstance().Throw({Util::Error::Severity::UNRECOVERABLE}, {Util::Error::Type::ROM_LOAD_ERROR}, {}, {}, "Unknown scheduler event type {}", static_cast<int>(type)); return;
return; default:
Util::Error::GetInstance().Throw({Util::Error::Severity::UNRECOVERABLE},
{Util::Error::Type::ROM_LOAD_ERROR}, {}, {},
"Unknown scheduler event type {}", static_cast<int>(type));
return;
}
events.pop();
} }
events.pop();
}
} }
+25 -24
View File
@@ -6,41 +6,42 @@
enum EventType { NONE, PI_BUS_WRITE_COMPLETE, PI_DMA_COMPLETE, SI_DMA, IMPOSSIBLE }; enum EventType { NONE, PI_BUS_WRITE_COMPLETE, PI_DMA_COMPLETE, SI_DMA, IMPOSSIBLE };
struct Event { struct Event {
u64 time; u64 time;
EventType type; EventType type;
friend bool operator<(const Event &rhs, const Event &lhs) { return rhs.time < lhs.time; } friend bool operator<(const Event &rhs, const Event &lhs) { return rhs.time < lhs.time; }
friend bool operator>(const Event &rhs, const Event &lhs) { return rhs.time > lhs.time; } friend bool operator>(const Event &rhs, const Event &lhs) { return rhs.time > lhs.time; }
friend bool operator>=(const Event &rhs, const Event &lhs) { return rhs.time >= lhs.time; } friend bool operator>=(const Event &rhs, const Event &lhs) { return rhs.time >= lhs.time; }
}; };
struct IterableEvents { struct IterableEvents {
std::priority_queue<Event, std::vector<Event>, std::greater<>> events; std::priority_queue<Event, std::vector<Event>, std::greater<>> events;
explicit IterableEvents() = default; explicit IterableEvents() = default;
[[nodiscard]] auto top() const { return events.top(); } [[nodiscard]] auto top() const { return events.top(); }
auto pop() { events.pop(); } auto pop() { events.pop(); }
[[nodiscard]] auto begin() const { return const_cast<Event *>(&events.top()); } [[nodiscard]] auto begin() const { return const_cast<Event *>(&events.top()); }
[[nodiscard]] auto end() const { return begin() + events.size(); } [[nodiscard]] auto end() const { return begin() + events.size(); }
auto push(const Event e) { events.push(e); } auto push(const Event e) { events.push(e); }
}; };
struct Scheduler { struct Scheduler {
Scheduler() { EnqueueAbsolute(std::numeric_limits<u64>::max(), IMPOSSIBLE); } Scheduler() { EnqueueAbsolute(std::numeric_limits<u64>::max(), IMPOSSIBLE); }
static Scheduler &GetInstance() { static Scheduler &GetInstance() {
static Scheduler instance; static Scheduler instance;
return instance; return instance;
} }
void EnqueueRelative(u64, EventType); void EnqueueRelative(u64, EventType);
void EnqueueAbsolute(u64, EventType); void EnqueueAbsolute(u64, EventType);
[[nodiscard]] u64 Remove(EventType) const; [[nodiscard]] u64 Remove(EventType) const;
void Tick(u64 t); [[nodiscard]] Event *Find(EventType) const;
void Tick(u64 t);
u8 index = 0; u8 index = 0;
u64 ticks = 0; u64 ticks = 0;
IterableEvents events{}; IterableEvents events{};
}; };