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