Changeset 39784 in webkit for trunk/JavaScriptCore/runtime
- Timestamp:
- Jan 11, 2009, 12:14:58 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/runtime/DateMath.cpp
r38831 r39784 49 49 #include <wtf/ASCIICType.h> 50 50 #include <wtf/Assertions.h> 51 #include <wtf/CurrentTime.h> 51 52 #include <wtf/MathExtras.h> 52 53 #include <wtf/StringExtras.h> … … 292 293 } 293 294 294 #if PLATFORM(WIN_OS) 295 296 static LARGE_INTEGER qpcFrequency; 297 static bool syncedTime; 298 299 static double highResUpTime() 300 { 301 // We use QPC, but only after sanity checking its result, due to bugs: 302 // http://support.microsoft.com/kb/274323 303 // http://support.microsoft.com/kb/895980 304 // http://msdn.microsoft.com/en-us/library/ms644904.aspx ("...you can get different results on different processors due to bugs in the basic input/output system (BIOS) or the hardware abstraction layer (HAL)." 305 306 static LARGE_INTEGER qpcLast; 307 static DWORD tickCountLast; 308 static bool inited; 309 310 LARGE_INTEGER qpc; 311 QueryPerformanceCounter(&qpc); 312 DWORD tickCount = GetTickCount(); 313 314 if (inited) { 315 __int64 qpcElapsed = ((qpc.QuadPart - qpcLast.QuadPart) * 1000) / qpcFrequency.QuadPart; 316 __int64 tickCountElapsed; 317 if (tickCount >= tickCountLast) 318 tickCountElapsed = (tickCount - tickCountLast); 319 else { 320 #if COMPILER(MINGW) 321 __int64 tickCountLarge = tickCount + 0x100000000ULL; 322 #else 323 __int64 tickCountLarge = tickCount + 0x100000000I64; 324 #endif 325 tickCountElapsed = tickCountLarge - tickCountLast; 326 } 327 328 // force a re-sync if QueryPerformanceCounter differs from GetTickCount by more than 500ms. 329 // (500ms value is from http://support.microsoft.com/kb/274323) 330 __int64 diff = tickCountElapsed - qpcElapsed; 331 if (diff > 500 || diff < -500) 332 syncedTime = false; 333 } else 334 inited = true; 335 336 qpcLast = qpc; 337 tickCountLast = tickCount; 338 339 return (1000.0 * qpc.QuadPart) / static_cast<double>(qpcFrequency.QuadPart);; 340 } 341 342 static double lowResUTCTime() 343 { 344 #if PLATFORM(WIN_CE) 345 SYSTEMTIME systemTime; 346 GetSystemTime(&systemTime); 347 struct tm tmtime; 348 tmtime.tm_year = systemTime.wYear - 1900; 349 tmtime.tm_mon = systemTime.wMonth - 1; 350 tmtime.tm_mday = systemTime.wDay; 351 tmtime.tm_wday = systemTime.wDayOfWeek; 352 tmtime.tm_hour = systemTime.wHour; 353 tmtime.tm_min = systemTime.wMinute; 354 tmtime.tm_sec = systemTime.wSecond; 355 time_t timet = mktime(&tmtime); 356 return timet * msPerSecond + systemTime.wMilliseconds; 357 #else 358 struct _timeb timebuffer; 359 _ftime(&timebuffer); 360 return timebuffer.time * msPerSecond + timebuffer.millitm; 361 #endif 362 } 363 364 static bool qpcAvailable() 365 { 366 static bool available; 367 static bool checked; 368 369 if (checked) 370 return available; 371 372 available = QueryPerformanceFrequency(&qpcFrequency); 373 checked = true; 374 return available; 375 } 376 377 #endif 378 295 // Returns current time in milliseconds since 1 Jan 1970. 379 296 double getCurrentUTCTimeWithMicroseconds() 380 297 { 381 #if PLATFORM(WIN_OS) 382 // Use a combination of ftime and QueryPerformanceCounter. 383 // ftime returns the information we want, but doesn't have sufficient resolution. 384 // QueryPerformanceCounter has high resolution, but is only usable to measure time intervals. 385 // To combine them, we call ftime and QueryPerformanceCounter initially. Later calls will use QueryPerformanceCounter 386 // by itself, adding the delta to the saved ftime. We periodically re-sync to correct for drift. 387 static bool started; 388 static double syncLowResUTCTime; 389 static double syncHighResUpTime; 390 static double lastUTCTime; 391 392 double lowResTime = lowResUTCTime(); 393 394 if (!qpcAvailable()) 395 return lowResTime; 396 397 double highResTime = highResUpTime(); 398 399 if (!syncedTime) { 400 timeBeginPeriod(1); // increase time resolution around low-res time getter 401 syncLowResUTCTime = lowResTime = lowResUTCTime(); 402 timeEndPeriod(1); // restore time resolution 403 syncHighResUpTime = highResTime; 404 syncedTime = true; 405 } 406 407 double highResElapsed = highResTime - syncHighResUpTime; 408 double utc = syncLowResUTCTime + highResElapsed; 409 410 // force a clock re-sync if we've drifted 411 double lowResElapsed = lowResTime - syncLowResUTCTime; 412 const double maximumAllowedDriftMsec = 15.625 * 2.0; // 2x the typical low-res accuracy 413 if (fabs(highResElapsed - lowResElapsed) > maximumAllowedDriftMsec) 414 syncedTime = false; 415 416 // make sure time doesn't run backwards (only correct if difference is < 2 seconds, since DST or clock changes could occur) 417 const double backwardTimeLimit = 2000.0; 418 if (utc < lastUTCTime && (lastUTCTime - utc) < backwardTimeLimit) 419 return lastUTCTime; 420 lastUTCTime = utc; 421 #else 422 struct timeval tv; 423 gettimeofday(&tv, 0); 424 double utc = tv.tv_sec * msPerSecond + tv.tv_usec / 1000.0; 425 #endif 426 return utc; 298 return currentTime() * 1000.0; 427 299 } 428 300
Note:
See TracChangeset
for help on using the changeset viewer.