blob: ce88f7284ba1eb1949fc9df56e87903d9478750c [file] [log] [blame]
Eric Seckler771960c2019-10-22 15:37:12 +01001/*
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#ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PACKET_SEQUENCE_STATE_H_
18#define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PACKET_SEQUENCE_STATE_H_
19
20#include <stdint.h>
21
22#include <unordered_map>
23#include <vector>
24
Sami Kyostila4d172cd2019-11-07 12:59:44 +000025#include "perfetto/base/compiler.h"
Eric Seckler771960c2019-10-22 15:37:12 +010026#include "perfetto/protozero/proto_decoder.h"
Primiano Tucci3264b592021-11-08 18:20:51 +000027#include "perfetto/trace_processor/trace_blob_view.h"
Lalit Maganti05819e22020-04-14 21:01:38 +010028#include "src/trace_processor/importers/proto/stack_profile_tracker.h"
Lalit Maganti7010b332020-02-07 10:51:15 +000029#include "src/trace_processor/storage/trace_storage.h"
Lalit Maganti0faddc42020-04-10 17:58:24 +010030#include "src/trace_processor/types/trace_processor_context.h"
Alexander Timin97d87852021-05-17 18:01:33 +000031#include "src/trace_processor/util/interned_message_view.h"
Eric Seckler771960c2019-10-22 15:37:12 +010032
Eric Seckler1edbe002019-12-16 18:08:57 +000033#include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
Eric Seckler926b3372020-03-06 16:17:53 +000034#include "protos/perfetto/trace/track_event/track_event.pbzero.h"
Eric Seckler1edbe002019-12-16 18:08:57 +000035
Eric Seckler771960c2019-10-22 15:37:12 +010036namespace perfetto {
37namespace trace_processor {
38
Eric Seckler7e9dc312020-01-02 15:17:28 +000039using InternedMessageMap =
40 std::unordered_map<uint64_t /*iid*/, InternedMessageView>;
41using InternedFieldMap =
42 std::unordered_map<uint32_t /*field_id*/, InternedMessageMap>;
43
44class PacketSequenceState;
45
46class PacketSequenceStateGeneration {
47 public:
48 // Returns |nullptr| if the message with the given |iid| was not found (also
49 // records a stat in this case).
50 template <uint32_t FieldId, typename MessageType>
51 typename MessageType::Decoder* LookupInternedMessage(uint64_t iid);
52
Alexander Timin99653b12021-05-11 22:50:00 +000053 InternedMessageView* GetInternedMessageView(uint32_t field_id, uint64_t iid);
Eric Seckler926b3372020-03-06 16:17:53 +000054 // Returns |nullptr| if no defaults were set.
Eric Seckler7e9dc312020-01-02 15:17:28 +000055 InternedMessageView* GetTracePacketDefaultsView() {
56 if (!trace_packet_defaults_)
57 return nullptr;
58 return &trace_packet_defaults_.value();
59 }
60
Eric Seckler926b3372020-03-06 16:17:53 +000061 // Returns |nullptr| if no defaults were set.
62 protos::pbzero::TracePacketDefaults::Decoder* GetTracePacketDefaults() {
Eric Seckler7e9dc312020-01-02 15:17:28 +000063 InternedMessageView* view = GetTracePacketDefaultsView();
64 if (!view)
65 return nullptr;
66 return view->GetOrCreateDecoder<protos::pbzero::TracePacketDefaults>();
67 }
68
Eric Seckler926b3372020-03-06 16:17:53 +000069 // Returns |nullptr| if no TrackEventDefaults were set.
70 protos::pbzero::TrackEventDefaults::Decoder* GetTrackEventDefaults() {
71 auto* packet_defaults_view = GetTracePacketDefaultsView();
72 if (packet_defaults_view) {
73 auto* track_event_defaults_view =
74 packet_defaults_view
75 ->GetOrCreateSubmessageView<protos::pbzero::TracePacketDefaults,
76 protos::pbzero::TracePacketDefaults::
77 kTrackEventDefaultsFieldNumber>();
78 if (track_event_defaults_view) {
79 return track_event_defaults_view
80 ->GetOrCreateDecoder<protos::pbzero::TrackEventDefaults>();
81 }
82 }
83 return nullptr;
84 }
85
Eric Seckler7e9dc312020-01-02 15:17:28 +000086 PacketSequenceState* state() const { return state_; }
Primiano Tucci63201702020-12-04 17:38:12 +010087 size_t generation_index() const { return generation_index_; }
Eric Seckler7e9dc312020-01-02 15:17:28 +000088
89 private:
90 friend class PacketSequenceState;
91
92 PacketSequenceStateGeneration(PacketSequenceState* state,
93 size_t generation_index)
94 : state_(state), generation_index_(generation_index) {}
95
96 PacketSequenceStateGeneration(PacketSequenceState* state,
97 size_t generation_index,
98 InternedFieldMap interned_data,
99 TraceBlobView defaults)
100 : state_(state),
101 generation_index_(generation_index),
102 interned_data_(interned_data),
103 trace_packet_defaults_(InternedMessageView(std::move(defaults))) {}
104
105 void InternMessage(uint32_t field_id, TraceBlobView message);
106
107 void SetTracePacketDefaults(TraceBlobView defaults) {
108 // Defaults should only be set once per generation.
109 PERFETTO_DCHECK(!trace_packet_defaults_);
110 trace_packet_defaults_ = InternedMessageView(std::move(defaults));
111 }
112
113 PacketSequenceState* state_;
114 size_t generation_index_;
115 InternedFieldMap interned_data_;
116 base::Optional<InternedMessageView> trace_packet_defaults_;
117};
118
Eric Seckler771960c2019-10-22 15:37:12 +0100119class PacketSequenceState {
120 public:
Eric Seckler771960c2019-10-22 15:37:12 +0100121 PacketSequenceState(TraceProcessorContext* context)
Florian Mayerab0c27a2020-08-12 17:42:49 +0100122 : context_(context), sequence_stack_profile_tracker_(context) {
Lalit Maganti9a843112020-11-10 13:39:05 +0000123 current_generation_.reset(
124 new PacketSequenceStateGeneration(this, generation_index_++));
Eric Seckler771960c2019-10-22 15:37:12 +0100125 }
126
127 int64_t IncrementAndGetTrackEventTimeNs(int64_t delta_ns) {
128 PERFETTO_DCHECK(track_event_timestamps_valid());
129 track_event_timestamp_ns_ += delta_ns;
130 return track_event_timestamp_ns_;
131 }
132
133 int64_t IncrementAndGetTrackEventThreadTimeNs(int64_t delta_ns) {
134 PERFETTO_DCHECK(track_event_timestamps_valid());
135 track_event_thread_timestamp_ns_ += delta_ns;
136 return track_event_thread_timestamp_ns_;
137 }
138
139 int64_t IncrementAndGetTrackEventThreadInstructionCount(int64_t delta) {
140 PERFETTO_DCHECK(track_event_timestamps_valid());
141 track_event_thread_instruction_count_ += delta;
142 return track_event_thread_instruction_count_;
143 }
144
Eric Seckler7e9dc312020-01-02 15:17:28 +0000145 // Intern a message into the current generation.
146 void InternMessage(uint32_t field_id, TraceBlobView message) {
Lalit Maganti9a843112020-11-10 13:39:05 +0000147 current_generation_->InternMessage(field_id, std::move(message));
Eric Seckler771960c2019-10-22 15:37:12 +0100148 }
149
Eric Seckler7e9dc312020-01-02 15:17:28 +0000150 // Set the trace packet defaults for the current generation. If the current
151 // generation already has defaults set, starts a new generation without
152 // invalidating other incremental state (such as interned data).
153 void UpdateTracePacketDefaults(TraceBlobView defaults) {
Lalit Maganti9a843112020-11-10 13:39:05 +0000154 if (!current_generation_->GetTracePacketDefaultsView()) {
155 current_generation_->SetTracePacketDefaults(std::move(defaults));
Eric Seckler7e9dc312020-01-02 15:17:28 +0000156 return;
157 }
158
159 // The new defaults should only apply to subsequent messages on the
160 // sequence. Add a new generation with the updated defaults but the
161 // current generation's interned data state.
Lalit Maganti9a843112020-11-10 13:39:05 +0000162 current_generation_.reset(new PacketSequenceStateGeneration(
163 this, generation_index_++, current_generation_->interned_data_,
Eric Seckler7e9dc312020-01-02 15:17:28 +0000164 std::move(defaults)));
Eric Seckler771960c2019-10-22 15:37:12 +0100165 }
166
167 void SetThreadDescriptor(int32_t pid,
168 int32_t tid,
169 int64_t timestamp_ns,
170 int64_t thread_timestamp_ns,
171 int64_t thread_instruction_count) {
172 track_event_timestamps_valid_ = true;
173 pid_and_tid_valid_ = true;
174 pid_ = pid;
175 tid_ = tid;
176 track_event_timestamp_ns_ = timestamp_ns;
177 track_event_thread_timestamp_ns_ = thread_timestamp_ns;
178 track_event_thread_instruction_count_ = thread_instruction_count;
179 }
180
Eric Seckler7e9dc312020-01-02 15:17:28 +0000181 void OnPacketLoss() {
182 packet_loss_ = true;
183 track_event_timestamps_valid_ = false;
184 }
185
186 // Starts a new generation with clean-slate incremental state and defaults.
187 void OnIncrementalStateCleared() {
188 packet_loss_ = false;
Lalit Maganti9a843112020-11-10 13:39:05 +0000189 current_generation_.reset(
190 new PacketSequenceStateGeneration(this, generation_index_++));
Eric Seckler7e9dc312020-01-02 15:17:28 +0000191 }
192
Eric Seckler771960c2019-10-22 15:37:12 +0100193 bool IsIncrementalStateValid() const { return !packet_loss_; }
194
Florian Mayerab0c27a2020-08-12 17:42:49 +0100195 SequenceStackProfileTracker& sequence_stack_profile_tracker() {
196 return sequence_stack_profile_tracker_;
Eric Seckler771960c2019-10-22 15:37:12 +0100197 }
198
Lalit Maganti9a843112020-11-10 13:39:05 +0000199 // Returns a ref-counted ptr to the current generation.
200 std::shared_ptr<PacketSequenceStateGeneration> current_generation() const {
201 return current_generation_;
Eric Seckler7e9dc312020-01-02 15:17:28 +0000202 }
Eric Seckler771960c2019-10-22 15:37:12 +0100203
204 bool track_event_timestamps_valid() const {
205 return track_event_timestamps_valid_;
206 }
207
208 bool pid_and_tid_valid() const { return pid_and_tid_valid_; }
209
210 int32_t pid() const { return pid_; }
211 int32_t tid() const { return tid_; }
212
Eric Seckler7e9dc312020-01-02 15:17:28 +0000213 TraceProcessorContext* context() const { return context_; }
Eric Seckler1edbe002019-12-16 18:08:57 +0000214
Eric Seckler771960c2019-10-22 15:37:12 +0100215 private:
216 TraceProcessorContext* context_;
217
Lalit Maganti9a843112020-11-10 13:39:05 +0000218 size_t generation_index_ = 0;
219
Eric Seckler771960c2019-10-22 15:37:12 +0100220 // If true, incremental state on the sequence is considered invalid until we
221 // see the next packet with incremental_state_cleared. We assume that we
222 // missed some packets at the beginning of the trace.
223 bool packet_loss_ = true;
224
225 // We can only consider TrackEvent delta timestamps to be correct after we
226 // have observed a thread descriptor (since the last packet loss).
227 bool track_event_timestamps_valid_ = false;
228
229 // |pid_| and |tid_| are only valid after we parsed at least one
230 // ThreadDescriptor packet on the sequence.
231 bool pid_and_tid_valid_ = false;
232
233 // Process/thread ID of the packet sequence set by a ThreadDescriptor
234 // packet. Used as default values for TrackEvents that don't specify a
235 // pid/tid override. Only valid after |pid_and_tid_valid_| is set to true.
236 int32_t pid_ = 0;
237 int32_t tid_ = 0;
238
239 // Current wall/thread timestamps/counters used as reference for the next
240 // TrackEvent delta timestamp.
241 int64_t track_event_timestamp_ns_ = 0;
242 int64_t track_event_thread_timestamp_ns_ = 0;
243 int64_t track_event_thread_instruction_count_ = 0;
244
Lalit Maganti9a843112020-11-10 13:39:05 +0000245 std::shared_ptr<PacketSequenceStateGeneration> current_generation_;
Florian Mayerab0c27a2020-08-12 17:42:49 +0100246 SequenceStackProfileTracker sequence_stack_profile_tracker_;
Eric Seckler771960c2019-10-22 15:37:12 +0100247};
248
Florian Mayer2881d6b2021-01-12 17:53:53 +0000249template <uint32_t FieldId, typename MessageType>
250typename MessageType::Decoder*
251PacketSequenceStateGeneration::LookupInternedMessage(uint64_t iid) {
Alexander Timin99653b12021-05-11 22:50:00 +0000252 auto* interned_message_view = GetInternedMessageView(FieldId, iid);
Florian Mayer2881d6b2021-01-12 17:53:53 +0000253 if (!interned_message_view)
254 return nullptr;
255
256 return interned_message_view->template GetOrCreateDecoder<MessageType>();
257}
258
Eric Seckler771960c2019-10-22 15:37:12 +0100259} // namespace trace_processor
260} // namespace perfetto
261
262#endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PACKET_SEQUENCE_STATE_H_