Bug 784859 - Part 5: Change the implementation of GetTickCount64Fallback so that it never locks; r=bbondy

This commit is contained in:
Ehsan Akhgari 2012-09-06 11:01:06 -04:00
Родитель 742f5dc623
Коммит 2aed23cb92
1 изменённых файлов: 18 добавлений и 20 удалений

Просмотреть файл

@ -417,24 +417,22 @@ InitResolution()
static ULONGLONG WINAPI
GetTickCount64Fallback()
{
DWORD now = GetTickCount();
ULONGLONG lastResultHiPart = sLastGTCResult & (~0ULL << 32);
ULONGLONG result = lastResultHiPart | ULONGLONG(now);
ULONGLONG old, newValue;
do {
old = InterlockedRead64(&sLastGTCResult);
ULONGLONG oldTop = old & 0xffffffff00000000;
ULONG oldBottom = old & 0xffffffff;
ULONG newBottom = GetTickCount();
if (newBottom < oldBottom) {
// handle overflow
newValue = (oldTop + (1ULL<<32)) | newBottom;
} else {
newValue = oldTop | newBottom;
}
} while (old != _InterlockedCompareExchange64(reinterpret_cast<volatile __int64*> (&sLastGTCResult),
newValue, old));
// It may happen that when accessing GTC on multiple threads the results
// may differ (GTC value may be lower due to running before the others
// right around the overflow moment). That falsely shifts the high part.
// Easiest solution is to check for a significant difference.
if (sLastGTCResult > result) {
if ((sLastGTCResult - result) > (1ULL << 31))
result += 1ULL << 32;
else
result = sLastGTCResult;
}
sLastGTCResult = result;
return result;
return newValue;
}
// Result is in [mt]
@ -569,13 +567,13 @@ CalibratedPerformanceCounter()
ULONGLONG qpc = PerformanceCounter();
// Rollover protection
ULONGLONG gtc = sGetTickCount64();
ULONGLONG result;
{
AutoCriticalSection lock(&sTimeStampLock);
// Rollover protection
ULONGLONG gtc = sGetTickCount64();
LONGLONG diff = qpc - ms2mt(gtc) - sSkew;
LONGLONG overflow = 0;