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.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()

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.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()

View File

@ -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()

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.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_MMCStorage>(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_NWifi>(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
}

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>()),
GPU2D_Renderer(renderer2d ? std::move(renderer2d) : std::make_unique<GPU2D::SoftRenderer>(*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

View File

@ -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<<i);
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;
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];
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<<id))
{
Log(LogLevel::Debug, "!! EVENT %d ALREADY SCHEDULED\n", id);
return;
return;
}
SchedEvent& evt = SchedList[id];

View File

@ -76,11 +76,15 @@ enum
Event_MAX
};
typedef std::function<void(u32)> 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<class*>(that)->func(param); }
struct SchedEvent
{
std::map<u32, EventFunc> Funcs;
std::array<EventFunc, MaxEventFunctions> 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<EventFunc>& funcs);
void UnregisterEventFuncs(u32 id);
void ScheduleEvent(u32 id, bool periodic, s32 delay, u32 funcid, u32 param);
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)
{
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<CartCommon>&& 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
}

View File

@ -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()

View File

@ -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()

View File

@ -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()

View File

@ -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()