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()22void ReportHighResolutionTimerUsage() { 23 UMA_HISTOGRAM_PERCENTAGE("Windows.HighResolutionTimerUsage", 24 Time::GetHighResolutionTimerUsage()); 25 // Reset usage for the next interval. 26 Time::ResetHighResolutionTimerUsage(); 27 } 28 HighResolutionTimerAllowed()29bool HighResolutionTimerAllowed() { 30 return !CommandLine::ForCurrentProcess()->HasSwitch( 31 switches::kDisableHighResTimer); 32 } 33 34 } // namespace 35 HighResolutionTimerManager()36HighResolutionTimerManager::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()56HighResolutionTimerManager::~HighResolutionTimerManager() { 57 if (HighResolutionTimerAllowed()) { 58 PowerMonitor::RemovePowerSuspendObserver(this); 59 PowerMonitor::RemovePowerStateObserver(this); 60 UseHiResClock(false); 61 } 62 } 63 OnPowerStateChange(bool on_battery_power)64void HighResolutionTimerManager::OnPowerStateChange(bool on_battery_power) { 65 DCHECK(HighResolutionTimerAllowed()); 66 UseHiResClock(!on_battery_power); 67 } 68 OnSuspend()69void HighResolutionTimerManager::OnSuspend() { 70 DCHECK(HighResolutionTimerAllowed()); 71 // Stop polling the usage to avoid including the standby time. 72 timer_.Stop(); 73 } 74 OnResume()75void HighResolutionTimerManager::OnResume() { 76 DCHECK(HighResolutionTimerAllowed()); 77 // Resume polling the usage. 78 Time::ResetHighResolutionTimerUsage(); 79 timer_.Reset(); 80 } 81 UseHiResClock(bool use)82void 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