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