Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(136)

Side by Side Diff: trunk/src/base/time/time_win.cc

Issue 22984005: Revert 217172 "Enable high resolution time for TimeTicks::Now on..." (Closed) Base URL: svn://svn.chromium.org/chrome/
Patch Set: Created 7 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « trunk/src/base/time/time.h ('k') | trunk/src/chrome/browser/chrome_browser_main_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 5
6 // Windows Timer Primer 6 // Windows Timer Primer
7 // 7 //
8 // A good article: http://www.ddj.com/windows/184416651 8 // A good article: http://www.ddj.com/windows/184416651
9 // A good mozilla bug: http://bugzilla.mozilla.org/show_bug.cgi?id=363258 9 // A good mozilla bug: http://bugzilla.mozilla.org/show_bug.cgi?id=363258
10 // 10 //
(...skipping 304 matching lines...) Expand 10 before | Expand all | Expand 10 after
315 base::AutoLock locked(rollover_lock); 315 base::AutoLock locked(rollover_lock);
316 // We should hold the lock while calling tick_function to make sure that 316 // We should hold the lock while calling tick_function to make sure that
317 // we keep last_seen_now stay correctly in sync. 317 // we keep last_seen_now stay correctly in sync.
318 DWORD now = tick_function(); 318 DWORD now = tick_function();
319 if (now < last_seen_now) 319 if (now < last_seen_now)
320 rollover_ms += 0x100000000I64; // ~49.7 days. 320 rollover_ms += 0x100000000I64; // ~49.7 days.
321 last_seen_now = now; 321 last_seen_now = now;
322 return TimeDelta::FromMilliseconds(now + rollover_ms); 322 return TimeDelta::FromMilliseconds(now + rollover_ms);
323 } 323 }
324 324
325 bool IsBuggyAthlon(const base::CPU& cpu) {
326 // On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is
327 // unreliable. Fallback to low-res clock.
328 return cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15;
329 }
330
331 // Overview of time counters: 325 // Overview of time counters:
332 // (1) CPU cycle counter. (Retrieved via RDTSC) 326 // (1) CPU cycle counter. (Retrieved via RDTSC)
333 // The CPU counter provides the highest resolution time stamp and is the least 327 // The CPU counter provides the highest resolution time stamp and is the least
334 // expensive to retrieve. However, the CPU counter is unreliable and should not 328 // expensive to retrieve. However, the CPU counter is unreliable and should not
335 // be used in production. Its biggest issue is that it is per processor and it 329 // be used in production. Its biggest issue is that it is per processor and it
336 // is not synchronized between processors. Also, on some computers, the counters 330 // is not synchronized between processors. Also, on some computers, the counters
337 // will change frequency due to thermal and power changes, and stop in some 331 // will change frequency due to thermal and power changes, and stop in some
338 // states. 332 // states.
339 // 333 //
340 // (2) QueryPerformanceCounter (QPC). The QPC counter provides a high- 334 // (2) QueryPerformanceCounter (QPC). The QPC counter provides a high-
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
397 ticks_per_second_); 391 ticks_per_second_);
398 return microseconds; 392 return microseconds;
399 } 393 }
400 394
401 private: 395 private:
402 HighResNowSingleton() 396 HighResNowSingleton()
403 : ticks_per_second_(0), 397 : ticks_per_second_(0),
404 skew_(0) { 398 skew_(0) {
405 InitializeClock(); 399 InitializeClock();
406 400
401 // On Athlon X2 CPUs (e.g. model 15) QueryPerformanceCounter is
402 // unreliable. Fallback to low-res clock.
407 base::CPU cpu; 403 base::CPU cpu;
408 if (IsBuggyAthlon(cpu)) 404 if (cpu.vendor_name() == "AuthenticAMD" && cpu.family() == 15)
409 DisableHighResClock(); 405 DisableHighResClock();
410 } 406 }
411 407
412 // Synchronize the QPC clock with GetSystemTimeAsFileTime. 408 // Synchronize the QPC clock with GetSystemTimeAsFileTime.
413 void InitializeClock() { 409 void InitializeClock() {
414 LARGE_INTEGER ticks_per_sec = {0}; 410 LARGE_INTEGER ticks_per_sec = {0};
415 if (!QueryPerformanceFrequency(&ticks_per_sec)) 411 if (!QueryPerformanceFrequency(&ticks_per_sec))
416 return; // Broken, we don't guarantee this function works. 412 return; // Broken, we don't guarantee this function works.
417 ticks_per_second_ = ticks_per_sec.QuadPart; 413 ticks_per_second_ = ticks_per_sec.QuadPart;
418 414
(...skipping 11 matching lines...) Expand all
430 int64 ReliableNow() { 426 int64 ReliableNow() {
431 return RolloverProtectedNow().InMicroseconds(); 427 return RolloverProtectedNow().InMicroseconds();
432 } 428 }
433 429
434 int64 ticks_per_second_; // 0 indicates QPF failed and we're broken. 430 int64 ticks_per_second_; // 0 indicates QPF failed and we're broken.
435 int64 skew_; // Skew between lo-res and hi-res clocks (for debugging). 431 int64 skew_; // Skew between lo-res and hi-res clocks (for debugging).
436 432
437 friend struct DefaultSingletonTraits<HighResNowSingleton>; 433 friend struct DefaultSingletonTraits<HighResNowSingleton>;
438 }; 434 };
439 435
440 TimeDelta HighResNowWrapper() {
441 return HighResNowSingleton::GetInstance()->Now();
442 }
443
444 typedef TimeDelta (*NowFunction)(void);
445 NowFunction now_function = RolloverProtectedNow;
446
447 bool CPUReliablySupportsHighResTime() {
448 base::CPU cpu;
449 if (!cpu.has_non_stop_time_stamp_counter())
450 return false;
451
452 if (IsBuggyAthlon(cpu))
453 return false;
454
455 return true;
456 }
457
458 } // namespace 436 } // namespace
459 437
460 // static 438 // static
461 TimeTicks::TickFunctionType TimeTicks::SetMockTickFunction( 439 TimeTicks::TickFunctionType TimeTicks::SetMockTickFunction(
462 TickFunctionType ticker) { 440 TickFunctionType ticker) {
463 base::AutoLock locked(rollover_lock); 441 base::AutoLock locked(rollover_lock);
464 TickFunctionType old = tick_function; 442 TickFunctionType old = tick_function;
465 tick_function = ticker; 443 tick_function = ticker;
466 rollover_ms = 0; 444 rollover_ms = 0;
467 last_seen_now = 0; 445 last_seen_now = 0;
468 return old; 446 return old;
469 } 447 }
470 448
471 // static 449 // static
472 bool TimeTicks::SetNowIsHighResNowIfSupported() {
473 if (!CPUReliablySupportsHighResTime()) {
474 return false;
475 }
476
477 now_function = HighResNowWrapper;
478 return true;
479 }
480
481 // static
482 TimeTicks TimeTicks::Now() { 450 TimeTicks TimeTicks::Now() {
483 return TimeTicks() + now_function(); 451 return TimeTicks() + RolloverProtectedNow();
484 } 452 }
485 453
486 // static 454 // static
487 TimeTicks TimeTicks::HighResNow() { 455 TimeTicks TimeTicks::HighResNow() {
488 return TimeTicks() + HighResNowSingleton::GetInstance()->Now(); 456 return TimeTicks() + HighResNowSingleton::GetInstance()->Now();
489 } 457 }
490 458
491 // static 459 // static
492 TimeTicks TimeTicks::ThreadNow() { 460 TimeTicks TimeTicks::ThreadNow() {
493 NOTREACHED(); 461 NOTREACHED();
(...skipping 14 matching lines...) Expand all
508 TimeTicks TimeTicks::FromQPCValue(LONGLONG qpc_value) { 476 TimeTicks TimeTicks::FromQPCValue(LONGLONG qpc_value) {
509 return TimeTicks( 477 return TimeTicks(
510 HighResNowSingleton::GetInstance()->QPCValueToMicroseconds(qpc_value)); 478 HighResNowSingleton::GetInstance()->QPCValueToMicroseconds(qpc_value));
511 } 479 }
512 480
513 // static 481 // static
514 bool TimeTicks::IsHighResClockWorking() { 482 bool TimeTicks::IsHighResClockWorking() {
515 return HighResNowSingleton::GetInstance()->IsUsingHighResClock(); 483 return HighResNowSingleton::GetInstance()->IsUsingHighResClock();
516 } 484 }
517 485
518 TimeTicks TimeTicks::UnprotectedNow() {
519 if (now_function == HighResNowWrapper) {
520 return Now();
521 } else {
522 return TimeTicks() + TimeDelta::FromMilliseconds(timeGetTime());
523 }
524 }
525
526 // TimeDelta ------------------------------------------------------------------ 486 // TimeDelta ------------------------------------------------------------------
527 487
528 // static 488 // static
529 TimeDelta TimeDelta::FromQPCValue(LONGLONG qpc_value) { 489 TimeDelta TimeDelta::FromQPCValue(LONGLONG qpc_value) {
530 return TimeDelta( 490 return TimeDelta(
531 HighResNowSingleton::GetInstance()->QPCValueToMicroseconds(qpc_value)); 491 HighResNowSingleton::GetInstance()->QPCValueToMicroseconds(qpc_value));
532 } 492 }
OLDNEW
« no previous file with comments | « trunk/src/base/time/time.h ('k') | trunk/src/chrome/browser/chrome_browser_main_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698