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