diff --git a/include/EASTL/chrono.h b/include/EASTL/chrono.h index 4b94fe4a..7f062a91 100644 --- a/include/EASTL/chrono.h +++ b/include/EASTL/chrono.h @@ -26,7 +26,7 @@ // TODO: move to platform specific cpp or header file -#if defined EA_PLATFORM_MICROSOFT +#if defined(EA_PLATFORM_MICROSOFT) && !defined(EA_PLATFORM_WINDOWS_KERNEL) EA_DISABLE_ALL_VC_WARNINGS() #ifndef WIN32_LEAN_AND_MEAN @@ -48,7 +48,9 @@ EA_RESTORE_ALL_VC_WARNINGS() #endif -#if defined(EA_PLATFORM_MICROSOFT) && !defined(EA_PLATFORM_MINGW) +#if defined(EA_PLATFORM_WINDOWS_KERNEL) + #include +#elif defined(EA_PLATFORM_MICROSOFT) && !defined(EA_PLATFORM_MINGW) // Nothing to do #elif defined(EA_PLATFORM_APPLE) #include @@ -544,20 +546,26 @@ namespace chrono { #if defined(EA_PLATFORM_MICROSOFT) && !defined(EA_PLATFORM_MINGW) #define EASTL_NS_PER_TICK 1 - #elif defined EA_PLATFORM_SONY + #elif defined(EA_PLATFORM_SONY) #define EASTL_NS_PER_TICK 1 - #elif defined EA_PLATFORM_POSIX + #elif defined(EA_PLATFORM_POSIX) #define EASTL_NS_PER_TICK _XTIME_NSECS_PER_TICK #else #define EASTL_NS_PER_TICK 100 #endif + #if defined(EA_PLATFORM_WINDOWS_KERNEL) + #define EASTL_NS_PER_SYSTEM_TICK 100 + #else + #define EASTL_NS_PER_SYSTEM_TICK EASTL_NS_PER_TICK + #endif + #if defined(EA_PLATFORM_POSIX) typedef chrono::nanoseconds::period SystemClock_Period; typedef chrono::nanoseconds::period SteadyClock_Period; #else - typedef eastl::ratio_multiply, nano>::type SystemClock_Period; - typedef eastl::ratio_multiply, nano>::type SteadyClock_Period; + typedef eastl::ratio_multiply, nano>::type SystemClock_Period; + typedef eastl::ratio_multiply, nano>::type SteadyClock_Period; #endif @@ -566,18 +574,26 @@ namespace chrono /////////////////////////////////////////////////////////////////////////////// inline uint64_t GetTicks() { - #if defined EA_PLATFORM_MICROSOFT + #if defined(EA_PLATFORM_MICROSOFT) auto queryFrequency = [] { LARGE_INTEGER frequency; - QueryPerformanceFrequency(&frequency); + #if defined(EA_PLATFORM_WINDOWS_KERNEL) + KeQueryPerformanceCounter(&frequency); + #else + QueryPerformanceFrequency(&frequency); + #endif return double(1000000000.0L / (long double)frequency.QuadPart); // nanoseconds per tick }; auto queryCounter = [] { LARGE_INTEGER counter; - QueryPerformanceCounter(&counter); + #if defined(EA_PLATFORM_WINDOWS_KERNEL) + counter = KeQueryPerformanceCounter(nullptr); + #else + QueryPerformanceCounter(&counter); + #endif return counter.QuadPart; }; @@ -585,7 +601,7 @@ namespace chrono static auto frequency = queryFrequency(); // cache cpu frequency on first call EA_RESTORE_VC_WARNING() return uint64_t(frequency * (double)queryCounter()); - #elif defined EA_PLATFORM_SONY + #elif defined(EA_PLATFORM_SONY) static_assert(false, "Implementing GetTicks() requires first party support"); return 0; #elif defined(EA_PLATFORM_APPLE) @@ -621,6 +637,21 @@ namespace chrono #error "chrono not implemented for platform" #endif } + + inline uint64_t GetSystemTicks() + { + #if defined(EA_PLATFORM_WINDOWS_KERNEL) + LARGE_INTEGER systemTime; + #if (NTDDI_VERSION >= 0x06020000) // NTDDI_WIN8 + KeQuerySystemTimePrecise(&systemTime); + #else + KeQuerySystemTime(&systemTime); + #endif + return systemTime.QuadPart; + #else + return GetTicks(); + #endif + } } // namespace Internal @@ -641,7 +672,7 @@ namespace chrono // returns a time point representing the current point in time. static time_point now() EA_NOEXCEPT { - return time_point(duration(Internal::GetTicks())); + return time_point(duration(Internal::GetSystemTicks())); } }; @@ -671,7 +702,13 @@ namespace chrono /////////////////////////////////////////////////////////////////////////////// // high_resolution_clock /////////////////////////////////////////////////////////////////////////////// - typedef system_clock high_resolution_clock; + #if defined(EA_PLATFORM_WINDOWS_KERNEL) + // Kernel ticks are less expensive to query precisely compared to system time + // on Windows kernel + typedef steady_clock high_resolution_clock; + #else + typedef system_clock high_resolution_clock; + #endif } // namespace chrono