xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/ftrace/thermal_tracker.cc (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
1 /*
2  * Copyright (C) 2024 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 #include "src/trace_processor/importers/ftrace/thermal_tracker.h"
18 
19 #include <array>
20 #include <cstddef>
21 #include <cstdint>
22 
23 #include "perfetto/ext/base/string_utils.h"
24 #include "perfetto/ext/base/string_view.h"
25 #include "perfetto/protozero/field.h"
26 #include "protos/perfetto/trace/ftrace/thermal.pbzero.h"
27 #include "protos/perfetto/trace/ftrace/thermal_exynos.pbzero.h"
28 #include "src/trace_processor/importers/common/args_tracker.h"
29 #include "src/trace_processor/importers/common/event_tracker.h"
30 #include "src/trace_processor/importers/common/track_tracker.h"
31 #include "src/trace_processor/importers/common/tracks.h"
32 #include "src/trace_processor/importers/common/tracks_common.h"
33 #include "src/trace_processor/storage/stats.h"
34 #include "src/trace_processor/storage/trace_storage.h"
35 #include "src/trace_processor/types/variadic.h"
36 
37 namespace perfetto::trace_processor {
38 namespace {
39 
40 constexpr std::array<const char*, 7> kAcpmThermalZones = {
41     "BIG", "MID", "LITTLE", "GPU", "ISP", "TPU", "AUR",
42 };
43 
44 constexpr char kThermalZoneIdKey[] = "thermal_zone_id";
45 
46 constexpr auto kThermalZoneDimension =
47     tracks::StringDimensionBlueprint("thermal_zone");
48 
49 constexpr auto kAcpmTemperatureTrackBlueprint = tracks::CounterBlueprint(
50     "acpm_thermal_temperature",
51     tracks::UnknownUnitBlueprint(),
52     tracks::DimensionBlueprints(kThermalZoneDimension),
__anonaecd97970202(base::StringView zone) 53     tracks::FnNameBlueprint([](base::StringView zone) {
54       return base::StackString<64>("%.*s Temperature",
55                                    static_cast<int>(zone.size()), zone.data());
56     }));
57 
58 constexpr auto kAcpmCoolingTrackBlueprint = tracks::CounterBlueprint(
59     "acpm_cooling_device_counter",
60     tracks::UnknownUnitBlueprint(),
61     tracks::DimensionBlueprints(kThermalZoneDimension),
__anonaecd97970302(base::StringView zone) 62     tracks::FnNameBlueprint([](base::StringView zone) {
63       return base::StackString<64>("Tj-%.*s Cooling Device",
64                                    static_cast<int>(zone.size()), zone.data());
65     }));
66 
67 }  // namespace
68 
ThermalTracker(TraceProcessorContext * context)69 ThermalTracker::ThermalTracker(TraceProcessorContext* context)
70     : context_(context) {}
71 
ParseThermalTemperature(int64_t timestamp,protozero::ConstBytes blob)72 void ThermalTracker::ParseThermalTemperature(int64_t timestamp,
73                                              protozero::ConstBytes blob) {
74   protos::pbzero::ThermalTemperatureFtraceEvent::Decoder event(blob);
75   TrackId track = context_->track_tracker->InternTrack(
76       tracks::kThermalTemperatureBlueprint,
77       tracks::Dimensions(event.thermal_zone()));
78   context_->event_tracker->PushCounter(
79       timestamp, static_cast<double>(event.temp()), track);
80 }
81 
ParseCdevUpdate(int64_t timestamp,protozero::ConstBytes blob)82 void ThermalTracker::ParseCdevUpdate(int64_t timestamp,
83                                      protozero::ConstBytes blob) {
84   protos::pbzero::CdevUpdateFtraceEvent::Decoder event(blob);
85   TrackId track = context_->track_tracker->InternTrack(
86       tracks::kCoolingDeviceCounterBlueprint, tracks::Dimensions(event.type()));
87   context_->event_tracker->PushCounter(
88       timestamp, static_cast<double>(event.target()), track);
89 }
90 
ParseThermalExynosAcpmBulk(protozero::ConstBytes blob)91 void ThermalTracker::ParseThermalExynosAcpmBulk(protozero::ConstBytes blob) {
92   protos::pbzero::ThermalExynosAcpmBulkFtraceEvent::Decoder event(blob);
93   auto tz_id = static_cast<uint32_t>(event.tz_id());
94   if (tz_id >= kAcpmThermalZones.size()) {
95     context_->storage->IncrementStats(
96         stats::ftrace_thermal_exynos_acpm_unknown_tz_id);
97     return;
98   }
99   auto timestamp = static_cast<int64_t>(event.timestamp());
100   {
101     TrackId track = context_->track_tracker->InternTrack(
102         kAcpmTemperatureTrackBlueprint,
103         tracks::Dimensions(kAcpmThermalZones[tz_id]));
104     context_->event_tracker->PushCounter(
105         timestamp, static_cast<double>(event.current_temp()), track,
106         [this, tz_id](ArgsTracker::BoundInserter* inserter) {
107           StringId key = context_->storage->InternString(kThermalZoneIdKey);
108           inserter->AddArg(key, Variadic::Integer(tz_id));
109         });
110   }
111   {
112     TrackId track = context_->track_tracker->InternTrack(
113         kAcpmCoolingTrackBlueprint,
114         tracks::Dimensions(kAcpmThermalZones[tz_id]));
115     context_->event_tracker->PushCounter(
116         timestamp, static_cast<double>(event.cdev_state()), track,
117         [this, tz_id](ArgsTracker::BoundInserter* inserter) {
118           StringId key = context_->storage->InternString(kThermalZoneIdKey);
119           inserter->AddArg(key, Variadic::Integer(tz_id));
120         });
121   }
122 }
123 
ParseThermalExynosAcpmHighOverhead(int64_t timestamp,protozero::ConstBytes blob)124 void ThermalTracker::ParseThermalExynosAcpmHighOverhead(
125     int64_t timestamp,
126     protozero::ConstBytes blob) {
127   protos::pbzero::ThermalExynosAcpmHighOverheadFtraceEvent::Decoder event(blob);
128   auto tz_id = static_cast<uint32_t>(event.tz_id());
129   if (tz_id >= kAcpmThermalZones.size()) {
130     context_->storage->IncrementStats(
131         stats::ftrace_thermal_exynos_acpm_unknown_tz_id);
132     return;
133   }
134   {
135     TrackId track = context_->track_tracker->InternTrack(
136         kAcpmTemperatureTrackBlueprint,
137         tracks::Dimensions(kAcpmThermalZones[tz_id]));
138     context_->event_tracker->PushCounter(
139         timestamp, static_cast<double>(event.current_temp()), track,
140         [this, tz_id](ArgsTracker::BoundInserter* inserter) {
141           StringId key = context_->storage->InternString(kThermalZoneIdKey);
142           inserter->AddArg(key, Variadic::Integer(tz_id));
143         });
144   }
145   {
146     TrackId track = context_->track_tracker->InternTrack(
147         kAcpmCoolingTrackBlueprint,
148         tracks::Dimensions(kAcpmThermalZones[tz_id]));
149     context_->event_tracker->PushCounter(
150         timestamp, static_cast<double>(event.cdev_state()), track,
151         [this, tz_id](ArgsTracker::BoundInserter* inserter) {
152           StringId key = context_->storage->InternString(kThermalZoneIdKey);
153           inserter->AddArg(key, Variadic::Integer(tz_id));
154         });
155   }
156 }
157 
158 }  // namespace perfetto::trace_processor
159