• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
14 namespace base {
15 
16 namespace {
17 
18 // Whether to enable a series of optimizations that reduce total CPU
19 // utilization.
20 BASE_FEATURE(kReduceCpuUtilization,
21              "ReduceCpuUtilization2",
22              FEATURE_ENABLED_BY_DEFAULT);
23 
24 class CpuReductionExperimentSubSampler {
25  public:
CpuReductionExperimentSubSampler()26   CpuReductionExperimentSubSampler() : counter_(base::RandUint64()) {}
27 
ShouldLogHistograms()28   bool ShouldLogHistograms() {
29     // Relaxed memory order since there is no dependent memory access.
30     uint64_t val = counter_.fetch_add(1, std::memory_order_relaxed);
31     return val % 1000 == 0;
32   }
33 
34  private:
35   std::atomic<uint64_t> counter_{0};
36 };
37 
38 // Singleton instance of CpuReductionExperimentSubSampler. This is only set when
39 // the ReduceCpuUtilization experiment is enabled -- as a result, it's ok to
40 // assume that the experiment is disabled when this is not set.
41 CpuReductionExperimentSubSampler* g_subsampler = nullptr;
42 
43 #if DCHECK_IS_ON()
44 // Atomic to support concurrent writes from IsRunningCpuReductionExperiment().
45 std::atomic_bool g_accessed_subsampler = false;
46 #endif
47 
48 }  // namespace
49 
IsRunningCpuReductionExperiment()50 bool IsRunningCpuReductionExperiment() {
51 #if DCHECK_IS_ON()
52   // Relaxed memory order since there is no dependent memory access.
53   g_accessed_subsampler.store(true, std::memory_order_relaxed);
54 #endif
55   return !!g_subsampler;
56 }
57 
InitializeCpuReductionExperiment()58 void InitializeCpuReductionExperiment() {
59 #if DCHECK_IS_ON()
60   // TSAN should generate an error if InitializeCpuReductionExperiment() races
61   // with IsRunningCpuReductionExperiment().
62   //
63   // Relaxed memory order since there is no dependent memory access.
64   DCHECK(!g_accessed_subsampler.load(std::memory_order_relaxed));
65 #endif
66   if (FeatureList::IsEnabled(kReduceCpuUtilization)) {
67     g_subsampler = new CpuReductionExperimentSubSampler();
68   }
69 }
70 
ShouldLogHistogramForCpuReductionExperiment()71 bool ShouldLogHistogramForCpuReductionExperiment() {
72   if (!IsRunningCpuReductionExperiment())
73     return true;
74   return g_subsampler->ShouldLogHistograms();
75 }
76 
77 }  // namespace base
78