hi_res_timer_manager_win.cc 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Copyright (c) 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "base/timer/hi_res_timer_manager.h"
  5. #include <algorithm>
  6. #include "base/atomicops.h"
  7. #include "base/base_switches.h"
  8. #include "base/command_line.h"
  9. #include "base/metrics/histogram_macros.h"
  10. #include "base/power_monitor/power_monitor.h"
  11. #include "base/time/time.h"
  12. namespace base {
  13. namespace {
  14. constexpr TimeDelta kUsageSampleInterval = Minutes(10);
  15. void ReportHighResolutionTimerUsage() {
  16. UMA_HISTOGRAM_PERCENTAGE("Windows.HighResolutionTimerUsage",
  17. Time::GetHighResolutionTimerUsage());
  18. // Reset usage for the next interval.
  19. Time::ResetHighResolutionTimerUsage();
  20. }
  21. bool HighResolutionTimerAllowed() {
  22. return !CommandLine::ForCurrentProcess()->HasSwitch(
  23. switches::kDisableHighResTimer);
  24. }
  25. } // namespace
  26. HighResolutionTimerManager::HighResolutionTimerManager()
  27. : hi_res_clock_available_(false) {
  28. // Register for PowerMonitor callbacks only if high-resolution
  29. // timers are allowed. If high-resolution timers are disabled
  30. // we won't receive power state change callbacks and
  31. // hi_res_clock_available_ will remain at its initial value.
  32. if (HighResolutionTimerAllowed()) {
  33. DCHECK(PowerMonitor::IsInitialized());
  34. PowerMonitor::AddPowerSuspendObserver(this);
  35. const bool on_battery =
  36. PowerMonitor::AddPowerStateObserverAndReturnOnBatteryState(this);
  37. UseHiResClock(!on_battery);
  38. // Start polling the high resolution timer usage.
  39. Time::ResetHighResolutionTimerUsage();
  40. timer_.Start(FROM_HERE, kUsageSampleInterval,
  41. BindRepeating(&ReportHighResolutionTimerUsage));
  42. }
  43. }
  44. HighResolutionTimerManager::~HighResolutionTimerManager() {
  45. if (HighResolutionTimerAllowed()) {
  46. PowerMonitor::RemovePowerSuspendObserver(this);
  47. PowerMonitor::RemovePowerStateObserver(this);
  48. UseHiResClock(false);
  49. }
  50. }
  51. void HighResolutionTimerManager::OnPowerStateChange(bool on_battery_power) {
  52. DCHECK(HighResolutionTimerAllowed());
  53. UseHiResClock(!on_battery_power);
  54. }
  55. void HighResolutionTimerManager::OnSuspend() {
  56. DCHECK(HighResolutionTimerAllowed());
  57. // Stop polling the usage to avoid including the standby time.
  58. timer_.Stop();
  59. }
  60. void HighResolutionTimerManager::OnResume() {
  61. DCHECK(HighResolutionTimerAllowed());
  62. // Resume polling the usage.
  63. Time::ResetHighResolutionTimerUsage();
  64. timer_.Reset();
  65. }
  66. void HighResolutionTimerManager::UseHiResClock(bool use) {
  67. DCHECK(HighResolutionTimerAllowed());
  68. if (use == hi_res_clock_available_)
  69. return;
  70. hi_res_clock_available_ = use;
  71. Time::EnableHighResolutionTimer(use);
  72. }
  73. } // namespace base