• 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 #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