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