Changeset 36578 in webkit for trunk/JavaScriptCore/kjs/DateMath.cpp
- Timestamp:
- Sep 17, 2008, 4:54:31 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/JavaScriptCore/kjs/DateMath.cpp
r36263 r36578 288 288 } 289 289 290 double getCurrentUTCTimeWithMicroseconds()291 {292 290 #if PLATFORM(WIN_OS) 293 // FIXME: the implementation for Windows is only millisecond resolution. 294 #if COMPILER(BORLAND) 295 struct timeb timebuffer; 296 ftime(&timebuffer); 297 #else 291 292 static LARGE_INTEGER qpcFrequency; 293 static bool syncedTime; 294 295 static double highResUpTime() 296 { 297 // We use QPC, but only after sanity checking its result, due to bugs: 298 // http://support.microsoft.com/kb/274323 299 // http://support.microsoft.com/kb/895980 300 // 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)." 301 302 static LARGE_INTEGER qpcLast; 303 static DWORD tickCountLast; 304 static bool inited; 305 306 LARGE_INTEGER qpc; 307 QueryPerformanceCounter(&qpc); 308 DWORD tickCount = GetTickCount(); 309 310 if (inited) { 311 __int64 qpcElapsed = ((qpc.QuadPart - qpcLast.QuadPart) * 1000) / qpcFrequency.QuadPart; 312 __int64 tickCountElapsed; 313 if (tickCount >= tickCountLast) 314 tickCountElapsed = (tickCount - tickCountLast); 315 else { 316 __int64 tickCountLarge = tickCount + 0x100000000I64; 317 tickCountElapsed = tickCountLarge - tickCountLast; 318 } 319 320 // force a re-sync if QueryPerformanceCounter differs from GetTickCount by more than 500ms. 321 // (500ms value is from http://support.microsoft.com/kb/274323) 322 __int64 diff = tickCountElapsed - qpcElapsed; 323 if (diff > 500 || diff < -500) 324 syncedTime = false; 325 } else 326 inited = true; 327 328 qpcLast = qpc; 329 tickCountLast = tickCount; 330 331 return (1000.0 * qpc.QuadPart) / static_cast<double>(qpcFrequency.QuadPart);; 332 } 333 334 static double lowResUTCTime() 335 { 298 336 struct _timeb timebuffer; 299 337 _ftime(&timebuffer); 300 #endif 301 double utc = timebuffer.time * msPerSecond + timebuffer.millitm; 338 return timebuffer.time * msPerSecond + timebuffer.millitm; 339 } 340 341 static bool qpcAvailable() 342 { 343 static bool available; 344 static bool checked; 345 346 if (checked) 347 return available; 348 349 available = QueryPerformanceFrequency(&qpcFrequency); 350 checked = true; 351 return available; 352 } 353 354 #endif 355 356 double getCurrentUTCTimeWithMicroseconds() 357 { 358 #if PLATFORM(WIN_OS) 359 // Use a combination of ftime and QueryPerformanceCounter. 360 // ftime returns the information we want, but doesn't have sufficient resolution. 361 // QueryPerformanceCounter has high resolution, but is only usable to measure time intervals. 362 // To combine them, we call ftime and QueryPerformanceCounter initially. Later calls will use QueryPerformanceCounter 363 // by itself, adding the delta to the saved ftime. We periodically re-sync to correct for drift. 364 static bool started; 365 static double syncLowResUTCTime; 366 static double syncHighResUpTime; 367 static double lastUTCTime; 368 369 double lowResTime = lowResUTCTime(); 370 371 if (!qpcAvailable()) 372 return lowResTime; 373 374 double highResTime = highResUpTime(); 375 376 if (!syncedTime) { 377 timeBeginPeriod(1); // increase time resolution around low-res time getter 378 syncLowResUTCTime = lowResTime = lowResUTCTime(); 379 timeEndPeriod(1); // restore time resolution 380 syncHighResUpTime = highResTime; 381 syncedTime = true; 382 } 383 384 double highResElapsed = highResTime - syncHighResUpTime; 385 double utc = syncLowResUTCTime + highResElapsed; 386 387 // force a clock re-sync if we've drifted 388 double lowResElapsed = lowResTime - syncLowResUTCTime; 389 const double maximumAllowedDriftMsec = 15.625 * 2.0; // 2x the typical low-res accuracy 390 if (fabs(highResElapsed - lowResElapsed) > maximumAllowedDriftMsec) 391 syncedTime = false; 392 393 // make sure time doesn't run backwards (only correct if difference is < 2 seconds, since DST or clock changes could occur) 394 const double backwardTimeLimit = 2000.0; 395 if (utc < lastUTCTime && (lastUTCTime - utc) < backwardTimeLimit) 396 return lastUTCTime; 397 lastUTCTime = utc; 302 398 #else 303 399 struct timeval tv;
Note:
See TracChangeset
for help on using the changeset viewer.