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

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

Issue 1824673002: time: Add a static TimeTicks method that returns the underlying clock (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed Clock::UNKNOWN Created 4 years, 8 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
« no previous file with comments | « base/time/time_posix.cc ('k') | no next file » | 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 385 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 // this timer; and also other Windows applications can alter it, affecting this 396 // this timer; and also other Windows applications can alter it, affecting this
397 // one. 397 // one.
398 398
399 using NowFunction = TimeDelta (*)(void); 399 using NowFunction = TimeDelta (*)(void);
400 400
401 TimeDelta InitialNowFunction(); 401 TimeDelta InitialNowFunction();
402 402
403 // See "threading notes" in InitializeNowFunctionPointer() for details on how 403 // See "threading notes" in InitializeNowFunctionPointer() for details on how
404 // concurrent reads/writes to these globals has been made safe. 404 // concurrent reads/writes to these globals has been made safe.
405 NowFunction g_now_function = &InitialNowFunction; 405 NowFunction g_now_function = &InitialNowFunction;
406 TimeTicks::Clock g_now_clock = TimeTicks::WIN_ROLLOVER_PROTECTED_TIME_GET_TIME;
407
406 int64_t g_qpc_ticks_per_second = 0; 408 int64_t g_qpc_ticks_per_second = 0;
407 409
408 // As of January 2015, use of <atomic> is forbidden in Chromium code. This is 410 // As of January 2015, use of <atomic> is forbidden in Chromium code. This is
409 // what std::atomic_thread_fence does on Windows on all Intel architectures when 411 // what std::atomic_thread_fence does on Windows on all Intel architectures when
410 // the memory_order argument is anything but std::memory_order_seq_cst: 412 // the memory_order argument is anything but std::memory_order_seq_cst:
411 #define ATOMIC_THREAD_FENCE(memory_order) _ReadWriteBarrier(); 413 #define ATOMIC_THREAD_FENCE(memory_order) _ReadWriteBarrier();
412 414
413 TimeDelta QPCValueToTimeDelta(LONGLONG qpc_value) { 415 TimeDelta QPCValueToTimeDelta(LONGLONG qpc_value) {
414 // Ensure that the assignment to |g_qpc_ticks_per_second|, made in 416 // Ensure that the assignment to |g_qpc_ticks_per_second|, made in
415 // InitializeNowFunctionPointer(), has happened by this point. 417 // InitializeNowFunctionPointer(), has happened by this point.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
452 // 454 //
453 // If the QPC implementation is expensive and/or unreliable, TimeTicks::Now() 455 // If the QPC implementation is expensive and/or unreliable, TimeTicks::Now()
454 // will still use the low-resolution clock. A CPU lacking a non-stop time 456 // will still use the low-resolution clock. A CPU lacking a non-stop time
455 // counter will cause Windows to provide an alternate QPC implementation that 457 // counter will cause Windows to provide an alternate QPC implementation that
456 // works, but is expensive to use. Certain Athlon CPUs are known to make the 458 // works, but is expensive to use. Certain Athlon CPUs are known to make the
457 // QPC implementation unreliable. 459 // QPC implementation unreliable.
458 // 460 //
459 // Otherwise, Now uses the high-resolution QPC clock. As of 21 August 2015, 461 // Otherwise, Now uses the high-resolution QPC clock. As of 21 August 2015,
460 // ~72% of users fall within this category. 462 // ~72% of users fall within this category.
461 NowFunction now_function; 463 NowFunction now_function;
464 const char* now_clock;
462 base::CPU cpu; 465 base::CPU cpu;
463 if (ticks_per_sec.QuadPart <= 0 || 466 if (ticks_per_sec.QuadPart <= 0 ||
464 !cpu.has_non_stop_time_stamp_counter() || IsBuggyAthlon(cpu)) { 467 !cpu.has_non_stop_time_stamp_counter() || IsBuggyAthlon(cpu)) {
465 now_function = &RolloverProtectedNow; 468 now_function = &RolloverProtectedNow;
469 now_clock = Clock::WIN_ROLLOVER_PROTECTED_TIME_GET_TIME;
466 } else { 470 } else {
467 now_function = &QPCNow; 471 now_function = &QPCNow;
472 now_clock = Clock::WIN_QPC;
468 } 473 }
469 474
470 // Threading note 1: In an unlikely race condition, it's possible for two or 475 // Threading note 1: In an unlikely race condition, it's possible for two or
471 // more threads to enter InitializeNowFunctionPointer() in parallel. This is 476 // more threads to enter InitializeNowFunctionPointer() in parallel. This is
472 // not a problem since all threads should end up writing out the same values 477 // not a problem since all threads should end up writing out the same values
473 // to the global variables. 478 // to the global variables.
474 // 479 //
475 // Threading note 2: A release fence is placed here to ensure, from the 480 // Threading note 2: A release fence is placed here to ensure, from the
476 // perspective of other threads using the function pointers, that the 481 // perspective of other threads using the function pointers, that the
477 // assignment to |g_qpc_ticks_per_second| happens before the function pointers 482 // assignment to |g_qpc_ticks_per_second| happens before the function pointers
478 // are changed. 483 // are changed.
484 g_now_clock = now_clock;
479 g_qpc_ticks_per_second = ticks_per_sec.QuadPart; 485 g_qpc_ticks_per_second = ticks_per_sec.QuadPart;
480 ATOMIC_THREAD_FENCE(memory_order_release); 486 ATOMIC_THREAD_FENCE(memory_order_release);
481 g_now_function = now_function; 487 g_now_function = now_function;
482 } 488 }
483 489
484 TimeDelta InitialNowFunction() { 490 TimeDelta InitialNowFunction() {
485 InitializeNowFunctionPointer(); 491 InitializeNowFunctionPointer();
486 return g_now_function(); 492 return g_now_function();
487 } 493 }
488 494
(...skipping 16 matching lines...) Expand all
505 } 511 }
506 512
507 // static 513 // static
508 bool TimeTicks::IsHighResolution() { 514 bool TimeTicks::IsHighResolution() {
509 if (g_now_function == &InitialNowFunction) 515 if (g_now_function == &InitialNowFunction)
510 InitializeNowFunctionPointer(); 516 InitializeNowFunctionPointer();
511 return g_now_function == &QPCNow; 517 return g_now_function == &QPCNow;
512 } 518 }
513 519
514 // static 520 // static
521 TimeTicks::Clock TimeTicks::GetClock() {
fmeawad 2016/03/30 20:25:19 nit: I might be confused, but why not something li
danakj 2016/03/30 20:26:29 Oh, that's pretty nice yah.
charliea (OOO until 10-5) 2016/03/31 15:38:38 Agreed. That's a much nicer way of doing this. Don
522 if (g_now_function == &InitialNowFunction)
523 InitializeNowFunctionPointer();
524 return g_now_clock;
525 }
526
527 // static
515 ThreadTicks ThreadTicks::Now() { 528 ThreadTicks ThreadTicks::Now() {
516 DCHECK(IsSupported()); 529 DCHECK(IsSupported());
517 530
518 // Get the number of TSC ticks used by the current thread. 531 // Get the number of TSC ticks used by the current thread.
519 ULONG64 thread_cycle_time = 0; 532 ULONG64 thread_cycle_time = 0;
520 GetQueryThreadCycleTimeFunction()(::GetCurrentThread(), &thread_cycle_time); 533 GetQueryThreadCycleTimeFunction()(::GetCurrentThread(), &thread_cycle_time);
521 534
522 // Get the frequency of the TSC. 535 // Get the frequency of the TSC.
523 double tsc_ticks_per_second = TSCTicksPerSecond(); 536 double tsc_ticks_per_second = TSCTicksPerSecond();
524 if (tsc_ticks_per_second == 0) 537 if (tsc_ticks_per_second == 0)
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
607 TimeTicks TimeTicks::FromQPCValue(LONGLONG qpc_value) { 620 TimeTicks TimeTicks::FromQPCValue(LONGLONG qpc_value) {
608 return TimeTicks() + QPCValueToTimeDelta(qpc_value); 621 return TimeTicks() + QPCValueToTimeDelta(qpc_value);
609 } 622 }
610 623
611 // TimeDelta ------------------------------------------------------------------ 624 // TimeDelta ------------------------------------------------------------------
612 625
613 // static 626 // static
614 TimeDelta TimeDelta::FromQPCValue(LONGLONG qpc_value) { 627 TimeDelta TimeDelta::FromQPCValue(LONGLONG qpc_value) {
615 return QPCValueToTimeDelta(qpc_value); 628 return QPCValueToTimeDelta(qpc_value);
616 } 629 }
OLDNEW
« no previous file with comments | « base/time/time_posix.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698