1 // Copyright 2020 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/task/sequence_manager/thread_controller_power_monitor.h" 6 7 #include "base/feature_list.h" 8 #include "base/power_monitor/power_monitor.h" 9 #include "base/trace_event/base_tracing.h" 10 11 namespace base { 12 namespace sequence_manager { 13 namespace internal { 14 15 namespace { 16 17 // Activate the power management events that affect task scheduling. 18 BASE_FEATURE(kUsePowerMonitorWithThreadController, 19 "UsePowerMonitorWithThreadController", 20 FEATURE_ENABLED_BY_DEFAULT); 21 22 // TODO(1074332): Remove this when the experiment becomes the default. 23 bool g_use_thread_controller_power_monitor_ = false; 24 25 } // namespace 26 27 ThreadControllerPowerMonitor::ThreadControllerPowerMonitor() = default; 28 ~ThreadControllerPowerMonitor()29ThreadControllerPowerMonitor::~ThreadControllerPowerMonitor() { 30 PowerMonitor::RemovePowerSuspendObserver(this); 31 } 32 BindToCurrentThread()33void ThreadControllerPowerMonitor::BindToCurrentThread() { 34 // Occasionally registration happens twice (i.e. when the 35 // ThreadController::SetDefaultTaskRunner() re-initializes the 36 // ThreadController). 37 if (is_observer_registered_) 38 PowerMonitor::RemovePowerSuspendObserver(this); 39 40 // Register the observer to deliver notifications on the current thread. 41 PowerMonitor::AddPowerSuspendObserver(this); 42 is_observer_registered_ = true; 43 } 44 IsProcessInPowerSuspendState()45bool ThreadControllerPowerMonitor::IsProcessInPowerSuspendState() { 46 return is_power_suspended_; 47 } 48 49 // static InitializeFeatures()50void ThreadControllerPowerMonitor::InitializeFeatures() { 51 DCHECK(!g_use_thread_controller_power_monitor_); 52 g_use_thread_controller_power_monitor_ = 53 FeatureList::IsEnabled(kUsePowerMonitorWithThreadController); 54 } 55 56 // static OverrideUsePowerMonitorForTesting(bool use_power_monitor)57void ThreadControllerPowerMonitor::OverrideUsePowerMonitorForTesting( 58 bool use_power_monitor) { 59 g_use_thread_controller_power_monitor_ = use_power_monitor; 60 } 61 62 // static ResetForTesting()63void ThreadControllerPowerMonitor::ResetForTesting() { 64 g_use_thread_controller_power_monitor_ = false; 65 } 66 OnSuspend()67void ThreadControllerPowerMonitor::OnSuspend() { 68 if (!g_use_thread_controller_power_monitor_) 69 return; 70 DCHECK(!is_power_suspended_); 71 72 TRACE_EVENT_BEGIN("base", "ThreadController::Suspended", 73 perfetto::Track(reinterpret_cast<uint64_t>(this), 74 perfetto::ThreadTrack::Current())); 75 is_power_suspended_ = true; 76 } 77 OnResume()78void ThreadControllerPowerMonitor::OnResume() { 79 if (!g_use_thread_controller_power_monitor_) 80 return; 81 82 // It is possible a suspend was already happening before the observer was 83 // added to the power monitor. Ignoring the resume notification in that case. 84 if (is_power_suspended_) { 85 TRACE_EVENT_END("base" /* ThreadController::Suspended */, 86 perfetto::Track(reinterpret_cast<uint64_t>(this), 87 perfetto::ThreadTrack::Current())); 88 is_power_suspended_ = false; 89 } 90 } 91 92 } // namespace internal 93 } // namespace sequence_manager 94 } // namespace base 95