• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2019 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/common/track_tracker.h"
18 
19 #include <cstddef>
20 #include <cstdint>
21 #include <optional>
22 #include <tuple>
23 
24 #include "perfetto/ext/base/string_view.h"
25 #include "src/trace_processor/importers/common/args_tracker.h"
26 #include "src/trace_processor/importers/common/cpu_tracker.h"
27 #include "src/trace_processor/importers/common/process_track_translation_table.h"
28 #include "src/trace_processor/importers/common/tracks.h"
29 #include "src/trace_processor/importers/common/tracks_common.h"
30 #include "src/trace_processor/importers/common/tracks_internal.h"
31 #include "src/trace_processor/storage/trace_storage.h"
32 #include "src/trace_processor/tables/track_tables_py.h"
33 #include "src/trace_processor/types/trace_processor_context.h"
34 #include "src/trace_processor/types/variadic.h"
35 
36 namespace perfetto::trace_processor {
37 
TrackTracker(TraceProcessorContext * context)38 TrackTracker::TrackTracker(TraceProcessorContext* context)
39     : source_key_(context->storage->InternString("source")),
40       trace_id_key_(context->storage->InternString("trace_id")),
41       trace_id_is_process_scoped_key_(
42           context->storage->InternString("trace_id_is_process_scoped")),
43       upid_(context->storage->InternString("upid")),
44       source_scope_key_(context->storage->InternString("source_scope")),
45       chrome_source_(context->storage->InternString("chrome")),
46       context_(context),
47       args_tracker_(context) {}
48 
InternLegacyAsyncTrack(StringId raw_name,uint32_t upid,int64_t trace_id,bool trace_id_is_process_scoped,StringId source_scope)49 TrackId TrackTracker::InternLegacyAsyncTrack(StringId raw_name,
50                                              uint32_t upid,
51                                              int64_t trace_id,
52                                              bool trace_id_is_process_scoped,
53                                              StringId source_scope) {
54   const StringId name =
55       context_->process_track_translation_table->TranslateName(raw_name);
56 
57   auto args_fn = [&](ArgsTracker::BoundInserter& inserter) {
58     inserter.AddArg(source_key_, Variadic::String(chrome_source_))
59         .AddArg(trace_id_key_, Variadic::Integer(trace_id))
60         .AddArg(trace_id_is_process_scoped_key_,
61                 Variadic::Boolean(trace_id_is_process_scoped))
62         .AddArg(upid_, Variadic::UnsignedInteger(upid))
63         .AddArg(source_scope_key_, Variadic::String(source_scope));
64   };
65   TrackId track_id;
66   bool inserted;
67   if (trace_id_is_process_scoped) {
68     static constexpr auto kBlueprint = tracks::SliceBlueprint(
69         "legacy_async_process_slice",
70         tracks::DimensionBlueprints(tracks::kProcessDimensionBlueprint,
71                                     tracks::StringDimensionBlueprint("scope"),
72                                     tracks::LongDimensionBlueprint("cookie")),
73         tracks::DynamicNameBlueprint());
74     std::tie(track_id, inserted) = InternTrackInner(
75         kBlueprint,
76         tracks::Dimensions(upid, context_->storage->GetString(source_scope),
77                            trace_id),
78         tracks::DynamicName(name), args_fn);
79   } else {
80     static constexpr auto kBlueprint = tracks::SliceBlueprint(
81         "legacy_async_global_slice",
82         tracks::DimensionBlueprints(tracks::StringDimensionBlueprint("scope"),
83                                     tracks::LongDimensionBlueprint("cookie")),
84         tracks::DynamicNameBlueprint());
85     std::tie(track_id, inserted) = InternTrackInner(
86         kBlueprint,
87         tracks::Dimensions(context_->storage->GetString(source_scope),
88                            trace_id),
89         tracks::DynamicName(name), args_fn);
90   }
91   // The track may have been created for an end event without name. In
92   // that case, update it with this event's name.
93   if (inserted && name != kNullStringId) {
94     auto& tracks = *context_->storage->mutable_track_table();
95     auto rr = *tracks.FindById(track_id);
96     if (rr.name() == kNullStringId) {
97       rr.set_name(name);
98     }
99   }
100   return track_id;
101 }
102 
AddTrack(const tracks::BlueprintBase & blueprint,StringId name,StringId counter_unit,GlobalArgsTracker::CompactArg * d_args,uint32_t d_size,const SetArgsCallback & args)103 TrackId TrackTracker::AddTrack(const tracks::BlueprintBase& blueprint,
104                                StringId name,
105                                StringId counter_unit,
106                                GlobalArgsTracker::CompactArg* d_args,
107                                uint32_t d_size,
108                                const SetArgsCallback& args) {
109   tables::TrackTable::Row row(name);
110   const auto* dims = blueprint.dimension_blueprints.data();
111   for (uint32_t i = 0; i < d_size; ++i) {
112     base::StringView str(dims[i].name.data(), dims[i].name.size());
113     if (str == "cpu" && d_args[i].value.type == Variadic::kInt) {
114       context_->cpu_tracker->MarkCpuValid(
115           static_cast<uint32_t>(d_args[i].value.int_value));
116     } else if (str == "utid" && d_args[i].value.type == Variadic::kInt) {
117       row.utid = static_cast<uint32_t>(d_args[i].value.int_value);
118     } else if (str == "upid" && d_args[i].value.type == Variadic::kInt) {
119       row.upid = static_cast<uint32_t>(d_args[i].value.int_value);
120     }
121     StringId key = context_->storage->InternString(str);
122     d_args[i].key = key;
123     d_args[i].flat_key = key;
124   }
125 
126   row.machine_id = context_->machine_id();
127   row.type = context_->storage->InternString(
128       base::StringView(blueprint.type.data(), blueprint.type.size()));
129   if (d_size > 0) {
130     row.dimension_arg_set_id =
131         context_->global_args_tracker->AddArgSet(d_args, 0, d_size);
132   }
133   row.event_type = context_->storage->InternString(blueprint.event_type);
134   row.counter_unit = counter_unit;
135   TrackId id = context_->storage->mutable_track_table()->Insert(row).id;
136   if (args) {
137     auto inserter = args_tracker_.AddArgsTo(id);
138     args(inserter);
139     args_tracker_.Flush();
140   }
141   return id;
142 }
143 
144 }  // namespace perfetto::trace_processor
145