don't use std::map and std::function in scheduler

This commit is contained in:
RSDuck 2024-11-20 02:55:40 +01:00
parent f6f993cb41
commit d0d010b09d
12 changed files with 68 additions and 59 deletions

View File

@ -40,8 +40,8 @@ const u32 DSi_CamModule::kTransferStart = 60000;
DSi_CamModule::DSi_CamModule(melonDS::DSi& dsi) : DSi(dsi) DSi_CamModule::DSi_CamModule(melonDS::DSi& dsi) : DSi(dsi)
{ {
DSi.RegisterEventFunc(Event_DSi_CamIRQ, 0, MemberEventFunc(DSi_CamModule, IRQ)); DSi.RegisterEventFuncs(Event_DSi_CamIRQ, this, {MakeEventThunk(DSi_CamModule, IRQ)});
DSi.RegisterEventFunc(Event_DSi_CamTransfer, 0, MemberEventFunc(DSi_CamModule, TransferScanline)); DSi.RegisterEventFuncs(Event_DSi_CamTransfer, this, {MakeEventThunk(DSi_CamModule, TransferScanline)});
Camera0 = DSi.I2C.GetOuterCamera(); Camera0 = DSi.I2C.GetOuterCamera();
Camera1 = DSi.I2C.GetInnerCamera(); Camera1 = DSi.I2C.GetInnerCamera();
@ -52,8 +52,8 @@ DSi_CamModule::~DSi_CamModule()
Camera0 = nullptr; Camera0 = nullptr;
Camera1 = nullptr; Camera1 = nullptr;
DSi.UnregisterEventFunc(Event_DSi_CamIRQ, 0); DSi.UnregisterEventFuncs(Event_DSi_CamIRQ);
DSi.UnregisterEventFunc(Event_DSi_CamTransfer, 0); DSi.UnregisterEventFuncs(Event_DSi_CamTransfer);
} }
void DSi_CamModule::Reset() void DSi_CamModule::Reset()

View File

@ -109,7 +109,7 @@ void DSi_DSP::AudioCb(std::array<s16, 2> frame)
DSi_DSP::DSi_DSP(melonDS::DSi& dsi) : DSi(dsi) DSi_DSP::DSi_DSP(melonDS::DSi& dsi) : DSi(dsi)
{ {
DSi.RegisterEventFunc(Event_DSi_DSP, 0, MemberEventFunc(DSi_DSP, DSPCatchUpU32)); DSi.RegisterEventFuncs(Event_DSi_DSP, this, {MakeEventThunk(DSi_DSP, DSPCatchUpU32)});
TeakraCore = new Teakra::Teakra(); TeakraCore = new Teakra::Teakra();
SCFG_RST = false; SCFG_RST = false;
@ -156,7 +156,7 @@ DSi_DSP::~DSi_DSP()
//PDATAWriteFifo = NULL; //PDATAWriteFifo = NULL;
TeakraCore = NULL; TeakraCore = NULL;
DSi.UnregisterEventFunc(Event_DSi_DSP, 0); DSi.UnregisterEventFuncs(Event_DSi_DSP);
} }
void DSi_DSP::Reset() void DSi_DSP::Reset()

View File

