xref: /aosp_15_r20/external/perfetto/src/traced/probes/sys_stats/sys_stats_data_source.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2018 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SRC_TRACED_PROBES_SYS_STATS_SYS_STATS_DATA_SOURCE_H_
18 #define SRC_TRACED_PROBES_SYS_STATS_SYS_STATS_DATA_SOURCE_H_
19 
20 #include <string.h>
21 
22 #include <map>
23 #include <memory>
24 #include <optional>
25 #include <string>
26 
27 #include "perfetto/ext/base/paged_memory.h"
28 #include "perfetto/ext/base/scoped_file.h"
29 #include "perfetto/ext/base/weak_ptr.h"
30 #include "perfetto/ext/tracing/core/basic_types.h"
31 #include "perfetto/ext/tracing/core/trace_writer.h"
32 #include "perfetto/tracing/core/data_source_config.h"
33 #include "protos/perfetto/trace/sys_stats/sys_stats.pbzero.h"
34 #include "src/traced/probes/common/cpu_freq_info.h"
35 #include "src/traced/probes/probes_data_source.h"
36 
37 namespace perfetto {
38 
39 namespace base {
40 class TaskRunner;
41 }
42 
43 namespace protos {
44 namespace pbzero {
45 class SysStats;
46 }
47 }  // namespace protos
48 
49 class SysStatsDataSource : public ProbesDataSource {
50  public:
51   static const ProbesDataSource::Descriptor descriptor;
52 
53   using OpenFunction = base::ScopedFile (*)(const char*);
54   SysStatsDataSource(base::TaskRunner*,
55                      TracingSessionID,
56                      std::unique_ptr<TraceWriter> writer,
57                      const DataSourceConfig&,
58                      std::unique_ptr<CpuFreqInfo> cpu_freq_info,
59                      OpenFunction = nullptr);
60   ~SysStatsDataSource() override;
61 
62   // ProbesDataSource implementation.
63   void Start() override;
64   void Flush(FlushRequestID, std::function<void()> callback) override;
65 
66   base::WeakPtr<SysStatsDataSource> GetWeakPtr() const;
67 
set_ns_per_user_hz_for_testing(uint64_t ns)68   void set_ns_per_user_hz_for_testing(uint64_t ns) { ns_per_user_hz_ = ns; }
tick_for_testing()69   uint32_t tick_for_testing() const { return tick_; }
70 
71   // Virtual for testing
72   virtual base::ScopedDir OpenDirAndLogOnErrorOnce(const std::string& dir_path,
73                                                    bool* already_logged);
74   virtual const char* ReadDevfreqCurFreq(const std::string& name);
75   virtual std::optional<uint64_t> ReadFileToUInt64(const std::string& path);
76   virtual std::optional<std::string> ReadFileToString(const std::string& path);
77 
78  protected:
79   bool thermal_error_logged_ = false;
80   bool devfreq_error_logged_ = false;
81   bool cpuidle_error_logged_ = false;
82 
83  private:
84   struct CStrCmp {
operatorCStrCmp85     bool operator()(const char* a, const char* b) const {
86       return strcmp(a, b) < 0;
87     }
88   };
89 
90   static void Tick(base::WeakPtr<SysStatsDataSource>);
91 
92   SysStatsDataSource(const SysStatsDataSource&) = delete;
93   SysStatsDataSource& operator=(const SysStatsDataSource&) = delete;
94   void ReadSysStats();  // Virtual for testing.
95   void ReadMeminfo(protos::pbzero::SysStats* sys_stats);
96   void ReadVmstat(protos::pbzero::SysStats* sys_stats);
97   void ReadStat(protos::pbzero::SysStats* sys_stats);
98   void ReadDevfreq(protos::pbzero::SysStats* sys_stats);
99   void ReadCpufreq(protos::pbzero::SysStats* sys_stats);
100   void ReadBuddyInfo(protos::pbzero::SysStats* sys_stats);
101   void ReadDiskStat(protos::pbzero::SysStats* sys_stats);
102   void ReadPsi(protos::pbzero::SysStats* sys_stats);
103   void ReadThermalZones(protos::pbzero::SysStats* sys_stats);
104   void ReadCpuIdleStates(protos::pbzero::SysStats* sys_stats);
105   void ReadGpuFrequency(protos::pbzero::SysStats* sys_stats);
106   std::optional<uint64_t> ReadAMDGpuFreq();
107 
108   size_t ReadFile(base::ScopedFile*, const char* path);
109 
110   base::TaskRunner* const task_runner_;
111   std::unique_ptr<TraceWriter> writer_;
112   base::ScopedFile meminfo_fd_;
113   base::ScopedFile vmstat_fd_;
114   base::ScopedFile stat_fd_;
115   base::ScopedFile buddy_fd_;
116   base::ScopedFile diskstat_fd_;
117   base::ScopedFile psi_cpu_fd_;
118   base::ScopedFile psi_io_fd_;
119   base::ScopedFile psi_memory_fd_;
120   base::PagedMemory read_buf_;
121   TraceWriter::TracePacketHandle cur_packet_;
122   std::map<const char*, int, CStrCmp> meminfo_counters_;
123   std::map<const char*, int, CStrCmp> vmstat_counters_;
124   uint64_t ns_per_user_hz_ = 0;
125   uint32_t tick_ = 0;
126   uint32_t tick_period_ms_ = 0;
127   uint32_t meminfo_ticks_ = 0;
128   uint32_t vmstat_ticks_ = 0;
129   uint32_t stat_ticks_ = 0;
130   uint32_t stat_enabled_fields_ = 0;
131   uint32_t devfreq_ticks_ = 0;
132   uint32_t cpufreq_ticks_ = 0;
133   uint32_t buddyinfo_ticks_ = 0;
134   uint32_t diskstat_ticks_ = 0;
135   uint32_t psi_ticks_ = 0;
136   uint32_t thermal_ticks_ = 0;
137   uint32_t cpuidle_ticks_ = 0;
138   uint32_t gpufreq_ticks_ = 0;
139 
140   std::unique_ptr<CpuFreqInfo> cpu_freq_info_;
141 
142   base::WeakPtrFactory<SysStatsDataSource> weak_factory_;  // Keep last.
143 };
144 
145 }  // namespace perfetto
146 
147 #endif  // SRC_TRACED_PROBES_SYS_STATS_SYS_STATS_DATA_SOURCE_H_
148