From a00ffe6ec3a5d13ce2ac5590895176c029c18250 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Mon, 28 Jul 2025 18:33:05 +0200 Subject: [PATCH] Add `Platform::Yield` --- Source/Engine/Platform/Android/AndroidPlatform.cpp | 5 +++++ Source/Engine/Platform/Android/AndroidPlatform.h | 1 + Source/Engine/Platform/Apple/ApplePlatform.cpp | 5 +++++ Source/Engine/Platform/Apple/ApplePlatform.h | 1 + Source/Engine/Platform/Base/PlatformBase.h | 7 ++++++- Source/Engine/Platform/Linux/LinuxPlatform.cpp | 5 +++++ Source/Engine/Platform/Linux/LinuxPlatform.h | 1 + Source/Engine/Platform/Win32/IncludeWindowsHeaders.h | 1 + Source/Engine/Platform/Win32/Win32Platform.cpp | 5 +++++ Source/Engine/Platform/Win32/Win32Platform.h | 1 + Source/Engine/Renderer/RenderListBuffer.h | 2 +- Source/Engine/Threading/ConcurrentSystemLocker.cpp | 4 ++-- 12 files changed, 34 insertions(+), 4 deletions(-) diff --git a/Source/Engine/Platform/Android/AndroidPlatform.cpp b/Source/Engine/Platform/Android/AndroidPlatform.cpp index 2f8e442ba..d78b716bf 100644 --- a/Source/Engine/Platform/Android/AndroidPlatform.cpp +++ b/Source/Engine/Platform/Android/AndroidPlatform.cpp @@ -748,6 +748,11 @@ void AndroidPlatform::Sleep(int32 milliseconds) usleep(milliseconds * 1000); } +void AndroidPlatform::Yield() +{ + pthread_yield(); +} + double AndroidPlatform::GetTimeSeconds() { struct timespec ts; diff --git a/Source/Engine/Platform/Android/AndroidPlatform.h b/Source/Engine/Platform/Android/AndroidPlatform.h index 4bae040cc..6153fa951 100644 --- a/Source/Engine/Platform/Android/AndroidPlatform.h +++ b/Source/Engine/Platform/Android/AndroidPlatform.h @@ -91,6 +91,7 @@ public: static void SetThreadPriority(ThreadPriority priority); static void SetThreadAffinityMask(uint64 affinityMask); static void Sleep(int32 milliseconds); + static void Yield(); static double GetTimeSeconds(); static uint64 GetTimeCycles(); FORCE_INLINE static uint64 GetClockFrequency() diff --git a/Source/Engine/Platform/Apple/ApplePlatform.cpp b/Source/Engine/Platform/Apple/ApplePlatform.cpp index c6c689195..8f8a0ba61 100644 --- a/Source/Engine/Platform/Apple/ApplePlatform.cpp +++ b/Source/Engine/Platform/Apple/ApplePlatform.cpp @@ -293,6 +293,11 @@ void ApplePlatform::Sleep(int32 milliseconds) usleep(milliseconds * 1000); } +void ApplePlatform::Yield() +{ + pthread_yield(); +} + double ApplePlatform::GetTimeSeconds() { return SecondsPerCycle * mach_absolute_time(); diff --git a/Source/Engine/Platform/Apple/ApplePlatform.h b/Source/Engine/Platform/Apple/ApplePlatform.h index 003cec91a..04af9757b 100644 --- a/Source/Engine/Platform/Apple/ApplePlatform.h +++ b/Source/Engine/Platform/Apple/ApplePlatform.h @@ -75,6 +75,7 @@ public: static void SetThreadPriority(ThreadPriority priority); static void SetThreadAffinityMask(uint64 affinityMask); static void Sleep(int32 milliseconds); + static void Yield(); static double GetTimeSeconds(); static uint64 GetTimeCycles(); static uint64 GetClockFrequency(); diff --git a/Source/Engine/Platform/Base/PlatformBase.h b/Source/Engine/Platform/Base/PlatformBase.h index 40245a3fc..44a0c8415 100644 --- a/Source/Engine/Platform/Base/PlatformBase.h +++ b/Source/Engine/Platform/Base/PlatformBase.h @@ -436,11 +436,16 @@ public: static void SetThreadAffinityMask(uint64 affinityMask) = delete; /// - /// Suspends the execution of the current thread until the time-out interval elapses + /// Suspends the execution of the current thread until the time-out interval elapses. /// /// The time interval for which execution is to be suspended, in milliseconds. static void Sleep(int32 milliseconds) = delete; + /// + /// Yields the execution of the current thread to another thread that is ready to run on the current processor. + /// + static void Yield() = delete; + public: /// /// Gets the current time in seconds. diff --git a/Source/Engine/Platform/Linux/LinuxPlatform.cpp b/Source/Engine/Platform/Linux/LinuxPlatform.cpp index 4b55f8bd5..ce05bf361 100644 --- a/Source/Engine/Platform/Linux/LinuxPlatform.cpp +++ b/Source/Engine/Platform/Linux/LinuxPlatform.cpp @@ -1836,6 +1836,11 @@ void LinuxPlatform::Sleep(int32 milliseconds) usleep(milliseconds * 1000); } +void LinuxPlatform::Yield() +{ + pthread_yield(); +} + double LinuxPlatform::GetTimeSeconds() { struct timespec ts; diff --git a/Source/Engine/Platform/Linux/LinuxPlatform.h b/Source/Engine/Platform/Linux/LinuxPlatform.h index 98d9d2976..071566f41 100644 --- a/Source/Engine/Platform/Linux/LinuxPlatform.h +++ b/Source/Engine/Platform/Linux/LinuxPlatform.h @@ -106,6 +106,7 @@ public: static void SetThreadPriority(ThreadPriority priority); static void SetThreadAffinityMask(uint64 affinityMask); static void Sleep(int32 milliseconds); + static void Yield(); static double GetTimeSeconds(); static uint64 GetTimeCycles(); FORCE_INLINE static uint64 GetClockFrequency() diff --git a/Source/Engine/Platform/Win32/IncludeWindowsHeaders.h b/Source/Engine/Platform/Win32/IncludeWindowsHeaders.h index 4d4290866..1e4e8ff0d 100644 --- a/Source/Engine/Platform/Win32/IncludeWindowsHeaders.h +++ b/Source/Engine/Platform/Win32/IncludeWindowsHeaders.h @@ -68,6 +68,7 @@ #undef CreateMutex #undef DrawState #undef LoadLibrary +#undef Yield #undef GetEnvironmentVariable #undef SetEnvironmentVariable diff --git a/Source/Engine/Platform/Win32/Win32Platform.cpp b/Source/Engine/Platform/Win32/Win32Platform.cpp index d32cb1249..5eab78205 100644 --- a/Source/Engine/Platform/Win32/Win32Platform.cpp +++ b/Source/Engine/Platform/Win32/Win32Platform.cpp @@ -400,6 +400,11 @@ void Win32Platform::Sleep(int32 milliseconds) WaitForSingleObject(timer, INFINITE); } +void Win32Platform::Yield() +{ + SwitchToThread(); +} + double Win32Platform::GetTimeSeconds() { LARGE_INTEGER counter; diff --git a/Source/Engine/Platform/Win32/Win32Platform.h b/Source/Engine/Platform/Win32/Win32Platform.h index 36d982bf7..ca404ae80 100644 --- a/Source/Engine/Platform/Win32/Win32Platform.h +++ b/Source/Engine/Platform/Win32/Win32Platform.h @@ -100,6 +100,7 @@ public: static void SetThreadPriority(ThreadPriority priority); static void SetThreadAffinityMask(uint64 affinityMask); static void Sleep(int32 milliseconds); + static void Yield(); static double GetTimeSeconds(); static uint64 GetTimeCycles(); static uint64 GetClockFrequency(); diff --git a/Source/Engine/Renderer/RenderListBuffer.h b/Source/Engine/Renderer/RenderListBuffer.h index bf1ea2cb0..90a05d7ac 100644 --- a/Source/Engine/Renderer/RenderListBuffer.h +++ b/Source/Engine/Renderer/RenderListBuffer.h @@ -324,7 +324,7 @@ private: // Wait for all threads to stop adding items before resizing can happen RETRY: while (Platform::AtomicRead(&_threadsAdding)) - Platform::Sleep(0); + Platform::Yield(); // Thread-safe resizing _locker.Lock(); diff --git a/Source/Engine/Threading/ConcurrentSystemLocker.cpp b/Source/Engine/Threading/ConcurrentSystemLocker.cpp index cafc3dadb..4b64a12ac 100644 --- a/Source/Engine/Threading/ConcurrentSystemLocker.cpp +++ b/Source/Engine/Threading/ConcurrentSystemLocker.cpp @@ -39,7 +39,7 @@ RETRY: { // Someone else is doing opposite operation so wait for it's end // TODO: use ConditionVariable+CriticalSection to prevent active-waiting - Platform::Sleep(0); + Platform::Yield(); goto RETRY; } @@ -47,7 +47,7 @@ RETRY: if (exclusively && Platform::AtomicRead(thisCounter) != 0) { // Someone else is doing opposite operation so wait for it's end - Platform::Sleep(0); + Platform::Yield(); goto RETRY; }