@ -134,7 +134,7 @@ DSi_NWifi::DSi_NWifi(melonDS::DSi& dsi, DSi_SDHost* host) :
}, },
DSi(dsi) DSi(dsi)
{ {
DSi.RegisterEventFunc(Event_DSi_NWifi, 0, MemberEventFunc(DSi_NWifi, MSTimer)); DSi.RegisterEventFuncs(Event_DSi_NWifi, this, {MakeEventThunk(DSi_NWifi, MSTimer)});
// this seems to control whether the firmware upload is done // this seems to control whether the firmware upload is done
EEPROMReady = 0; EEPROMReady = 0;
@ -144,7 +144,7 @@ DSi_NWifi::~DSi_NWifi()
{ {
DSi.CancelEvent(Event_DSi_NWifi); DSi.CancelEvent(Event_DSi_NWifi);
DSi.UnregisterEventFunc(Event_DSi_NWifi, 0); DSi.UnregisterEventFuncs(Event_DSi_NWifi);
} }
void DSi_NWifi::Reset() void DSi_NWifi::Reset()

View File

@ -64,10 +64,9 @@ enum
DSi_SDHost::DSi_SDHost(melonDS::DSi& dsi, DSi_NAND::NANDImage&& nand, std::optional<FATStorage>&& sdcard) noexcept : DSi(dsi), Num(0) DSi_SDHost::DSi_SDHost(melonDS::DSi& dsi, DSi_NAND::NANDImage&& nand, std::optional<FATStorage>&& sdcard) noexcept : DSi(dsi), Num(0)
{ {
DSi.RegisterEventFunc( Event_DSi_SDMMCTransfer, DSi.RegisterEventFuncs(Event_DSi_SDMMCTransfer, this,
Transfer_TX, MemberEventFunc(DSi_SDHost, FinishTX)); {MakeEventThunk(DSi_SDHost, FinishTX),
DSi.RegisterEventFunc( Event_DSi_SDMMCTransfer, MakeEventThunk(DSi_SDHost, FinishRX)});
Transfer_RX, MemberEventFunc(DSi_SDHost, FinishRX));
Ports[0] = sdcard ? std::make_unique<DSi_MMCStorage>(DSi, this, std::move(*sdcard)) : nullptr; Ports[0] = sdcard ? std::make_unique<DSi_MMCStorage>(DSi, this, std::move(*sdcard)) : nullptr;
sdcard = std::nullopt; // to ensure that sdcard isn't left with a moved-from object sdcard = std::nullopt; // to ensure that sdcard isn't left with a moved-from object
@ -77,10 +76,9 @@ DSi_SDHost::DSi_SDHost(melonDS::DSi& dsi, DSi_NAND::NANDImage&& nand, std::optio
// Creates an SDIO host // Creates an SDIO host
DSi_SDHost::DSi_SDHost(melonDS::DSi& dsi) noexcept : DSi(dsi), Num(1) DSi_SDHost::DSi_SDHost(melonDS::DSi& dsi) noexcept : DSi(dsi), Num(1)
{ {
DSi.RegisterEventFunc(Event_DSi_SDIOTransfer , DSi.RegisterEventFuncs(Event_DSi_SDIOTransfer, this,
Transfer_TX, MemberEventFunc(DSi_SDHost, FinishTX)); {MakeEventThunk(DSi_SDHost, FinishTX),
DSi.RegisterEventFunc(Event_DSi_SDIOTransfer, MakeEventThunk(DSi_SDHost, FinishRX)});
Transfer_RX, MemberEventFunc(DSi_SDHost, FinishRX));
Ports[0] = std::make_unique<DSi_NWifi>(DSi, this); Ports[0] = std::make_unique<DSi_NWifi>(DSi, this);
Ports[1] = nullptr; Ports[1] = nullptr;
@ -88,10 +86,7 @@ DSi_SDHost::DSi_SDHost(melonDS::DSi& dsi) noexcept : DSi(dsi), Num(1)
DSi_SDHost::~DSi_SDHost() DSi_SDHost::~DSi_SDHost()
{ {
DSi.UnregisterEventFunc(Num ? Event_DSi_SDIOTransfer : Event_DSi_SDMMCTransfer, DSi.UnregisterEventFuncs(Num ? Event_DSi_SDIOTransfer : Event_DSi_SDMMCTransfer);
Transfer_TX);
DSi.UnregisterEventFunc(Num ? Event_DSi_SDIOTransfer : Event_DSi_SDMMCTransfer,
Transfer_RX);
// unique_ptr's destructor will clean up the ports // unique_ptr's destructor will clean up the ports
} }

View File

@ -70,10 +70,13 @@ GPU::GPU(melonDS::NDS& nds, std::unique_ptr<Renderer3D>&& renderer3d, std::uniqu
GPU3D(nds, renderer3d ? std::move(renderer3d) : std::make_unique<SoftRenderer>()), GPU3D(nds, renderer3d ? std::move(renderer3d) : std::make_unique<SoftRenderer>()),
GPU2D_Renderer(renderer2d ? std::move(renderer2d) : std::make_unique<GPU2D::SoftRenderer>(*this)) GPU2D_Renderer(renderer2d ? std::move(renderer2d) : std::make_unique<GPU2D::SoftRenderer>(*this))
{ {
NDS.RegisterEventFunc(Event_LCD, LCD_StartHBlank, MemberEventFunc(GPU, StartHBlank)); NDS.RegisterEventFuncs(Event_LCD, this,
NDS.RegisterEventFunc(Event_LCD, LCD_StartScanline, MemberEventFunc(GPU, StartScanline)); {
NDS.RegisterEventFunc(Event_LCD, LCD_FinishFrame, MemberEventFunc(GPU, FinishFrame)); MakeEventThunk(GPU, StartHBlank),
NDS.RegisterEventFunc(Event_DisplayFIFO, 0, MemberEventFunc(GPU, DisplayFIFO)); MakeEventThunk(GPU, StartScanline),
MakeEventThunk(GPU, FinishFrame)
});
NDS.RegisterEventFuncs(Event_DisplayFIFO, this, {MakeEventThunk(GPU, DisplayFIFO)});
InitFramebuffers(); InitFramebuffers();
} }
@ -82,10 +85,8 @@ GPU::~GPU() noexcept
{ {
// All unique_ptr fields are automatically cleaned up // All unique_ptr fields are automatically cleaned up
NDS.UnregisterEventFunc(Event_LCD, LCD_StartHBlank); NDS.UnregisterEventFuncs(Event_LCD);
NDS.UnregisterEventFunc(Event_LCD, LCD_StartScanline); NDS.UnregisterEventFuncs(Event_DisplayFIFO);
NDS.UnregisterEventFunc(Event_LCD, LCD_FinishFrame);
NDS.UnregisterEventFunc(Event_DisplayFIFO, 0);
} }
void GPU::ResetVRAMCache() noexcept void GPU::ResetVRAMCache() noexcept

View File

@ -122,19 +122,18 @@ NDS::NDS(NDSArgs&& args, int type, void* userdata) noexcept :
DMA(1, 3, *this), DMA(1, 3, *this),
} }
{ {
RegisterEventFunc(Event_Div, 0, MemberEventFunc(NDS, DivDone)); RegisterEventFuncs(Event_Div, this, {MakeEventThunk(NDS, DivDone)});
RegisterEventFunc(Event_Sqrt, 0, MemberEventFunc(NDS, SqrtDone)); RegisterEventFuncs(Event_Sqrt, this, {MakeEventThunk(NDS, SqrtDone)});
MainRAM = JIT.Memory.GetMainRAM(); MainRAM = JIT.Memory.GetMainRAM();
SharedWRAM = JIT.Memory.GetSharedWRAM(); SharedWRAM = JIT.Memory.GetSharedWRAM();
ARM7WRAM = JIT.Memory.GetARM7WRAM(); ARM7WRAM = JIT.Memory.GetARM7WRAM();
} }
NDS::~NDS() noexcept NDS::~NDS() noexcept
{ {
UnregisterEventFunc(Event_Div, 0); UnregisterEventFuncs(Event_Div);
UnregisterEventFunc(Event_Sqrt, 0); UnregisterEventFuncs(Event_Sqrt);
// The destructor for each component is automatically called by the compiler // The destructor for each component is automatically called by the compiler
} }
@ -819,7 +818,7 @@ void NDS::RunSystem(u64 timestamp)
SchedListMask &= ~(1<<i); SchedListMask &= ~(1<<i);
EventFunc func = evt.Funcs[evt.FuncID]; EventFunc func = evt.Funcs[evt.FuncID];
func(evt.Param); func(evt.That, evt.Param);
} }
} }
@ -876,7 +875,7 @@ void NDS::RunSystemSleep(u64 timestamp)
param = evt.Param; param = evt.Param;
EventFunc func = evt.Funcs[evt.FuncID]; EventFunc func = evt.Funcs[evt.FuncID];
func(param); func(this, param);
} }
} }
} }
@ -1074,18 +1073,26 @@ void NDS::Reschedule(u64 target)
} }
} }
void NDS::RegisterEventFunc(u32 id, u32 funcid, EventFunc func) void NDS::RegisterEventFuncs(u32 id, void* that, const std::initializer_list<EventFunc>& funcs)
{ {
SchedEvent& evt = SchedList[id]; SchedEvent& evt = SchedList[id];
evt.Funcs[funcid] = func; evt.That = that;
assert(funcs.size() <= MaxEventFunctions);
int i = 0;
for (EventFunc func : funcs)
{
evt.Funcs[i++] = func;
}
} }
void NDS::UnregisterEventFunc(u32 id, u32 funcid) void NDS::UnregisterEventFuncs(u32 id)
{ {
SchedEvent& evt = SchedList[id]; SchedEvent& evt = SchedList[id];
evt.Funcs.erase(funcid); evt.That = nullptr;
for (int i = 0; i < MaxEventFunctions; i++)
evt.Funcs[i] = nullptr;
} }
void NDS::ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param) void NDS::ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param)

