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