bsnes/higan/emulator/scheduler.hpp

66 lines
1.4 KiB
C++

#pragma once
namespace Emulator {
struct Scheduler {
enum class Mode : uint {
Run,
SynchronizeMaster,
SynchronizeSlave,
};
enum class Event : uint {
Step,
Frame,
Synchronize,
};
auto reset(cothread_t master_) -> void {
master = resume = master_;
host = co_active();
}
auto enter(Mode mode_ = Mode::Run) -> Event {
mode = mode_;
host = co_active();
co_switch(resume);
return event;
}
auto exit(Event event_) -> void {
event = event_;
resume = co_active();
co_switch(host);
}
auto synchronize(cothread_t thread) -> void {
if(thread == master) {
while(enter(Mode::SynchronizeMaster) != Event::Synchronize);
} else {
resume = thread;
while(enter(Mode::SynchronizeSlave) != Event::Synchronize);
}
}
auto synchronize() -> void {
if(co_active() == master) {
if(mode == Mode::SynchronizeMaster) return exit(Event::Synchronize);
} else {
if(mode == Mode::SynchronizeSlave) return exit(Event::Synchronize);
}
}
auto synchronizing() const -> bool {
return mode == Mode::SynchronizeSlave;
}
private:
cothread_t host = nullptr; //program thread (used to exit scheduler)
cothread_t resume = nullptr; //resume thread (used to enter scheduler)
cothread_t master = nullptr; //primary thread (used to synchronize components)
Mode mode = Mode::Run;
Event event = Event::Step;
};
}