From 7fcb758da2370cdd511d78c2577d4a43bd8068e0 Mon Sep 17 00:00:00 2001 From: psucien Date: Mon, 10 Jun 2024 23:48:06 +0200 Subject: [PATCH] timer_management: `sceKernelUsleep` on <1ms delays --- src/core/libraries/kernel/time_management.cpp | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/core/libraries/kernel/time_management.cpp b/src/core/libraries/kernel/time_management.cpp index 8c31c550..3f5f92ee 100644 --- a/src/core/libraries/kernel/time_management.cpp +++ b/src/core/libraries/kernel/time_management.cpp @@ -9,9 +9,16 @@ #include "core/libraries/libs.h" #ifdef _WIN64 +#include #include + +// http://stackoverflow.com/a/31411628/4725495 +static u32(__stdcall* NtDelayExecution)(BOOL Alertable, PLARGE_INTEGER DelayInterval) = + (u32(__stdcall*)(BOOL, PLARGE_INTEGER))GetProcAddress(GetModuleHandle("ntdll.dll"), + "NtDelayExecution"); #else #include +#include #endif namespace Libraries::Kernel { @@ -40,8 +47,18 @@ u64 PS4_SYSV_ABI sceKernelReadTsc() { } int PS4_SYSV_ABI sceKernelUsleep(u32 microseconds) { - ASSERT(microseconds >= 1000); - std::this_thread::sleep_for(std::chrono::microseconds(microseconds)); + if (microseconds < 1000u) { +#if _WIN64 + LARGE_INTEGER interval{ + .QuadPart = -1 * (microseconds * 10u), + }; + NtDelayExecution(FALSE, &interval); + } else { + std::this_thread::sleep_for(std::chrono::microseconds(microseconds)); + } +#else + usleep(microseconds); +#endif return 0; }