diff options
author | Jan Vorlicek <janvorli@microsoft.com> | 2016-01-14 22:57:01 +0100 |
---|---|---|
committer | Jan Vorlicek <janvorli@microsoft.com> | 2016-01-14 22:57:01 +0100 |
commit | 3da3c24dce2c64193b9b9823c8e2a7fc80060189 (patch) | |
tree | 663687343affb4ed810ed9fa26721f901873abd1 /src | |
parent | c84ac790576e774bf7b72f28da8367ee35372c5a (diff) | |
download | coreclr-3da3c24dce2c64193b9b9823c8e2a7fc80060189.tar.gz coreclr-3da3c24dce2c64193b9b9823c8e2a7fc80060189.tar.bz2 coreclr-3da3c24dce2c64193b9b9823c8e2a7fc80060189.zip |
Make time measurement in PAL threading tests more precise
This change replaces GetTickCount by measurement using QueryPerformanceCounter.
This is an attempt to fix stability of bunch of threading tests that were
failing randomly due to large error margin of the GetTickCount on Debian.
Diffstat (limited to 'src')
9 files changed, 100 insertions, 112 deletions
diff --git a/src/pal/tests/palsuite/common/palsuite.h b/src/pal/tests/palsuite/common/palsuite.h index 4156f10190..498cf6f001 100644 --- a/src/pal/tests/palsuite/common/palsuite.h +++ b/src/pal/tests/palsuite/common/palsuite.h @@ -165,6 +165,17 @@ char* convertC(WCHAR * wString) return MultiBuffer; } +UINT64 GetHighPrecisionTimeStamp(LARGE_INTEGER performanceFrequency) +{ + LARGE_INTEGER ts; + if (!QueryPerformanceCounter(&ts)) + { + Fail("ERROR: Unable to query performance counter!\n"); + } + + return ts.QuadPart / (performanceFrequency.QuadPart / 1000); +} + #endif diff --git a/src/pal/tests/palsuite/threading/Sleep/test1/Sleep.c b/src/pal/tests/palsuite/threading/Sleep/test1/Sleep.c index 26c374eb89..2520c60244 100644 --- a/src/pal/tests/palsuite/threading/Sleep/test1/Sleep.c +++ b/src/pal/tests/palsuite/threading/Sleep/test1/Sleep.c @@ -34,8 +34,8 @@ DWORD AcceptableTimeError = 150; int __cdecl main( int argc, char **argv ) { - DWORD OldTickCount; - DWORD NewTickCount; + UINT64 OldTimeStamp; + UINT64 NewTimeStamp; DWORD MaxDelta; DWORD TimeDelta; DWORD i; @@ -45,21 +45,19 @@ int __cdecl main( int argc, char **argv ) return ( FAIL ); } + LARGE_INTEGER performanceFrequency; + if (!QueryPerformanceFrequency(&performanceFrequency)) + { + return FAIL; + } + for( i = 0; i < sizeof(SleepTimes) / sizeof(DWORD); i++) { - OldTickCount = GetTickCount(); + OldTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); Sleep(SleepTimes[i]); - NewTickCount = GetTickCount(); + NewTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); - /* - * Check for DWORD wraparound - */ - if (OldTickCount>NewTickCount) - { - OldTickCount -= NewTickCount+1; - NewTickCount = 0xFFFFFFFF; - } - TimeDelta = NewTickCount-OldTickCount; + TimeDelta = NewTimeStamp - OldTimeStamp; /* For longer intervals use a 10 percent tolerance */ if ((SleepTimes[i] * 0.1) > AcceptableTimeError) diff --git a/src/pal/tests/palsuite/threading/Sleep/test2/sleep.c b/src/pal/tests/palsuite/threading/Sleep/test2/sleep.c index 8d6c19a791..ee9969ce64 100644 --- a/src/pal/tests/palsuite/threading/Sleep/test2/sleep.c +++ b/src/pal/tests/palsuite/threading/Sleep/test2/sleep.c @@ -35,8 +35,8 @@ DWORD AcceptableTimeError = 150; int __cdecl main( int argc, char **argv ) { - DWORD OldTickCount; - DWORD NewTickCount; + UINT64 OldTimeStamp; + UINT64 NewTimeStamp; DWORD MaxDelta; DWORD TimeDelta; DWORD i; @@ -46,21 +46,19 @@ int __cdecl main( int argc, char **argv ) return ( FAIL ); } + LARGE_INTEGER performanceFrequency; + if (!QueryPerformanceFrequency(&performanceFrequency)) + { + return FAIL; + } + for( i = 0; i < sizeof(SleepTimes) / sizeof(DWORD); i++) { - OldTickCount = GetTickCount(); + OldTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); Sleep(SleepTimes[i]); - NewTickCount = GetTickCount(); + NewTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); - /* - * Check for DWORD wraparound - */ - if (OldTickCount>NewTickCount) - { - OldTickCount -= NewTickCount+1; - NewTickCount = 0xFFFFFFFF; - } - TimeDelta = NewTickCount-OldTickCount; + TimeDelta = NewTimeStamp - OldTimeStamp; MaxDelta = SleepTimes[i] + AcceptableTimeError; diff --git a/src/pal/tests/palsuite/threading/SleepEx/test1/test1.c b/src/pal/tests/palsuite/threading/SleepEx/test1/test1.c index 2aee9c0750..b32da78e01 100644 --- a/src/pal/tests/palsuite/threading/SleepEx/test1/test1.c +++ b/src/pal/tests/palsuite/threading/SleepEx/test1/test1.c @@ -41,8 +41,8 @@ DWORD AcceptableTimeError = 150; int __cdecl main( int argc, char **argv ) { - DWORD OldTickCount; - DWORD NewTickCount; + UINT64 OldTimeStamp; + UINT64 NewTimeStamp; DWORD MaxDelta; DWORD TimeDelta; DWORD i; @@ -52,24 +52,21 @@ int __cdecl main( int argc, char **argv ) return FAIL; } + LARGE_INTEGER performanceFrequency; + if (!QueryPerformanceFrequency(&performanceFrequency)) + { + return FAIL; + } + for (i = 0; i<sizeof(testCases) / sizeof(testCases[0]); i++) { - OldTickCount = GetTickCount(); + OldTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); SleepEx(testCases[i].SleepTime, testCases[i].Alertable); - NewTickCount = GetTickCount(); - - /* - * Check for DWORD wraparound - */ - if (OldTickCount>NewTickCount) - { - OldTickCount -= NewTickCount+1; - NewTickCount = 0xFFFFFFFF; - } + NewTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); - TimeDelta = NewTickCount - OldTickCount; + TimeDelta = NewTimeStamp - OldTimeStamp; /* For longer intervals use a 10 percent tolerance */ if ((testCases[i].SleepTime * 0.1) > AcceptableTimeError) diff --git a/src/pal/tests/palsuite/threading/SleepEx/test2/test2.c b/src/pal/tests/palsuite/threading/SleepEx/test2/test2.c index 9bfcebf245..52cf9295da 100644 --- a/src/pal/tests/palsuite/threading/SleepEx/test2/test2.c +++ b/src/pal/tests/palsuite/threading/SleepEx/test2/test2.c @@ -148,19 +148,24 @@ VOID PALAPI APCFunc(ULONG_PTR dwParam) /* Entry Point for child thread. */ DWORD PALAPI SleeperProc(LPVOID lpParameter) { - DWORD OldTickCount; - DWORD NewTickCount; + UINT64 OldTimeStamp; + UINT64 NewTimeStamp; BOOL Alertable; DWORD ret; Alertable = (BOOL) lpParameter; - OldTickCount = GetTickCount(); + LARGE_INTEGER performanceFrequency; + if (!QueryPerformanceFrequency(&performanceFrequency)) + { + return FAIL; + } + + OldTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); ret = SleepEx(ChildThreadSleepTime, Alertable); - NewTickCount = GetTickCount(); - + NewTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); if (Alertable && ret != WAIT_IO_COMPLETION) { @@ -173,16 +178,7 @@ DWORD PALAPI SleeperProc(LPVOID lpParameter) } - /* - * Check for DWORD wraparound - */ - if (OldTickCount>NewTickCount) - { - OldTickCount -= NewTickCount+1; - NewTickCount = 0xFFFFFFFF; - } - - ThreadSleepDelta = NewTickCount - OldTickCount; + ThreadSleepDelta = NewTimeStamp - OldTimeStamp; return 0; } diff --git a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/test2.c b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/test2.c index ee40fed95c..7643a076ca 100644 --- a/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/test2.c +++ b/src/pal/tests/palsuite/threading/WaitForMultipleObjectsEx/test2/test2.c @@ -133,8 +133,8 @@ VOID PALAPI APCFunc(ULONG_PTR dwParam) DWORD PALAPI WaiterProc(LPVOID lpParameter) { HANDLE Semaphore; - DWORD OldTickCount; - DWORD NewTickCount; + UINT64 OldTimeStamp; + UINT64 NewTimeStamp; BOOL Alertable; DWORD ret; @@ -149,12 +149,18 @@ DWORD PALAPI WaiterProc(LPVOID lpParameter) Alertable = (BOOL) lpParameter; - OldTickCount = GetTickCount(); + LARGE_INTEGER performanceFrequency; + if (!QueryPerformanceFrequency(&performanceFrequency)) + { + Fail("Failed to query performance frequency!"); + } + + OldTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); ret = WaitForMultipleObjectsEx(1, &Semaphore, FALSE, ChildThreadWaitTime, Alertable); - NewTickCount = GetTickCount(); + NewTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); if (Alertable && ret != WAIT_IO_COMPLETION) @@ -168,17 +174,7 @@ DWORD PALAPI WaiterProc(LPVOID lpParameter) "Expected return of WAIT_TIMEOUT, got %d.\n", ret); } - - /* - * Check for DWORD wraparound - */ - if (OldTickCount>NewTickCount) - { - OldTickCount -= NewTickCount+1; - NewTickCount = 0xFFFFFFFF; - } - - ThreadWaitDelta = NewTickCount - OldTickCount; + ThreadWaitDelta = NewTimeStamp - OldTimeStamp; ret = CloseHandle(Semaphore); if (!ret) diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/WFSOExMutexTest.c b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/WFSOExMutexTest.c index 303f9033e6..2fec029d4e 100644 --- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/WFSOExMutexTest.c +++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExMutexTest/WFSOExMutexTest.c @@ -174,20 +174,26 @@ VOID PALAPI APCFunc(ULONG_PTR dwParam) /* Entry Point for child thread. */ DWORD PALAPI WaiterProc(LPVOID lpParameter) { - DWORD OldTickCount; - DWORD NewTickCount; + UINT64 OldTimeStamp; + UINT64 NewTimeStamp; BOOL Alertable; DWORD ret; Alertable = (BOOL) lpParameter; - OldTickCount = GetTickCount(); + LARGE_INTEGER performanceFrequency; + if (!QueryPerformanceFrequency(&performanceFrequency)) + { + Fail("Failed to query performance frequency!"); + } + + OldTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); ret = WaitForSingleObjectEx( hMutex, ChildThreadWaitTime, Alertable); - NewTickCount = GetTickCount(); + NewTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); if (Alertable && ret != WAIT_IO_COMPLETION) { @@ -200,15 +206,7 @@ DWORD PALAPI WaiterProc(LPVOID lpParameter) "Expected return of WAIT_TIMEOUT, got %d.\n", ret); } - /* - * Check for DWORD wraparound - */ - if (OldTickCount>NewTickCount) - { - OldTickCount -= NewTickCount+1; - NewTickCount = 0xFFFFFFFF; - } - ThreadWaitDelta = NewTickCount - OldTickCount; + ThreadWaitDelta = NewTimeStamp - OldTimeStamp; return 0; } diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/WFSOExSemaphoreTest.c b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/WFSOExSemaphoreTest.c index 5538883b98..02c835ef0b 100644 --- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/WFSOExSemaphoreTest.c +++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExSemaphoreTest/WFSOExSemaphoreTest.c @@ -126,11 +126,17 @@ VOID PALAPI APCFunc(ULONG_PTR dwParam) DWORD PALAPI WaiterProc(LPVOID lpParameter) { HANDLE hSemaphore; - DWORD OldTickCount; - DWORD NewTickCount; + UINT64 OldTimeStamp; + UINT64 NewTimeStamp; BOOL Alertable; DWORD ret; + LARGE_INTEGER performanceFrequency; + if (!QueryPerformanceFrequency(&performanceFrequency)) + { + Fail("Failed to query performance frequency!"); + } + /* Create a semaphore that is not in the signalled state */ hSemaphore = CreateSemaphoreW(NULL, 0, 1, NULL); @@ -142,13 +148,13 @@ DWORD PALAPI WaiterProc(LPVOID lpParameter) Alertable = (BOOL) lpParameter; - OldTickCount = GetTickCount(); + OldTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); ret = WaitForSingleObjectEx( hSemaphore, ChildThreadWaitTime, Alertable); - NewTickCount = GetTickCount(); + NewTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); if (Alertable && ret != WAIT_IO_COMPLETION) @@ -163,16 +169,7 @@ DWORD PALAPI WaiterProc(LPVOID lpParameter) } - /* - * Check for DWORD wraparound - */ - if (OldTickCount>NewTickCount) - { - OldTickCount -= NewTickCount+1; - NewTickCount = 0xFFFFFFFF; - } - - ThreadWaitDelta = NewTickCount - OldTickCount; + ThreadWaitDelta = NewTimeStamp - OldTimeStamp; ret = CloseHandle(hSemaphore); if (!ret) diff --git a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/WFSOExThreadTest.c b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/WFSOExThreadTest.c index fd9e8f0874..e80c9745e2 100644 --- a/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/WFSOExThreadTest.c +++ b/src/pal/tests/palsuite/threading/WaitForSingleObject/WFSOExThreadTest/WFSOExThreadTest.c @@ -129,8 +129,8 @@ VOID PALAPI APCFunc(ULONG_PTR dwParam) DWORD PALAPI WaiterProc(LPVOID lpParameter) { HANDLE hWaitThread; - DWORD OldTickCount; - DWORD NewTickCount; + UINT64 OldTimeStamp; + UINT64 NewTimeStamp; BOOL Alertable; DWORD ret; DWORD dwThreadId = 0; @@ -154,15 +154,21 @@ satisfying any threads that were waiting on the object. "GetLastError returned %d\n", GetLastError()); } - Alertable = (BOOL) lpParameter; + Alertable = (BOOL) lpParameter; - OldTickCount = GetTickCount(); + LARGE_INTEGER performanceFrequency; + if (!QueryPerformanceFrequency(&performanceFrequency)) + { + Fail("Failed to query performance frequency!"); + } + + OldTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); ret = WaitForSingleObjectEx( hWaitThread, ChildThreadWaitTime, Alertable); - NewTickCount = GetTickCount(); + NewTimeStamp = GetHighPrecisionTimeStamp(performanceFrequency); if (Alertable && ret != WAIT_IO_COMPLETION) @@ -176,16 +182,7 @@ satisfying any threads that were waiting on the object. "Expected return of WAIT_TIMEOUT, got %d.\n", ret); } - /* - * Check for DWORD wraparound - */ - if (OldTickCount>NewTickCount) - { - OldTickCount -= NewTickCount+1; - NewTickCount = 0xFFFFFFFF; - } - - ThreadWaitDelta = (int)(NewTickCount - OldTickCount); + ThreadWaitDelta = NewTimeStamp - OldTimeStamp; ret = CloseHandle(hWaitThread); if (!ret) |