1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
|
// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef CHROME_BROWSER_ASH_POWER_CPU_DATA_COLLECTOR_H_
#define CHROME_BROWSER_ASH_POWER_CPU_DATA_COLLECTOR_H_
#include <stdint.h>
#include <map>
#include <string>
#include <vector>
#include "base/containers/circular_deque.h"
#include "base/files/file_util.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "base/timer/timer.h"
namespace ash {
// A class to sample CPU idle state occupancy and freq state occupancy.
// Collects raw data from sysfs and does not convert it to percentage
// occupancy. As CPUs can be offline at times, or the system can be suspended at
// other times, it is best for the consumer of this data to calculate percentage
// occupancy information using suspend time data from
// PowerDataCollector::system_resumed_data.
class CpuDataCollector {
public:
struct StateOccupancySample {
StateOccupancySample();
StateOccupancySample(const StateOccupancySample& other);
~StateOccupancySample();
// The time when the data was sampled.
base::Time time;
// Indicates whether the CPU is online.
bool cpu_online;
// A mapping from a CPU state to time spent in that state. For idle state
// samples, the name of the state at index i in this vector is the name at
// index i in the vector returned by cpu_idle_state_names(). Similarly, for
// freq state occupancy, similar information is in the vector returned by
// cpu_freq_state_names().
std::vector<base::TimeDelta> time_in_state;
};
using StateOccupancySampleDeque = base::circular_deque<StateOccupancySample>;
const std::vector<std::string>& cpu_idle_state_names() const {
return cpu_idle_state_names_;
}
const std::vector<StateOccupancySampleDeque>& cpu_idle_state_data() const {
return cpu_idle_state_data_;
}
const std::vector<std::string>& cpu_freq_state_names() const {
return cpu_freq_state_names_;
}
const std::vector<StateOccupancySampleDeque>& cpu_freq_state_data() const {
return cpu_freq_state_data_;
}
CpuDataCollector();
CpuDataCollector(const CpuDataCollector&) = delete;
CpuDataCollector& operator=(const CpuDataCollector&) = delete;
~CpuDataCollector();
// Starts a repeating timer which periodically runs a callback to collect
// CPU state occupancy samples.
void Start();
// Read CPU frequency data of a specific CPU from the file in |path| and fill
// |cpu_freq_state_names| and |freq_sample| with the data.
// Sample file looks like:
// 126000 223344
// 216000 93495
// ...
// 1800000 321907
static bool ReadCpuFreqTimeInState(
const base::FilePath& path,
std::vector<std::string>* cpu_freq_state_names,
CpuDataCollector::StateOccupancySample* freq_sample);
// Read CPU frequency data of all CPUs from the file in |path| and fill
// |cpu_freq_state_names| and |freq_samples| with the data. |cpu_count| is the
// number of possible CPUs on the system. Note that |freq_samples| is not
// empty and sample at index i in |freq_samples| corresponds to the freq state
// information of the i-th CPU. |cpu_online| of each sample must be set before
// calling this function.
// Sample file looks like:
// freq cpu0 cpu1
// 126000 223344 223311
// 216000 93495 93450
// ...
// 1800000 321907 331897
static bool ReadCpuFreqAllTimeInState(
int cpu_count,
const base::FilePath& path,
std::vector<std::string>* cpu_freq_state_names,
std::vector<CpuDataCollector::StateOccupancySample>* freq_samples);
private:
// Posts callbacks to the blocking pool which collect CPU state occupancy
// samples from the sysfs.
void PostSampleCpuState();
// This function commits the CPU count and samples read by
// SampleCpuStateAsync to |cpu_idle_state_data_| and
// |cpu_freq_state_data_|. Since UI is the consumer of CPU idle and freq data,
// this function should run on the UI thread.
void SaveCpuStateSamplesOnUIThread(
const int* cpu_count,
const std::vector<std::string>* cpu_idle_state_names,
const std::vector<StateOccupancySample>* idle_samples,
const std::vector<std::string>* cpu_freq_state_names,
const std::vector<StateOccupancySample>* freq_samples);
base::RepeatingTimer timer_;
// Names of the idle states.
std::vector<std::string> cpu_idle_state_names_;
// The deque at index <i> in the vector corresponds to the idle state
// occupancy data of CPU<i>.
std::vector<StateOccupancySampleDeque> cpu_idle_state_data_;
// Names of the freq states.
std::vector<std::string> cpu_freq_state_names_;
// The deque at index <i> in the vector corresponds to the frequency state
// occupancy data of CPU<i>.
std::vector<StateOccupancySampleDeque> cpu_freq_state_data_;
// The number of CPUs on the system. This value is read from the sysfs, and
// hence should be read/written to only from the blocking pool.
int cpu_count_;
base::WeakPtrFactory<CpuDataCollector> weak_ptr_factory_{this};
};
} // namespace ash
#endif // CHROME_BROWSER_ASH_POWER_CPU_DATA_COLLECTOR_H_
|