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.
This commit is contained in:
Mario Liebisch 2015-11-19 14:32:07 +01:00
parent b3e44568df
commit da3632b005

View File

@ -26,17 +26,27 @@
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include <SFML/System/Win32/ClockImpl.hpp> #include <SFML/System/Win32/ClockImpl.hpp>
#include <SFML/System/Mutex.hpp>
#include <SFML/System/Lock.hpp>
#include <windows.h> #include <windows.h>
namespace namespace
{ {
sf::Mutex oldWindowsMutex;
LARGE_INTEGER getFrequency() LARGE_INTEGER getFrequency()
{ {
LARGE_INTEGER frequency; LARGE_INTEGER frequency;
QueryPerformanceFrequency(&frequency); QueryPerformanceFrequency(&frequency);
return frequency; return frequency;
} }
bool isWindowsXpOrOlder()
{
// Windows XP was the last 5.x version of Windows
return static_cast<DWORD>(LOBYTE(LOWORD(GetVersion()))) < 6;
}
} }
namespace sf namespace sf
@ -46,21 +56,28 @@ namespace priv
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
Time ClockImpl::getCurrentTime() 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 // Get the frequency of the performance counter
// (it is constant across the program lifetime) // (it is constant across the program lifetime)
static LARGE_INTEGER frequency = getFrequency(); static LARGE_INTEGER frequency = getFrequency();
// Get the current time // Detect if we are on Windows XP or older
LARGE_INTEGER time; static bool oldWindows = isWindowsXpOrOlder();
QueryPerformanceCounter(&time);
// Restore the thread affinity LARGE_INTEGER time;
SetThreadAffinityMask(currentThread, previousMask);
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 the current time as microseconds
return sf::microseconds(1000000 * time.QuadPart / frequency.QuadPart); return sf::microseconds(1000000 * time.QuadPart / frequency.QuadPart);