View File

@ -76,11 +76,15 @@ enum
Event_MAX Event_MAX
}; };
typedef std::function<void(u32)> EventFunc; static constexpr u32 MaxEventFunctions = 3;
#define MemberEventFunc(cls,func) std::bind(&cls::func,this,std::placeholders::_1)
typedef void (*EventFunc)(void* that, u32 param);
#define MakeEventThunk(class, func) [](void* that, u32 param) { static_cast<class*>(that)->func(param); }
struct SchedEvent struct SchedEvent
{ {
std::map<u32, EventFunc> Funcs; std::array<EventFunc, MaxEventFunctions> Funcs;
void* That;
u64 Timestamp; u64 Timestamp;
u32 FuncID; u32 FuncID;
u32 Param; u32 Param;
@ -401,8 +405,8 @@ public: // TODO: Encapsulate the rest of these members
virtual void CamInputFrame(int cam, const u32* data, int width, int height, bool rgb) {} virtual void CamInputFrame(int cam, const u32* data, int width, int height, bool rgb) {}
void MicInputFrame(s16* data, int samples); void MicInputFrame(s16* data, int samples);
void RegisterEventFunc(u32 id, u32 funcid, EventFunc func); void RegisterEventFuncs(u32 id, void* that, const std::initializer_list<EventFunc>& funcs);
void UnregisterEventFunc(u32 id, u32 funcid); void UnregisterEventFuncs(u32 id);
void ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param); void ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param);
void CancelEvent(u32 id); void CancelEvent(u32 id);

