1*6777b538SAndroid Build Coastguard Worker // Copyright 2022 The Chromium Authors 2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be 3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file. 4*6777b538SAndroid Build Coastguard Worker 5*6777b538SAndroid Build Coastguard Worker #include "base/cpu_reduction_experiment.h" 6*6777b538SAndroid Build Coastguard Worker 7*6777b538SAndroid Build Coastguard Worker #include <atomic> 8*6777b538SAndroid Build Coastguard Worker 9*6777b538SAndroid Build Coastguard Worker #include "base/check.h" 10*6777b538SAndroid Build Coastguard Worker #include "base/dcheck_is_on.h" 11*6777b538SAndroid Build Coastguard Worker #include "base/feature_list.h" 12*6777b538SAndroid Build Coastguard Worker #include "base/rand_util.h" 13*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/lock.h" 14*6777b538SAndroid Build Coastguard Worker #include "base/thread_annotations.h" 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Worker namespace base { 17*6777b538SAndroid Build Coastguard Worker 18*6777b538SAndroid Build Coastguard Worker namespace { 19*6777b538SAndroid Build Coastguard Worker 20*6777b538SAndroid Build Coastguard Worker // Whether to enable a series of optimizations that reduce total CPU 21*6777b538SAndroid Build Coastguard Worker // utilization. 22*6777b538SAndroid Build Coastguard Worker BASE_FEATURE(kReduceCpuUtilization, 23*6777b538SAndroid Build Coastguard Worker "ReduceCpuUtilization2", 24*6777b538SAndroid Build Coastguard Worker FEATURE_ENABLED_BY_DEFAULT); 25*6777b538SAndroid Build Coastguard Worker 26*6777b538SAndroid Build Coastguard Worker class CpuReductionExperimentSubSampler { 27*6777b538SAndroid Build Coastguard Worker public: 28*6777b538SAndroid Build Coastguard Worker CpuReductionExperimentSubSampler() = default; 29*6777b538SAndroid Build Coastguard Worker ShouldLogHistograms()30*6777b538SAndroid Build Coastguard Worker bool ShouldLogHistograms() { 31*6777b538SAndroid Build Coastguard Worker AutoLock hold(lock_); 32*6777b538SAndroid Build Coastguard Worker return sub_sampler_.ShouldSample(0.001); 33*6777b538SAndroid Build Coastguard Worker } 34*6777b538SAndroid Build Coastguard Worker 35*6777b538SAndroid Build Coastguard Worker private: 36*6777b538SAndroid Build Coastguard Worker Lock lock_; 37*6777b538SAndroid Build Coastguard Worker MetricsSubSampler sub_sampler_ GUARDED_BY(lock_); 38*6777b538SAndroid Build Coastguard Worker }; 39*6777b538SAndroid Build Coastguard Worker 40*6777b538SAndroid Build Coastguard Worker // Singleton instance of CpuReductionExperimentSubSampler. This is only set when 41*6777b538SAndroid Build Coastguard Worker // the ReduceCpuUtilization experiment is enabled -- as a result, it's ok to 42*6777b538SAndroid Build Coastguard Worker // assume that the experiment is disabled when this is not set. 43*6777b538SAndroid Build Coastguard Worker CpuReductionExperimentSubSampler* g_subsampler = nullptr; 44*6777b538SAndroid Build Coastguard Worker 45*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 46*6777b538SAndroid Build Coastguard Worker // Atomic to support concurrent writes from IsRunningCpuReductionExperiment(). 47*6777b538SAndroid Build Coastguard Worker std::atomic_bool g_accessed_subsampler = false; 48*6777b538SAndroid Build Coastguard Worker #endif 49*6777b538SAndroid Build Coastguard Worker 50*6777b538SAndroid Build Coastguard Worker } // namespace 51*6777b538SAndroid Build Coastguard Worker IsRunningCpuReductionExperiment()52*6777b538SAndroid Build Coastguard Workerbool IsRunningCpuReductionExperiment() { 53*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 54*6777b538SAndroid Build Coastguard Worker g_accessed_subsampler.store(true, std::memory_order_seq_cst); 55*6777b538SAndroid Build Coastguard Worker #endif 56*6777b538SAndroid Build Coastguard Worker return !!g_subsampler; 57*6777b538SAndroid Build Coastguard Worker } 58*6777b538SAndroid Build Coastguard Worker InitializeCpuReductionExperiment()59*6777b538SAndroid Build Coastguard Workervoid InitializeCpuReductionExperiment() { 60*6777b538SAndroid Build Coastguard Worker #if DCHECK_IS_ON() 61*6777b538SAndroid Build Coastguard Worker // TSAN should generate an error if InitializeCpuReductionExperiment() races 62*6777b538SAndroid Build Coastguard Worker // with IsRunningCpuReductionExperiment(). 63*6777b538SAndroid Build Coastguard Worker DCHECK(!g_accessed_subsampler.load(std::memory_order_seq_cst)); 64*6777b538SAndroid Build Coastguard Worker #endif 65*6777b538SAndroid Build Coastguard Worker if (FeatureList::IsEnabled(kReduceCpuUtilization)) { 66*6777b538SAndroid Build Coastguard Worker g_subsampler = new CpuReductionExperimentSubSampler(); 67*6777b538SAndroid Build Coastguard Worker } 68*6777b538SAndroid Build Coastguard Worker } 69*6777b538SAndroid Build Coastguard Worker ShouldLogHistogramForCpuReductionExperiment()70*6777b538SAndroid Build Coastguard Workerbool ShouldLogHistogramForCpuReductionExperiment() { 71*6777b538SAndroid Build Coastguard Worker if (!IsRunningCpuReductionExperiment()) 72*6777b538SAndroid Build Coastguard Worker return true; 73*6777b538SAndroid Build Coastguard Worker return g_subsampler->ShouldLogHistograms(); 74*6777b538SAndroid Build Coastguard Worker } 75*6777b538SAndroid Build Coastguard Worker 76*6777b538SAndroid Build Coastguard Worker } // namespace base 77