Bug 1004923 part 8 - Add PRMJ_NowInit, call QueryPerformanceFrequency only once. r=njn

This commit is contained in:
Jan de Mooij 2014-05-05 10:33:29 +02:00
Родитель a12f43f05e
Коммит b47802f488
3 изменённых файлов: 45 добавлений и 40 удалений

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

@ -568,6 +568,8 @@ JS_Init(void)
MOZ_ASSERT(!JSRuntime::hasLiveRuntimes(), MOZ_ASSERT(!JSRuntime::hasLiveRuntimes(),
"how do we have live runtimes before JS_Init?"); "how do we have live runtimes before JS_Init?");
PRMJ_NowInit();
#ifdef DEBUG #ifdef DEBUG
CheckMessageNumbering(); CheckMessageNumbering();
CheckMessageParameterCounts(); CheckMessageParameterCounts();

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

@ -105,52 +105,52 @@ static CalibrationData calibration = { 0 };
static void static void
NowCalibrate() NowCalibrate()
{ {
if (calibration.freq == 0.0) { MOZ_ASSERT(calibration.freq > 0);
// According to the documentation, QueryPerformanceFrequency will never
// return false or return a non-zero frequency on systems that run
// Windows XP or later.
LARGE_INTEGER liFreq;
DebugOnly<BOOL> res = QueryPerformanceFrequency(&liFreq);
MOZ_ASSERT(res);
calibration.freq = double(liFreq.QuadPart);
MOZ_ASSERT(calibration.freq > 0.0);
}
if (calibration.freq > 0.0) {
// By wrapping a timeBegin/EndPeriod pair of calls around this loop,
// the loop seems to take much less time (1 ms vs 15ms) on Vista.
timeBeginPeriod(1);
FILETIME ft, ftStart;
GetSystemTimeAsFileTime(&ftStart);
do {
GetSystemTimeAsFileTime(&ft);
} while (memcmp(&ftStart,&ft, sizeof(ft)) == 0);
timeEndPeriod(1);
LARGE_INTEGER now; // By wrapping a timeBegin/EndPeriod pair of calls around this loop,
QueryPerformanceCounter(&now); // the loop seems to take much less time (1 ms vs 15ms) on Vista.
timeBeginPeriod(1);
FILETIME ft, ftStart;
GetSystemTimeAsFileTime(&ftStart);
do {
GetSystemTimeAsFileTime(&ft);
} while (memcmp(&ftStart,&ft, sizeof(ft)) == 0);
timeEndPeriod(1);
calibration.offset = FileTimeToUnixMicroseconds(ft); LARGE_INTEGER now;
calibration.timer_offset = double(now.QuadPart); QueryPerformanceCounter(&now);
calibration.calibrated = true; calibration.offset = FileTimeToUnixMicroseconds(ft);
} calibration.timer_offset = double(now.QuadPart);
calibration.calibrated = true;
} }
#define CALIBRATIONLOCK_SPINCOUNT 0 #define CALIBRATIONLOCK_SPINCOUNT 0
#define DATALOCK_SPINCOUNT 4096 #define DATALOCK_SPINCOUNT 4096
#define LASTLOCK_SPINCOUNT 4096 #define LASTLOCK_SPINCOUNT 4096
#ifdef JS_THREADSAFE void
static PRStatus PRMJ_NowInit()
NowInit(void)
{ {
memset(&calibration, 0, sizeof(calibration)); memset(&calibration, 0, sizeof(calibration));
NowCalibrate();
// According to the documentation, QueryPerformanceFrequency will never
// return false or return a non-zero frequency on systems that run
// Windows XP or later. Also, the frequency is fixed so we only have to
// query it once.
LARGE_INTEGER liFreq;
DebugOnly<BOOL> res = QueryPerformanceFrequency(&liFreq);
MOZ_ASSERT(res);
calibration.freq = double(liFreq.QuadPart);
MOZ_ASSERT(calibration.freq > 0.0);
#ifdef JS_THREADSAFE
InitializeCriticalSectionAndSpinCount(&calibration.calibration_lock, CALIBRATIONLOCK_SPINCOUNT); InitializeCriticalSectionAndSpinCount(&calibration.calibration_lock, CALIBRATIONLOCK_SPINCOUNT);
InitializeCriticalSectionAndSpinCount(&calibration.data_lock, DATALOCK_SPINCOUNT); InitializeCriticalSectionAndSpinCount(&calibration.data_lock, DATALOCK_SPINCOUNT);
return PR_SUCCESS; #endif
} }
#ifdef JS_THREADSAFE
void void
PRMJ_NowShutdown() PRMJ_NowShutdown()
{ {
@ -163,8 +163,6 @@ PRMJ_NowShutdown()
#define MUTEX_UNLOCK(m) LeaveCriticalSection(m) #define MUTEX_UNLOCK(m) LeaveCriticalSection(m)
#define MUTEX_SETSPINCOUNT(m, c) SetCriticalSectionSpinCount((m),(c)) #define MUTEX_SETSPINCOUNT(m, c) SetCriticalSectionSpinCount((m),(c))
static PRCallOnceType calibrationOnce = { 0 };
#else #else
#define MUTEX_LOCK(m) #define MUTEX_LOCK(m)
@ -201,11 +199,6 @@ PRMJ_Now()
bool calibrated = false; bool calibrated = false;
bool needsCalibration = false; bool needsCalibration = false;
double cachedOffset = 0.0; double cachedOffset = 0.0;
/* For non threadsafe platforms, NowInit is not necessary */
#ifdef JS_THREADSAFE
PR_CallOnce(&calibrationOnce, NowInit);
#endif
while (true) { while (true) {
if (!calibration.calibrated || needsCalibration) { if (!calibration.calibrated || needsCalibration) {
MUTEX_LOCK(&calibration.calibration_lock); MUTEX_LOCK(&calibration.calibration_lock);

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

@ -34,12 +34,22 @@ struct PRMJTime {
extern int64_t extern int64_t
PRMJ_Now(); PRMJ_Now();
/* Initialize the resources associated with PRMJ_Now. */
#if defined(XP_WIN)
extern void
PRMJ_NowInit();
#else
inline void
PRMJ_NowInit() {}
#endif
/* Release the resources associated with PRMJ_Now; don't call PRMJ_Now again */ /* Release the resources associated with PRMJ_Now; don't call PRMJ_Now again */
#if defined(JS_THREADSAFE) && defined(XP_WIN) #if defined(JS_THREADSAFE) && defined(XP_WIN)
extern void extern void
PRMJ_NowShutdown(void); PRMJ_NowShutdown();
#else #else
#define PRMJ_NowShutdown() inline void
PRMJ_NowShutdown() {}
#endif #endif
/* Format a time value into a buffer. Same semantics as strftime() */ /* Format a time value into a buffer. Same semantics as strftime() */