From d0d010b09db42db0aab24b5ac2ffa1cc3107b1c7 Mon Sep 17 00:00:00 2001 From: RSDuck Date: Wed, 20 Nov 2024 02:55:40 +0100 Subject: [PATCH] don't use std::map and std::function in scheduler --- src/DSi_Camera.cpp | 8 ++++---- src/DSi_DSP.cpp | 4 ++-- src/DSi_NWifi.cpp | 4 ++-- src/DSi_SD.cpp | 19 +++++++------------ src/GPU.cpp | 17 +++++++++-------- src/NDS.cpp | 31 +++++++++++++++++++------------ src/NDS.h | 14 +++++++++----- src/NDSCart.cpp | 14 ++++++++------ src/RTC.cpp | 4 ++-- src/SPI.cpp | 4 ++-- src/SPU.cpp | 4 ++-- src/Wifi.cpp | 4 ++-- 12 files changed, 68 insertions(+), 59 deletions(-) diff --git a/src/DSi_Camera.cpp b/src/DSi_Camera.cpp index b1d60d04..8a54bb18 100644 --- a/src/DSi_Camera.cpp +++ b/src/DSi_Camera.cpp @@ -40,8 +40,8 @@ const u32 DSi_CamModule::kTransferStart = 60000; DSi_CamModule::DSi_CamModule(melonDS::DSi& dsi) : DSi(dsi) { - DSi.RegisterEventFunc(Event_DSi_CamIRQ, 0, MemberEventFunc(DSi_CamModule, IRQ)); - DSi.RegisterEventFunc(Event_DSi_CamTransfer, 0, MemberEventFunc(DSi_CamModule, TransferScanline)); + DSi.RegisterEventFuncs(Event_DSi_CamIRQ, this, {MakeEventThunk(DSi_CamModule, IRQ)}); + DSi.RegisterEventFuncs(Event_DSi_CamTransfer, this, {MakeEventThunk(DSi_CamModule, TransferScanline)}); Camera0 = DSi.I2C.GetOuterCamera(); Camera1 = DSi.I2C.GetInnerCamera(); @@ -52,8 +52,8 @@ DSi_CamModule::~DSi_CamModule() Camera0 = nullptr; Camera1 = nullptr; - DSi.UnregisterEventFunc(Event_DSi_CamIRQ, 0); - DSi.UnregisterEventFunc(Event_DSi_CamTransfer, 0); + DSi.UnregisterEventFuncs(Event_DSi_CamIRQ); + DSi.UnregisterEventFuncs(Event_DSi_CamTransfer); } void DSi_CamModule::Reset() diff --git a/src/DSi_DSP.cpp b/src/DSi_DSP.cpp index 25abd474..24fa08b3 100644 --- a/src/DSi_DSP.cpp +++ b/src/DSi_DSP.cpp @@ -109,7 +109,7 @@ void DSi_DSP::AudioCb(std::array frame) 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(); SCFG_RST = false; @@ -156,7 +156,7 @@ DSi_DSP::~DSi_DSP() //PDATAWriteFifo = NULL; TeakraCore = NULL; - DSi.UnregisterEventFunc(Event_DSi_DSP, 0); + DSi.UnregisterEventFuncs(Event_DSi_DSP); } void DSi_DSP::Reset() diff --git a/src/DSi_NWifi.cpp b/src/DSi_NWifi.cpp index 9cfb0203..3ec5d3f0 100644 --- a/src/DSi_NWifi.cpp +++ b/src/DSi_NWifi.cpp @@ -134,7 +134,7 @@ DSi_NWifi::DSi_NWifi(melonDS::DSi& dsi, DSi_SDHost* host) : }, 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 EEPROMReady = 0; @@ -144,7 +144,7 @@ DSi_NWifi::~DSi_NWifi() { DSi.CancelEvent(Event_DSi_NWifi); - DSi.UnregisterEventFunc(Event_DSi_NWifi, 0); + DSi.UnregisterEventFuncs(Event_DSi_NWifi); } void DSi_NWifi::Reset() diff --git a/src/DSi_SD.cpp b/src/DSi_SD.cpp index c600bc76..c1d07682 100644 --- a/src/DSi_SD.cpp +++ b/src/DSi_SD.cpp @@ -64,10 +64,9 @@ enum DSi_SDHost::DSi_SDHost(melonDS::DSi& dsi, DSi_NAND::NANDImage&& nand, std::optional&& sdcard) noexcept : DSi(dsi), Num(0) { - DSi.RegisterEventFunc( Event_DSi_SDMMCTransfer, - Transfer_TX, MemberEventFunc(DSi_SDHost, FinishTX)); - DSi.RegisterEventFunc( Event_DSi_SDMMCTransfer, - Transfer_RX, MemberEventFunc(DSi_SDHost, FinishRX)); + DSi.RegisterEventFuncs(Event_DSi_SDMMCTransfer, this, + {MakeEventThunk(DSi_SDHost, FinishTX), + MakeEventThunk(DSi_SDHost, FinishRX)}); Ports[0] = sdcard ? std::make_unique(DSi, this, std::move(*sdcard)) : nullptr; 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 DSi_SDHost::DSi_SDHost(melonDS::DSi& dsi) noexcept : DSi(dsi), Num(1) { - DSi.RegisterEventFunc(Event_DSi_SDIOTransfer , - Transfer_TX, MemberEventFunc(DSi_SDHost, FinishTX)); - DSi.RegisterEventFunc(Event_DSi_SDIOTransfer, - Transfer_RX, MemberEventFunc(DSi_SDHost, FinishRX)); + DSi.RegisterEventFuncs(Event_DSi_SDIOTransfer, this, + {MakeEventThunk(DSi_SDHost, FinishTX), + MakeEventThunk(DSi_SDHost, FinishRX)}); Ports[0] = std::make_unique(DSi, this); Ports[1] = nullptr; @@ -88,10 +86,7 @@ DSi_SDHost::DSi_SDHost(melonDS::DSi& dsi) noexcept : DSi(dsi), Num(1) DSi_SDHost::~DSi_SDHost() { - DSi.UnregisterEventFunc(Num ? Event_DSi_SDIOTransfer : Event_DSi_SDMMCTransfer, - Transfer_TX); - DSi.UnregisterEventFunc(Num ? Event_DSi_SDIOTransfer : Event_DSi_SDMMCTransfer, - Transfer_RX); + DSi.UnregisterEventFuncs(Num ? Event_DSi_SDIOTransfer : Event_DSi_SDMMCTransfer); // unique_ptr's destructor will clean up the ports } diff --git a/src/GPU.cpp b/src/GPU.cpp index f24d8ab5..585f0bea 100644 --- a/src/GPU.cpp +++ b/src/GPU.cpp @@ -70,10 +70,13 @@ GPU::GPU(melonDS::NDS& nds, std::unique_ptr&& renderer3d, std::uniqu GPU3D(nds, renderer3d ? std::move(renderer3d) : std::make_unique()), GPU2D_Renderer(renderer2d ? std::move(renderer2d) : std::make_unique(*this)) { - NDS.RegisterEventFunc(Event_LCD, LCD_StartHBlank, MemberEventFunc(GPU, StartHBlank)); - NDS.RegisterEventFunc(Event_LCD, LCD_StartScanline, MemberEventFunc(GPU, StartScanline)); - NDS.RegisterEventFunc(Event_LCD, LCD_FinishFrame, MemberEventFunc(GPU, FinishFrame)); - NDS.RegisterEventFunc(Event_DisplayFIFO, 0, MemberEventFunc(GPU, DisplayFIFO)); + NDS.RegisterEventFuncs(Event_LCD, this, + { + MakeEventThunk(GPU, StartHBlank), + MakeEventThunk(GPU, StartScanline), + MakeEventThunk(GPU, FinishFrame) + }); + NDS.RegisterEventFuncs(Event_DisplayFIFO, this, {MakeEventThunk(GPU, DisplayFIFO)}); InitFramebuffers(); } @@ -82,10 +85,8 @@ GPU::~GPU() noexcept { // All unique_ptr fields are automatically cleaned up - NDS.UnregisterEventFunc(Event_LCD, LCD_StartHBlank); - NDS.UnregisterEventFunc(Event_LCD, LCD_StartScanline); - NDS.UnregisterEventFunc(Event_LCD, LCD_FinishFrame); - NDS.UnregisterEventFunc(Event_DisplayFIFO, 0); + NDS.UnregisterEventFuncs(Event_LCD); + NDS.UnregisterEventFuncs(Event_DisplayFIFO); } void GPU::ResetVRAMCache() noexcept diff --git a/src/NDS.cpp b/src/NDS.cpp index b9370c6b..7cef3bf0 100644 --- a/src/NDS.cpp +++ b/src/NDS.cpp @@ -122,19 +122,18 @@ NDS::NDS(NDSArgs&& args, int type, void* userdata) noexcept : DMA(1, 3, *this), } { - RegisterEventFunc(Event_Div, 0, MemberEventFunc(NDS, DivDone)); - RegisterEventFunc(Event_Sqrt, 0, MemberEventFunc(NDS, SqrtDone)); + RegisterEventFuncs(Event_Div, this, {MakeEventThunk(NDS, DivDone)}); + RegisterEventFuncs(Event_Sqrt, this, {MakeEventThunk(NDS, SqrtDone)}); MainRAM = JIT.Memory.GetMainRAM(); SharedWRAM = JIT.Memory.GetSharedWRAM(); ARM7WRAM = JIT.Memory.GetARM7WRAM(); - } NDS::~NDS() noexcept { - UnregisterEventFunc(Event_Div, 0); - UnregisterEventFunc(Event_Sqrt, 0); + UnregisterEventFuncs(Event_Div); + UnregisterEventFuncs(Event_Sqrt); // The destructor for each component is automatically called by the compiler } @@ -819,7 +818,7 @@ void NDS::RunSystem(u64 timestamp) SchedListMask &= ~(1<& funcs) { 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]; - 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) @@ -1093,7 +1100,7 @@ void NDS::ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param) if (SchedListMask & (1< EventFunc; -#define MemberEventFunc(cls,func) std::bind(&cls::func,this,std::placeholders::_1) +static constexpr u32 MaxEventFunctions = 3; + +typedef void (*EventFunc)(void* that, u32 param); +#define MakeEventThunk(class, func) [](void* that, u32 param) { static_cast(that)->func(param); } + struct SchedEvent { - std::map Funcs; + std::array Funcs; + void* That; u64 Timestamp; u32 FuncID; 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) {} void MicInputFrame(s16* data, int samples); - void RegisterEventFunc(u32 id, u32 funcid, EventFunc func); - void UnregisterEventFunc(u32 id, u32 funcid); + void RegisterEventFuncs(u32 id, void* that, const std::initializer_list& funcs); + void UnregisterEventFuncs(u32 id); void ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param); void CancelEvent(u32 id); diff --git a/src/NDSCart.cpp b/src/NDSCart.cpp index 97de4580..1fa0fbfe 100644 --- a/src/NDSCart.cpp +++ b/src/NDSCart.cpp @@ -1441,9 +1441,12 @@ void CartHomebrew::ROMCommandFinish(const u8* cmd, u8* data, u32 len) NDSCartSlot::NDSCartSlot(melonDS::NDS& nds, std::unique_ptr&& rom) noexcept : NDS(nds) { - NDS.RegisterEventFunc(Event_ROMTransfer, ROMTransfer_PrepareData, MemberEventFunc(NDSCartSlot, ROMPrepareData)); - NDS.RegisterEventFunc(Event_ROMTransfer, ROMTransfer_End, MemberEventFunc(NDSCartSlot, ROMEndTransfer)); - NDS.RegisterEventFunc(Event_ROMSPITransfer, 0, MemberEventFunc(NDSCartSlot, SPITransferDone)); + NDS.RegisterEventFuncs(Event_ROMTransfer, this, + { + 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 if (rom) @@ -1452,9 +1455,8 @@ NDSCartSlot::NDSCartSlot(melonDS::NDS& nds, std::unique_ptr&& rom) n NDSCartSlot::~NDSCartSlot() noexcept { - NDS.UnregisterEventFunc(Event_ROMTransfer, ROMTransfer_PrepareData); - NDS.UnregisterEventFunc(Event_ROMTransfer, ROMTransfer_End); - NDS.UnregisterEventFunc(Event_ROMSPITransfer, 0); + NDS.UnregisterEventFuncs(Event_ROMTransfer); + NDS.UnregisterEventFuncs(Event_ROMSPITransfer); // Cart is cleaned up automatically because it's a unique_ptr } diff --git a/src/RTC.cpp b/src/RTC.cpp index 24e00de7..c10672fb 100644 --- a/src/RTC.cpp +++ b/src/RTC.cpp @@ -34,7 +34,7 @@ void WriteDateTime(int num, u8 val); RTC::RTC(melonDS::NDS& nds) : NDS(nds) { - NDS.RegisterEventFunc(Event_RTC, 0, MemberEventFunc(RTC, ClockTimer)); + NDS.RegisterEventFuncs(Event_RTC, this, {MakeEventThunk(RTC, ClockTimer)}); ResetState(); @@ -45,7 +45,7 @@ RTC::RTC(melonDS::NDS& nds) : NDS(nds) RTC::~RTC() { - NDS.UnregisterEventFunc(Event_RTC, 0); + NDS.UnregisterEventFuncs(Event_RTC); } void RTC::Reset() diff --git a/src/SPI.cpp b/src/SPI.cpp index 6ab94c3a..67b63e2a 100644 --- a/src/SPI.cpp +++ b/src/SPI.cpp @@ -474,7 +474,7 @@ void TSC::Write(u8 val) 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_PowerMan] = new PowerMan(NDS); @@ -495,7 +495,7 @@ SPIHost::~SPIHost() Devices[i] = nullptr; } - NDS.UnregisterEventFunc(Event_SPITransfer, 0); + NDS.UnregisterEventFuncs(Event_SPITransfer); } void SPIHost::Reset() diff --git a/src/SPU.cpp b/src/SPU.cpp index eb30c0a9..5b245890 100644 --- a/src/SPU.cpp +++ b/src/SPU.cpp @@ -202,7 +202,7 @@ SPU::SPU(melonDS::NDS& nds, AudioBitDepth bitdepth, AudioInterpolation interpola AudioLock(Platform::Mutex_Create()), 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; Degrade10Bit = false; @@ -219,7 +219,7 @@ SPU::~SPU() Platform::Mutex_Free(AudioLock); AudioLock = nullptr; - NDS.UnregisterEventFunc(Event_SPU, 0); + NDS.UnregisterEventFuncs(Event_SPU); } void SPU::Reset() diff --git a/src/Wifi.cpp b/src/Wifi.cpp index 3eaa9fd3..77933dfb 100644 --- a/src/Wifi.cpp +++ b/src/Wifi.cpp @@ -91,7 +91,7 @@ bool MACIsBroadcast(const u8* a) 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); } @@ -100,7 +100,7 @@ Wifi::~Wifi() { delete WifiAP; WifiAP = nullptr; - NDS.UnregisterEventFunc(Event_Wifi, 0); + NDS.UnregisterEventFuncs(Event_Wifi); } void Wifi::Reset()