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