diff --git a/runtime/os_interface/windows/os_time.cpp b/runtime/os_interface/windows/os_time.cpp index 4b259bb367..1bbcf2773f 100644 --- a/runtime/os_interface/windows/os_time.cpp +++ b/runtime/os_interface/windows/os_time.cpp @@ -85,11 +85,9 @@ bool OSTimeWin::getCpuGpuTime(TimeStampData *pGpuCpuTime) { bool OSTimeWin::getCpuTime(uint64_t *timeStamp) { uint64_t time; - uint64_t frequency; - QueryPerformanceCounter((LARGE_INTEGER *)&time); - QueryPerformanceFrequency((LARGE_INTEGER *)&frequency); + this->QueryPerfomanceCounterFnc((LARGE_INTEGER *)&time); - *timeStamp = time * NSEC_PER_SEC / frequency; + *timeStamp = static_cast((static_cast(time) * NSEC_PER_SEC / frequency.QuadPart)); return true; }; @@ -126,7 +124,7 @@ double OSTimeWin::getDynamicDeviceTimerResolution(HardwareInfo const &hwInfo) co uint64_t OSTimeWin::getCpuRawTimestamp() { LARGE_INTEGER cpuRawTimestamp = {}; - QueryPerformanceCounter(&cpuRawTimestamp); + this->QueryPerfomanceCounterFnc(&cpuRawTimestamp); return cpuRawTimestamp.QuadPart; } } // namespace OCLRT diff --git a/runtime/os_interface/windows/os_time.h b/runtime/os_interface/windows/os_time.h index ddfff2c696..37e5b8d744 100644 --- a/runtime/os_interface/windows/os_time.h +++ b/runtime/os_interface/windows/os_time.h @@ -42,6 +42,7 @@ class OSTimeWin : public OSTime { Wddm *wddm; LARGE_INTEGER frequency; OSTimeWin() {} + decltype(&QueryPerformanceCounter) QueryPerfomanceCounterFnc = QueryPerformanceCounter; }; typedef enum GTDI_ESCAPE_FUNCTION_ENUM { diff --git a/unit_tests/os_interface/windows/mock_os_time_win.h b/unit_tests/os_interface/windows/mock_os_time_win.h index 97640c5e14..95f6a04b79 100644 --- a/unit_tests/os_interface/windows/mock_os_time_win.h +++ b/unit_tests/os_interface/windows/mock_os_time_win.h @@ -27,6 +27,11 @@ namespace OCLRT { class MockOSTimeWin : public OSTimeWin { public: MockOSTimeWin(OSInterface *osInterface) : OSTimeWin(osInterface){}; + + void overrideQueryPerformanceCounterFunction(decltype(&QueryPerformanceCounter) function) { + this->QueryPerfomanceCounterFnc = function; + } + void setFrequency(LARGE_INTEGER frequency) { this->frequency = frequency; } diff --git a/unit_tests/os_interface/windows/os_time_win_tests.cpp b/unit_tests/os_interface/windows/os_time_win_tests.cpp index 9f21684a29..a47c4629db 100644 --- a/unit_tests/os_interface/windows/os_time_win_tests.cpp +++ b/unit_tests/os_interface/windows/os_time_win_tests.cpp @@ -25,6 +25,15 @@ #include using namespace OCLRT; + +LARGE_INTEGER valueToSet = {0}; + +BOOL WINAPI QueryPerformanceCounterMock( + _Out_ LARGE_INTEGER *lpPerformanceCount) { + *lpPerformanceCount = valueToSet; + return true; +}; + struct OSTimeWinTest : public ::testing::Test { public: virtual void SetUp() override { @@ -56,3 +65,15 @@ TEST_F(OSTimeWinTest, givenOsTimeWinWhenGetCpuRawTimestampIsCalledThenReturnsNon auto retVal = osTime->getCpuRawTimestamp(); EXPECT_NE(0ull, retVal); } + +TEST_F(OSTimeWinTest, givenHighValueOfCpuTimestampWhenItIsObtainedThenItHasProperValue) { + osTime->overrideQueryPerformanceCounterFunction(QueryPerformanceCounterMock); + LARGE_INTEGER frequency = {0}; + frequency.QuadPart = 190457; + osTime->setFrequency(frequency); + valueToSet.QuadPart = 700894514854; + uint64_t timeStamp = 0; + uint64_t expectedTimestamp = static_cast((static_cast(valueToSet.QuadPart) * static_cast(NSEC_PER_SEC) / static_cast(frequency.QuadPart))); + osTime->getCpuTime(&timeStamp); + EXPECT_EQ(expectedTimestamp, timeStamp); +}