xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/common/tracks.h (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 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_TRACKS_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_TRACKS_H_
19 
20 #include <array>
21 #include <cstddef>
22 #include <cstdint>
23 #include <string_view>
24 #include <tuple>
25 
26 #include "perfetto/ext/base/hash.h"
27 #include "perfetto/ext/base/string_view.h"
28 #include "src/trace_processor/containers/string_pool.h"
29 #include "src/trace_processor/importers/common/tracks_internal.h"
30 
31 namespace perfetto::trace_processor::tracks {
32 
33 // This file contains the "public API" for creating track blueprints.
34 // See TrackTracker::InternTrack for usages of the functions in this file.
35 
36 // Start of blueprint functions.
37 
38 // Creates a blueprint for a slice track.
39 // See TrackTracker::InternTrack for usage of this function.
40 template <typename NB = NameBlueprintT::Auto, typename... D>
41 constexpr auto SliceBlueprint(const char classification[],
42                               DimensionBlueprintsT<D...> dimensions = {},
43                               NB name = NB{}) {
44   static_assert(sizeof...(D) < 8, "At most 8 dimensions are supported");
45   auto dims_array = std::apply(
46       [](auto&&... x) { return std::array<DimensionBlueprintBase, 8>{x...}; },
47       dimensions);
48   return BlueprintT<NB, UnitBlueprintT::Unknown, D...>{
49       {
50           "slice",
51           classification,
52           base::Hasher::CreatePartial(classification),
53           dims_array,
54       },
55       name,
56       UnitBlueprintT::Unknown{},
57   };
58 }
59 
60 // Creates a blueprint for a counter track.
61 // See TrackTracker::InternTrack for usage on this function.
62 template <typename NB = NameBlueprintT::Auto,
63           typename UB = UnitBlueprintT::Unknown,
64           typename... D>
65 constexpr auto CounterBlueprint(const char classification[],
66                                 UB unit,
67                                 DimensionBlueprintsT<D...> dimensions = {},
68                                 NB name = NB{}) {
69   static_assert(sizeof...(D) < 8, "At most 8 dimensions are supported");
70   auto dims_array = std::apply(
71       [](auto&&... x) { return std::array<DimensionBlueprintBase, 8>{x...}; },
72       dimensions);
73   return BlueprintT<NB, UB, D...>{
74       {
75           "counter",
76           classification,
77           base::Hasher::CreatePartial(classification),
78           dims_array,
79       },
80       name,
81       unit,
82   };
83 }
84 
85 // Wraps all the dimension blueprints before passing them to SliceBlueprint()
86 // or CounterBlueprint().
87 template <typename... DimensionBlueprint>
DimensionBlueprints(DimensionBlueprint...dimensions)88 constexpr auto DimensionBlueprints(DimensionBlueprint... dimensions) {
89   return DimensionBlueprintsT<DimensionBlueprint...>{dimensions...};
90 }
91 
92 // Adds a unit32_t dimension with the given name.
UintDimensionBlueprint(const char name[])93 constexpr auto UintDimensionBlueprint(const char name[]) {
94   return DimensionBlueprintT<uint32_t>{{name, std::string_view(name) == "cpu"}};
95 }
96 
97 // Adds a string dimension with the given name.
StringDimensionBlueprint(const char name[])98 constexpr auto StringDimensionBlueprint(const char name[]) {
99   return DimensionBlueprintT<base::StringView>{{name, false}};
100 }
101 
102 // Adds a int64_t dimension with the given name.
LongDimensionBlueprint(const char name[])103 constexpr auto LongDimensionBlueprint(const char name[]) {
104   return DimensionBlueprintT<int64_t>{{name, false}};
105 }
106 
107 // Indicates the name should be automatically determined by trace processor.
AutoNameBlueprint()108 constexpr auto AutoNameBlueprint() {
109   return NameBlueprintT::Auto{};
110 }
111 
112 // Indicates the name of the track should be given by a static string. This
113 // should really only be used when the track has no dimensions as it's quite
114 // confusing in queries otherwise.
StaticNameBlueprint(const char name[])115 constexpr auto StaticNameBlueprint(const char name[]) {
116   return NameBlueprintT::Static{name};
117 }
118 
119 // Indicates the name of the track is dynamic and will be provided at runtime to
120 // InternTrack.
DynamicNameBlueprint()121 constexpr auto DynamicNameBlueprint() {
122   return NameBlueprintT::Dynamic{};
123 }
124 
125 // Indicates the name of the track is a function which accepts as input the
126 // dimensions of the track and returns a base::StackString containing the
127 // results of transforming the dimensions.
128 template <typename F>
FnNameBlueprint(F fn)129 constexpr auto FnNameBlueprint(F fn) {
130   return NameBlueprintT::Fn<F>{{}, fn};
131 }
132 
133 // Indicates that the unit of this track is given by a static string.
StaticUnitBlueprint(const char unit[])134 constexpr auto StaticUnitBlueprint(const char unit[]) {
135   return UnitBlueprintT::Static{unit};
136 }
137 
138 // Indicates the unit of this track is dynamic and will be provided at
139 // InternTrack time.
DynamicUnitBlueprint()140 constexpr auto DynamicUnitBlueprint() {
141   return UnitBlueprintT::Dynamic{};
142 }
143 
144 // Indicates that the units of the counter are unknown. Should not be used, is
145 // only intended for counter tracks which predate the introduction of track
146 // blueprints.
UnknownUnitBlueprint()147 constexpr auto UnknownUnitBlueprint() {
148   return UnitBlueprintT::Unknown{};
149 }
150 
151 // End of blueprint functions.
152 
153 // Start of InternTrack helper functions.
154 
155 // Wraps all the dimensions for a track before passing them to InternTrack.
156 template <typename... D>
Dimensions(D...dimensions)157 constexpr auto Dimensions(D... dimensions) {
158   return DimensionsT<D...>{dimensions...};
159 }
160 
161 // Indicates that the name of the track was provided in the blueprint.
BlueprintName()162 constexpr nullptr_t BlueprintName() {
163   return nullptr;
164 }
165 
166 // Indicates that the name of the track should be `id`. Only valid if
167 // `DynamicNameBlueprint()` was passed when creating the blueprint.
DynamicName(StringPool::Id id)168 constexpr StringPool::Id DynamicName(StringPool::Id id) {
169   return id;
170 }
171 
172 // Indicates that the unit of the track was provided in the blueprint.
BlueprintUnit()173 constexpr nullptr_t BlueprintUnit() {
174   return nullptr;
175 }
176 
177 // Indicates that the unit of the track should be `id`. Only valid if
178 // `DynamicUnitBlueprint()` was passed when creating the blueprint.
DynamicUnit(StringPool::Id id)179 constexpr StringPool::Id DynamicUnit(StringPool::Id id) {
180   return id;
181 }
182 
183 // End of InternTrack helper functions.
184 
185 }  // namespace perfetto::trace_processor::tracks
186 
187 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_COMMON_TRACKS_H_
188