From c1e70c96867bcc28b30eb55eb703b2ed79640d70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Mon, 28 Sep 2026 18:22:52 -0600 Subject: [PATCH] Unloading a module is busy work, sceKernelVolatileMemTryLock is quick From pspautotests threads/scheduling/syscallkinds: - sceKernelUnloadModule takes ~400us that better threads can preempt and worse ones don't get in on, so it uses the busy delay rather than a wait. - A successful sceKernelVolatileMemTryLock takes under 100us. It ate 500000 cycles as a hack for Crash Tag Team Racing, which has since moved to (and no longer needs) the DrawSyncEatCycles compat flag. Co-Authored-By: Claude Opus 5.5 (1M context) --- Core/HLE/sceKernelModule.cpp | 4 +++- Core/HLE/scePower.cpp | 8 +++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Core/HLE/sceKernelModule.cpp b/Core/HLE/sceKernelModule.cpp index bb525627ae..c98837bd79 100644 --- a/Core/HLE/sceKernelModule.cpp +++ b/Core/HLE/sceKernelModule.cpp @@ -2714,7 +2714,9 @@ static u32 sceKernelUnloadModule(u32 moduleId) { module->Cleanup(); kernelObjects.Destroy(moduleId); - return hleDelayResult(hleLogDebug(Log::sceModule, moduleId), "module unloaded", 500); + // About 400us of work that better threads can preempt, and worse ones don't get in on + // (tests/threads/scheduling/syscallkinds). + return __KernelBusyDelayResult(hleLogDebug(Log::sceModule, moduleId), (int)usToCycles(400), "module unloaded"); } u32 __KernelStopUnloadSelfModuleWithOrWithoutStatus(u32 exitCode, u32 argSize, u32 argp, u32 statusAddr, u32 optionAddr, bool WithStatus) { diff --git a/Core/HLE/scePower.cpp b/Core/HLE/scePower.cpp index 43ca06633c..90cc481c7b 100644 --- a/Core/HLE/scePower.cpp +++ b/Core/HLE/scePower.cpp @@ -334,11 +334,9 @@ static int sceKernelVolatileMemTryLock(int type, u32 paddr, u32 psize) { switch (error) { case 0: - // HACK: This fixes Crash Tag Team Racing. - // Should only wait 1200 cycles though according to Unknown's testing, - // and with that it's still broken. So it's not this, unfortunately. - // Leaving it in for the 0.9.8 release anyway. - hleEatCycles(500000); + // Under 100us on hardware (tests/threads/scheduling/syscallkinds). This used to eat 500000 + // cycles as a hack for Crash Tag Team Racing, which no longer needs it. + hleEatCycles(1200); DEBUG_LOG(Log::HLE, "sceKernelVolatileMemTryLock(%i, %08x, %08x) - success", type, paddr, psize); break;