[util] Add platform-specific clock implementation

MinGW calls to GetSystemTimeAsFileTime via gettimeofday for std::chrono::high_resolution_clock::now,
This is horribly slow and inaccurate.

There are also issues if MinGW is not built with libstdc++ at the same time that can cause the precision to be bad enough to cause massive hangs.
This effectively works around that as well.

Relevant: ValveSoftware/Proton#3198
This commit is contained in:
Joshua Ashton 2019-11-26 00:45:45 +00:00
parent 25a1e0d355
commit 89dfa2bc22
1 changed files with 50 additions and 0 deletions

50
src/util/util_time.h Normal file
View File

@ -0,0 +1,50 @@
#pragma once
#include <chrono>
#include <cstdint>
#ifdef _WIN32
#include <windows.h>
#endif
namespace dxvk {
#ifdef _WIN32
struct high_resolution_clock {
static constexpr bool is_steady = true;
using rep = int64_t;
using period = std::nano;
using duration = std::chrono::nanoseconds;
using time_point = std::chrono::time_point<high_resolution_clock>;
static inline time_point now() noexcept {
// Keep the frequency static, this doesn't change at all.
static const int64_t freq = getFrequency();
const int64_t counter = getCounter();
const int64_t whole = (counter / freq) * period::den;
const int64_t part = (counter % freq) * period::den / freq;
return time_point(duration(whole + part));
}
static inline int64_t getFrequency() {
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
return freq.QuadPart;
}
static inline int64_t getCounter() {
LARGE_INTEGER count;
QueryPerformanceCounter(&count);
return count.QuadPart;
}
};
#else
using clock = std::chrono::high_resolution_clock;
#endif
}