• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "perfetto/ext/base/string_utils.h"
19 #include "protos/perfetto/trace/ftrace/thermal.pbzero.h"
20 #include "protos/perfetto/trace/ftrace/thermal_exynos.pbzero.h"
21 #include "src/trace_processor/importers/common/event_tracker.h"
22 #include "src/trace_processor/importers/common/track_tracker.h"
23 
24 namespace perfetto {
25 namespace trace_processor {
26 
27 constexpr const char* kTemperatureSuffix = "Temperature";
28 constexpr const char* kCoolingDeviceSuffix = "Cooling Device";
29 
ThermalTracker(TraceProcessorContext * context)30 ThermalTracker::ThermalTracker(TraceProcessorContext* context)
31     : context_(context) {
32   const std::array<const char*, kAcpmThermalZones> acpm_thermal_zones = {
33       "BIG", "MID", "LITTLE", "GPU", "ISP", "TPU", "AUR",
34   };
35   for (size_t i = 0; i < kAcpmThermalZones; i++) {
36     base::StackString<32> temperature_counter("%s %s", acpm_thermal_zones[i],
37                                               kTemperatureSuffix);
38     acpm_temperature_counters_[i] =
39         context_->storage->InternString(temperature_counter.string_view());
40     base::StackString<32> cooling_device_counter(
41         "Tj-%s %s", acpm_thermal_zones[i], kCoolingDeviceSuffix);
42     acpm_cooling_device_counters_[i] =
43         context_->storage->InternString(cooling_device_counter.string_view());
44   }
45 }
46 
ParseThermalTemperature(int64_t timestamp,protozero::ConstBytes blob)47 void ThermalTracker::ParseThermalTemperature(int64_t timestamp,
48                                              protozero::ConstBytes blob) {
49   protos::pbzero::ThermalTemperatureFtraceEvent::Decoder event(blob);
50   base::StringView tz = event.thermal_zone();
51   base::StackString<255> counter_name("%.*s %s", static_cast<int>(tz.size()),
52                                       tz.data(), kTemperatureSuffix);
53   StringId counter_id =
54       context_->storage->InternString(counter_name.string_view());
55   PushCounter(timestamp, counter_id, static_cast<double>(event.temp()));
56 }
57 
ParseCdevUpdate(int64_t timestamp,protozero::ConstBytes blob)58 void ThermalTracker::ParseCdevUpdate(int64_t timestamp,
59                                      protozero::ConstBytes blob) {
60   protos::pbzero::CdevUpdateFtraceEvent::Decoder event(blob);
61   base::StringView cdev = event.type();
62   base::StackString<255> counter_name("%.*s %s", static_cast<int>(cdev.size()),
63                                       cdev.data(), kCoolingDeviceSuffix);
64   StringId counter_id =
65       context_->storage->InternString(counter_name.string_view());
66   PushCounter(timestamp, counter_id, static_cast<double>(event.target()));
67 }
68 
ParseThermalExynosAcpmBulk(protozero::ConstBytes blob)69 void ThermalTracker::ParseThermalExynosAcpmBulk(protozero::ConstBytes blob) {
70   protos::pbzero::ThermalExynosAcpmBulkFtraceEvent::Decoder event(blob);
71   auto tz_id = static_cast<size_t>(event.tz_id());
72   if (tz_id >= kAcpmThermalZones) {
73     context_->storage->IncrementStats(
74         stats::ftrace_thermal_exynos_acpm_unknown_tz_id);
75     return;
76   }
77   auto timestamp = static_cast<int64_t>(event.timestamp());
78   // Record acpm tz's temperature.
79   PushCounter(timestamp, acpm_temperature_counters_[tz_id],
80               static_cast<double>(event.current_temp()));
81   // Record cdev target of acpm tz's cooling device.
82   PushCounter(timestamp, acpm_cooling_device_counters_[tz_id],
83               static_cast<double>(event.cdev_state()));
84 }
85 
ParseThermalExynosAcpmHighOverhead(int64_t timestamp,protozero::ConstBytes blob)86 void ThermalTracker::ParseThermalExynosAcpmHighOverhead(
87     int64_t timestamp,
88     protozero::ConstBytes blob) {
89   protos::pbzero::ThermalExynosAcpmHighOverheadFtraceEvent::Decoder event(blob);
90   auto tz_id = static_cast<size_t>(event.tz_id());
91   if (tz_id >= kAcpmThermalZones) {
92     context_->storage->IncrementStats(
93         stats::ftrace_thermal_exynos_acpm_unknown_tz_id);
94     return;
95   }
96   // Record acpm tz's temperature.
97   PushCounter(timestamp, acpm_temperature_counters_[tz_id],
98               static_cast<double>(event.current_temp()));
99   // Record cdev target of acpm tz's cooling device.
100   PushCounter(timestamp, acpm_cooling_device_counters_[tz_id],
101               static_cast<double>(event.cdev_state()));
102 }
103 
PushCounter(int64_t timestamp,StringId counter_id,double value)104 void ThermalTracker::PushCounter(int64_t timestamp,
105                                  StringId counter_id,
106                                  double value) {
107   TrackId track = context_->track_tracker->InternGlobalCounterTrack(
108       TrackTracker::Group::kThermals, counter_id);
109   context_->event_tracker->PushCounter(timestamp, value, track);
110 }
111 
112 }  // namespace trace_processor
113 }  // namespace perfetto
114