• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 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 #ifndef BASE_TRACE_EVENT_CPUFREQ_MONITOR_ANDROID_H_
6 #define BASE_TRACE_EVENT_CPUFREQ_MONITOR_ANDROID_H_
7 
8 #include <atomic>
9 
10 #include "base/base_export.h"
11 #include "base/files/scoped_file.h"
12 #include "base/memory/scoped_refptr.h"
13 #include "base/trace_event/trace_log.h"
14 
15 namespace base {
16 
17 class SingleThreadTaskRunner;
18 
19 namespace trace_event {
20 
21 // A delegate to isolate CPU frequency monitor functionality mainly for testing.
22 class BASE_EXPORT CPUFreqMonitorDelegate {
23  public:
24   CPUFreqMonitorDelegate();
25 
26   CPUFreqMonitorDelegate(const CPUFreqMonitorDelegate&) = delete;
27   CPUFreqMonitorDelegate& operator=(const CPUFreqMonitorDelegate&) = delete;
28 
29   virtual ~CPUFreqMonitorDelegate() = default;
30 
31   // Returns a vector of the minimal set of CPU IDs that we need to monitor to
32   // get CPU frequency information. For CPUs that operate cores in a cluster,
33   // i.e. modern Qualcomm 8 cores, this is CPU0 and CPU4.
34   virtual void GetCPUIds(std::vector<unsigned int>* ids) const;
35 
36   // Reads the kernel_max_cpu file to determine the max CPU ID, i.e. 7 on an
37   // 8-core CPU.
38   virtual unsigned int GetKernelMaxCPUs() const;
39 
40   // Reads the frequency from the CPUs being monitored and records them.
41   virtual void RecordFrequency(unsigned int cpu_id, unsigned int freq);
42 
43   // Returns whether or not the tracing category our CPU Frequency counters are
44   // in is enabled to determine if we should record.
45   virtual bool IsTraceCategoryEnabled() const;
46 
47   // Gets the path to CPU frequency related files for a particular CPU ID.
48   virtual std::string GetScalingCurFreqPathString(unsigned int cpu_id) const;
49   virtual std::string GetRelatedCPUsPathString(unsigned int cpu_id) const;
50 
51   // Allows us to delay creating a task runner, necessary because many tests
52   // don't like us creating one outside of a TaskEnvironment.
53   virtual scoped_refptr<SingleThreadTaskRunner> CreateTaskRunner();
54 };
55 
56 // A class for monitoring the CPU frequency on unique cores/clusters.
57 class BASE_EXPORT CPUFreqMonitor : public TraceLog::EnabledStateObserver {
58  public:
59   // Overhead of reading one cluster on a Nexus 6P is ~0.1ms per CPU. 50ms seems
60   // frequent enough to get a general idea of CPU frequency trends.
61   static const size_t kDefaultCPUFreqSampleIntervalMs = 50;
62 
63   CPUFreqMonitor();
64 
65   CPUFreqMonitor(const CPUFreqMonitor&) = delete;
66   CPUFreqMonitor& operator=(const CPUFreqMonitor&) = delete;
67 
68   ~CPUFreqMonitor() override;
69 
70   static CPUFreqMonitor* GetInstance();
71 
72   void Start();
73   void Stop();
74 
75   // TraceLog::EnabledStateObserver.
76   void OnTraceLogEnabled() override;
77   void OnTraceLogDisabled() override;
78 
79   bool IsEnabledForTesting();
80 
81  private:
82   friend class CPUFreqMonitorTest;
83 
84   CPUFreqMonitor(std::unique_ptr<CPUFreqMonitorDelegate> delegate);
85 
86   void Sample(std::vector<std::pair<unsigned int, base::ScopedFD>> fds);
87 
88   // Uses the delegate's CreateTaskRunner function to lazily create a task
89   // runner so we don't illegally create a task runner on Chrome startup for
90   // various tests.
91   const scoped_refptr<SingleThreadTaskRunner>& GetOrCreateTaskRunner();
92 
93   std::atomic<bool> is_enabled_{false};
94   scoped_refptr<SingleThreadTaskRunner> task_runner_;
95   std::unique_ptr<CPUFreqMonitorDelegate> delegate_;
96   base::WeakPtrFactory<CPUFreqMonitor> weak_ptr_factory_{this};
97 };
98 
99 }  // namespace trace_event
100 }  // namespace base
101 
102 #endif  // BASE_TRACE_EVENT_CPUFREQ_MONITOR_ANDROID_H_
103