View File

@ -1441,9 +1441,12 @@ void CartHomebrew::ROMCommandFinish(const u8* cmd, u8* data, u32 len)
NDSCartSlot::NDSCartSlot(melonDS::NDS& nds, std::unique_ptr<CartCommon>&& rom) noexcept : NDS(nds) NDSCartSlot::NDSCartSlot(melonDS::NDS& nds, std::unique_ptr<CartCommon>&& rom) noexcept : NDS(nds)
{ {
NDS.RegisterEventFunc(Event_ROMTransfer, ROMTransfer_PrepareData, MemberEventFunc(NDSCartSlot, ROMPrepareData)); NDS.RegisterEventFuncs(Event_ROMTransfer, this,
NDS.RegisterEventFunc(Event_ROMTransfer, ROMTransfer_End, MemberEventFunc(NDSCartSlot, ROMEndTransfer)); {
NDS.RegisterEventFunc(Event_ROMSPITransfer, 0, MemberEventFunc(NDSCartSlot, SPITransferDone)); MakeEventThunk(NDSCartSlot, ROMPrepareData),
MakeEventThunk(NDSCartSlot, ROMEndTransfer)
});
NDS.RegisterEventFuncs(Event_ROMSPITransfer, this, {MakeEventThunk(NDSCartSlot, SPITransferDone)});
// All fields are default-constructed because they're listed as such in the class declaration // All fields are default-constructed because they're listed as such in the class declaration
if (rom) if (rom)
@ -1452,9 +1455,8 @@ NDSCartSlot::NDSCartSlot(melonDS::NDS& nds, std::unique_ptr<CartCommon>&& rom) n
NDSCartSlot::~NDSCartSlot() noexcept NDSCartSlot::~NDSCartSlot() noexcept
{ {
NDS.UnregisterEventFunc(Event_ROMTransfer, ROMTransfer_PrepareData); NDS.UnregisterEventFuncs(Event_ROMTransfer);
NDS.UnregisterEventFunc(Event_ROMTransfer, ROMTransfer_End); NDS.UnregisterEventFuncs(Event_ROMSPITransfer);
NDS.UnregisterEventFunc(Event_ROMSPITransfer, 0);
// Cart is cleaned up automatically because it's a unique_ptr // Cart is cleaned up automatically because it's a unique_ptr
} }

View File

@ -34,7 +34,7 @@ void WriteDateTime(int num, u8 val);
RTC::RTC(melonDS::NDS& nds) : NDS(nds) RTC::RTC(melonDS::NDS& nds) : NDS(nds)
{ {
NDS.RegisterEventFunc(Event_RTC, 0, MemberEventFunc(RTC, ClockTimer)); NDS.RegisterEventFuncs(Event_RTC, this, {MakeEventThunk(RTC, ClockTimer)});
ResetState(); ResetState();
@ -45,7 +45,7 @@ RTC::RTC(melonDS::NDS& nds) : NDS(nds)
RTC::~RTC() RTC::~RTC()
{ {
NDS.UnregisterEventFunc(Event_RTC, 0); NDS.UnregisterEventFuncs(Event_RTC);
} }
void RTC::Reset() void RTC::Reset()

View File

@ -474,7 +474,7 @@ void TSC::Write(u8 val)
SPIHost::SPIHost(melonDS::NDS& nds, Firmware&& firmware) : NDS(nds) SPIHost::SPIHost(melonDS::NDS& nds, Firmware&& firmware) : NDS(nds)
{ {
NDS.RegisterEventFunc(Event_SPITransfer, 0, MemberEventFunc(SPIHost, TransferDone)); NDS.RegisterEventFuncs(Event_SPITransfer, this, {MakeEventThunk(SPIHost, TransferDone)});
Devices[SPIDevice_FirmwareMem] = new FirmwareMem(NDS, std::move(firmware)); Devices[SPIDevice_FirmwareMem] = new FirmwareMem(NDS, std::move(firmware));
Devices[SPIDevice_PowerMan] = new PowerMan(NDS); Devices[SPIDevice_PowerMan] = new PowerMan(NDS);
@ -495,7 +495,7 @@ SPIHost::~SPIHost()
Devices[i] = nullptr; Devices[i] = nullptr;
} }
NDS.UnregisterEventFunc(Event_SPITransfer, 0); NDS.UnregisterEventFuncs(Event_SPITransfer);
} }
void SPIHost::Reset() void SPIHost::Reset()

View File

@ -202,7 +202,7 @@ SPU::SPU(melonDS::NDS& nds, AudioBitDepth bitdepth, AudioInterpolation interpola
AudioLock(Platform::Mutex_Create()), AudioLock(Platform::Mutex_Create()),
Degrade10Bit(bitdepth == AudioBitDepth::_10Bit || (nds.ConsoleType == 1 && bitdepth == AudioBitDepth::Auto)) Degrade10Bit(bitdepth == AudioBitDepth::_10Bit || (nds.ConsoleType == 1 && bitdepth == AudioBitDepth::Auto))
{ {
NDS.RegisterEventFunc(Event_SPU, 0, MemberEventFunc(SPU, Mix)); NDS.RegisterEventFuncs(Event_SPU, this, {MakeEventThunk(SPU, Mix)});
ApplyBias = true; ApplyBias = true;
Degrade10Bit = false; Degrade10Bit = false;
@ -219,7 +219,7 @@ SPU::~SPU()
Platform::Mutex_Free(AudioLock); Platform::Mutex_Free(AudioLock);
AudioLock = nullptr; AudioLock = nullptr;
NDS.UnregisterEventFunc(Event_SPU, 0); NDS.UnregisterEventFuncs(Event_SPU);
} }
void SPU::Reset() void SPU::Reset()

View File

@ -91,7 +91,7 @@ bool MACIsBroadcast(const u8* a)
Wifi::Wifi(melonDS::NDS& nds) : NDS(nds) Wifi::Wifi(melonDS::NDS& nds) : NDS(nds)
{ {
NDS.RegisterEventFunc(Event_Wifi, 0, MemberEventFunc(Wifi, USTimer)); NDS.RegisterEventFuncs(Event_Wifi, this, {MakeEventThunk(Wifi, USTimer)});
WifiAP = new class WifiAP(this, NDS.UserData); WifiAP = new class WifiAP(this, NDS.UserData);
} }
@ -100,7 +100,7 @@ Wifi::~Wifi()
{ {
delete WifiAP; WifiAP = nullptr; delete WifiAP; WifiAP = nullptr;
NDS.UnregisterEventFunc(Event_Wifi, 0); NDS.UnregisterEventFuncs(Event_Wifi);
} }
void Wifi::Reset() void Wifi::Reset()