2009-05-12 22:20:41 +02:00

141 lines
2.7 KiB
C++
Executable File

//scheduler thread relationships:
//S-PPU <-> S-CPU <-> cartridge co-processor
// <|>
// S-SMP <-> S-DSP
class Scheduler {
public:
cothread_t thread_snes;
cothread_t thread_cpu; //S-CPU (5a22)
cothread_t thread_cop; //cartridge co-processor (SuperFX, SA-1, ...)
cothread_t thread_smp; //S-SMP (SPC700)
cothread_t thread_ppu; //S-PPU
cothread_t thread_dsp; //S-DSP
enum ActiveThread {
THREAD_CPU,
THREAD_COP,
THREAD_SMP,
THREAD_PPU,
THREAD_DSP,
};
struct {
unsigned cpu_freq;
unsigned smp_freq;
ActiveThread active;
int64_t cpucop;
int64_t cpuppu;
int64_t cpusmp;
int64_t smpdsp;
} clock;
//==========
//CPU <> COP
//==========
alwaysinline void sync_cpucop() {
if(clock.cpucop < 0) {
clock.active = THREAD_COP;
co_switch(thread_cop);
}
}
alwaysinline void sync_copcpu() {
if(clock.cpucop >= 0) {
clock.active = THREAD_CPU;
co_switch(thread_cpu);
}
}
//==========
//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);
}
}
//==========
//add clocks
//==========
alwaysinline void addclocks_cpu(unsigned clocks) {
clock.cpucop -= clocks;
clock.cpuppu -= clocks;
clock.cpusmp -= clocks * (uint64_t)clock.smp_freq;
}
alwaysinline void addclocks_cop(unsigned clocks) {
clock.cpucop += clocks;
}
alwaysinline void addclocks_ppu(unsigned clocks) {
clock.cpuppu += clocks;
}
alwaysinline void addclocks_smp(unsigned clocks) {
clock.cpusmp += clocks * (uint64_t)clock.cpu_freq;
clock.smpdsp -= clocks;
}
alwaysinline void addclocks_dsp(unsigned clocks) {
clock.smpdsp += clocks;
}
void enter();
void exit();
void init();
Scheduler();
};
extern Scheduler scheduler;