o cleanup
This commit is contained in:
56
tools/bsnes/snes/scheduler/scheduler.cpp
Executable file
56
tools/bsnes/snes/scheduler/scheduler.cpp
Executable file
@@ -0,0 +1,56 @@
|
||||
#ifdef SNES_CPP
|
||||
|
||||
Scheduler scheduler;
|
||||
|
||||
void threadentry_cpu() { cpu.enter(); }
|
||||
void threadentry_smp() { smp.enter(); }
|
||||
void threadentry_ppu() { ppu.enter(); }
|
||||
void threadentry_dsp() { dsp.enter(); }
|
||||
|
||||
void Scheduler::enter() {
|
||||
switch(clock.active) {
|
||||
case THREAD_CPU: co_switch(thread_cpu); break;
|
||||
case THREAD_SMP: co_switch(thread_smp); break;
|
||||
case THREAD_PPU: co_switch(thread_ppu); break;
|
||||
case THREAD_DSP: co_switch(thread_dsp); break;
|
||||
}
|
||||
}
|
||||
|
||||
void Scheduler::exit() {
|
||||
co_switch(thread_snes);
|
||||
}
|
||||
|
||||
void Scheduler::init() {
|
||||
clock.cpu_freq = snes.region() == SNES::NTSC
|
||||
? snes.config.cpu.ntsc_clock_rate
|
||||
: snes.config.cpu.pal_clock_rate;
|
||||
clock.smp_freq = snes.region() == SNES::NTSC
|
||||
? snes.config.smp.ntsc_clock_rate
|
||||
: snes.config.smp.pal_clock_rate;
|
||||
|
||||
clock.active = THREAD_CPU;
|
||||
clock.cpuppu = 0;
|
||||
clock.cpusmp = 0;
|
||||
clock.smpdsp = 0;
|
||||
|
||||
if(thread_cpu) co_delete(thread_cpu);
|
||||
if(thread_smp) co_delete(thread_smp);
|
||||
if(thread_ppu) co_delete(thread_ppu);
|
||||
if(thread_dsp) co_delete(thread_dsp);
|
||||
|
||||
thread_snes = co_active();
|
||||
thread_cpu = co_create(65536 * sizeof(void*), threadentry_cpu);
|
||||
thread_smp = co_create(65536 * sizeof(void*), threadentry_smp);
|
||||
thread_ppu = co_create(65536 * sizeof(void*), threadentry_ppu);
|
||||
thread_dsp = co_create(65536 * sizeof(void*), threadentry_dsp);
|
||||
}
|
||||
|
||||
Scheduler::Scheduler() {
|
||||
thread_snes = 0;
|
||||
thread_cpu = 0;
|
||||
thread_smp = 0;
|
||||
thread_ppu = 0;
|
||||
thread_dsp = 0;
|
||||
}
|
||||
|
||||
#endif //ifdef SNES_CPP
|
||||
123
tools/bsnes/snes/scheduler/scheduler.hpp
Executable file
123
tools/bsnes/snes/scheduler/scheduler.hpp
Executable file
@@ -0,0 +1,123 @@
|
||||
class Scheduler {
|
||||
public:
|
||||
cothread_t thread_snes;
|
||||
cothread_t thread_cpu;
|
||||
cothread_t thread_smp;
|
||||
cothread_t thread_ppu;
|
||||
cothread_t thread_dsp;
|
||||
|
||||
enum ActiveThread {
|
||||
THREAD_CPU,
|
||||
THREAD_SMP,
|
||||
THREAD_PPU,
|
||||
THREAD_DSP,
|
||||
};
|
||||
|
||||
struct {
|
||||
unsigned cpu_freq;
|
||||
unsigned smp_freq;
|
||||
|
||||
ActiveThread active;
|
||||
int64 cpuppu;
|
||||
int64 cpusmp;
|
||||
int64 smpdsp;
|
||||
} clock;
|
||||
|
||||
//==========
|
||||
//CPU <> PPU
|
||||
//==========
|
||||
|
||||
alwaysinline void sync_cpuppu() {
|
||||
if(clock.cpuppu < 0) {
|
||||
clock.active = THREAD_PPU;
|
||||
co_switch(thread_ppu);
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sync_ppucpu() {
|
||||
if(clock.cpuppu >= 0) {
|
||||
clock.active = THREAD_CPU;
|
||||
co_switch(thread_cpu);
|
||||
}
|
||||
}
|
||||
|
||||
//==========
|
||||
//CPU <> SMP
|
||||
//==========
|
||||
|
||||
alwaysinline void sync_cpusmp() {
|
||||
if(clock.cpusmp < 0) {
|
||||
clock.active = THREAD_SMP;
|
||||
co_switch(thread_smp);
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sync_smpcpu() {
|
||||
if(clock.cpusmp >= 0) {
|
||||
clock.active = THREAD_CPU;
|
||||
co_switch(thread_cpu);
|
||||
}
|
||||
}
|
||||
|
||||
//==========
|
||||
//SMP <> DSP
|
||||
//==========
|
||||
|
||||
alwaysinline void sync_smpdsp() {
|
||||
if(clock.smpdsp < 0) {
|
||||
clock.active = THREAD_DSP;
|
||||
co_switch(thread_dsp);
|
||||
}
|
||||
}
|
||||
|
||||
alwaysinline void sync_dspsmp() {
|
||||
if(clock.smpdsp >= 0) {
|
||||
clock.active = THREAD_SMP;
|
||||
co_switch(thread_smp);
|
||||
}
|
||||
}
|
||||
|
||||
//======
|
||||
//timing
|
||||
//======
|
||||
|
||||
alwaysinline void addclocks_cpu(unsigned clocks) {
|
||||
clock.cpuppu -= clocks;
|
||||
sync_cpuppu();
|
||||
|
||||
clock.cpusmp -= clocks * (uint64)clock.smp_freq;
|
||||
if(clock.cpusmp < -(20000 * (int64)24000000)) sync_cpusmp();
|
||||
}
|
||||
|
||||
alwaysinline void addclocks_ppu(unsigned clocks) {
|
||||
clock.cpuppu += clocks;
|
||||
sync_ppucpu();
|
||||
}
|
||||
|
||||
alwaysinline void addclocks_smp(unsigned clocks) {
|
||||
clock.cpusmp += clocks * (uint64)clock.cpu_freq;
|
||||
if(clock.cpusmp > +(20000 * (int64)24000000)) sync_smpcpu();
|
||||
|
||||
clock.smpdsp -= clocks;
|
||||
#if !defined(USE_STATE_MACHINE)
|
||||
sync_smpdsp();
|
||||
#else
|
||||
while(clock.smpdsp < 0) dsp.enter();
|
||||
#endif
|
||||
}
|
||||
|
||||
alwaysinline void addclocks_dsp(unsigned clocks) {
|
||||
clock.smpdsp += clocks;
|
||||
#if !defined(USE_STATE_MACHINE)
|
||||
sync_dspsmp();
|
||||
#endif
|
||||
}
|
||||
|
||||
void enter();
|
||||
void exit();
|
||||
void init();
|
||||
|
||||
Scheduler();
|
||||
};
|
||||
|
||||
extern Scheduler scheduler;
|
||||
Reference in New Issue
Block a user