Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add chrono.h implementation for Windows kernel #505

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 49 additions & 12 deletions include/EASTL/chrono.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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 <Wdm.h>
#elif defined(EA_PLATFORM_MICROSOFT) && !defined(EA_PLATFORM_MINGW)
// Nothing to do
#elif defined(EA_PLATFORM_APPLE)
#include <mach/mach_time.h>
Expand Down Expand Up @@ -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<eastl::ratio<EASTL_NS_PER_TICK, 1>, nano>::type SystemClock_Period;
typedef eastl::ratio_multiply<eastl::ratio<EASTL_NS_PER_TICK, 1>, nano>::type SteadyClock_Period;
typedef eastl::ratio_multiply<eastl::ratio<EASTL_NS_PER_SYSTEM_TICK, 1>, nano>::type SystemClock_Period;
typedef eastl::ratio_multiply<eastl::ratio<EASTL_NS_PER_TICK, 1>, nano>::type SteadyClock_Period;
#endif


Expand All @@ -566,26 +574,34 @@ 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;
};

EA_DISABLE_VC_WARNING(4640) // warning C4640: construction of local static object is not thread-safe (VS2013)
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)
Expand Down Expand Up @@ -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


Expand All @@ -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()));
}
};

Expand Down Expand Up @@ -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
Expand Down