From da3632b005c42541013f8a63bf08cb1eb07ed25f Mon Sep 17 00:00:00 2001 From: Mario Liebisch Date: Thu, 19 Nov 2015 14:32:07 +0100 Subject: [PATCH] Windows: Removed thread affinity changes in sf::Clock * This should prevent timing issues on Windows XP and earlier with broken BIOS while avoiding unnecessary threading changes. --- src/SFML/System/Win32/ClockImpl.cpp | 37 +++++++++++++++++++++-------- 1 file changed, 27 insertions(+), 10 deletions(-) diff --git a/src/SFML/System/Win32/ClockImpl.cpp b/src/SFML/System/Win32/ClockImpl.cpp index 67b19f929..5f6fdef3b 100644 --- a/src/SFML/System/Win32/ClockImpl.cpp +++ b/src/SFML/System/Win32/ClockImpl.cpp @@ -26,17 +26,27 @@ // Headers //////////////////////////////////////////////////////////// #include +#include +#include #include namespace { + sf::Mutex oldWindowsMutex; + LARGE_INTEGER getFrequency() { LARGE_INTEGER frequency; QueryPerformanceFrequency(&frequency); return frequency; } + + bool isWindowsXpOrOlder() + { + // Windows XP was the last 5.x version of Windows + return static_cast(LOBYTE(LOWORD(GetVersion()))) < 6; + } } namespace sf @@ -46,21 +56,28 @@ namespace priv //////////////////////////////////////////////////////////// Time ClockImpl::getCurrentTime() { - // Force the following code to run on first core - // (see http://msdn.microsoft.com/en-us/library/windows/desktop/ms644904(v=vs.85).aspx) - HANDLE currentThread = GetCurrentThread(); - DWORD_PTR previousMask = SetThreadAffinityMask(currentThread, 1); - // Get the frequency of the performance counter // (it is constant across the program lifetime) static LARGE_INTEGER frequency = getFrequency(); - // Get the current time - LARGE_INTEGER time; - QueryPerformanceCounter(&time); + // Detect if we are on Windows XP or older + static bool oldWindows = isWindowsXpOrOlder(); - // Restore the thread affinity - SetThreadAffinityMask(currentThread, previousMask); + LARGE_INTEGER time; + + if (oldWindows) + { + // Acquire a lock (CRITICAL_SECTION) to prevent travelling back in time + Lock lock(oldWindowsMutex); + + // Get the current time + QueryPerformanceCounter(&time); + } + else + { + // Get the current time + QueryPerformanceCounter(&time); + } // Return the current time as microseconds return sf::microseconds(1000000 * time.QuadPart / frequency.QuadPart);