blob: 303e2346931ced8f8af5724b06e7e388de5c9619 [file] [log] [blame]
Eric Seckler1a2ea132019-10-16 11:35:31 +01001/*
2 * Copyright (C) 2018 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_TIMESTAMPED_TRACE_PIECE_H_
18#define SRC_TRACE_PROCESSOR_TIMESTAMPED_TRACE_PIECE_H_
19
20#include "perfetto/base/build_config.h"
21#include "perfetto/trace_processor/basic_types.h"
Eric Seckler67e15a92020-01-03 13:20:46 +000022#include "src/trace_processor/importers/fuchsia/fuchsia_record.h"
Lalit Maganti0bfeb972020-03-14 03:57:30 +000023#include "src/trace_processor/importers/json/json_utils.h"
Eric Seckler771960c2019-10-22 15:37:12 +010024#include "src/trace_processor/importers/proto/packet_sequence_state.h"
Lalit Maganti31afb822020-03-05 17:36:57 +000025#include "src/trace_processor/importers/systrace/systrace_line.h"
Lalit Maganti7010b332020-02-07 10:51:15 +000026#include "src/trace_processor/storage/trace_storage.h"
Lalit Maganti0faddc42020-04-10 17:58:24 +010027#include "src/trace_processor/types/trace_processor_context.h"
Alexander Timin97d87852021-05-17 18:01:33 +000028#include "src/trace_processor/util/trace_blob_view.h"
Eric Seckler1a2ea132019-10-16 11:35:31 +010029
Eric Seckler67e15a92020-01-03 13:20:46 +000030// GCC can't figure out the relationship between TimestampedTracePiece's type
31// and the union, and thus thinks that we may be moving or destroying
32// uninitialized data in the move constructors / destructors. Disable those
33// warnings for TimestampedTracePiece and the types it contains.
34#if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
35#pragma GCC diagnostic push
36#pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
37#endif
38
Eric Seckler1a2ea132019-10-16 11:35:31 +010039namespace perfetto {
40namespace trace_processor {
41
42struct InlineSchedSwitch {
43 int64_t prev_state;
44 int32_t next_pid;
45 int32_t next_prio;
46 StringId next_comm;
47};
48
Ryan Savitskic53ec7e2019-11-07 17:04:50 +000049struct InlineSchedWaking {
50 int32_t pid;
51 int32_t target_cpu;
52 int32_t prio;
53 StringId comm;
54};
55
Eric Seckler67e15a92020-01-03 13:20:46 +000056struct TracePacketData {
57 TraceBlobView packet;
Lalit Maganti9a843112020-11-10 13:39:05 +000058 std::shared_ptr<PacketSequenceStateGeneration> sequence_state;
Lalit Maganti24305ca72020-10-15 17:18:32 +010059};
Eric Seckler1a2ea132019-10-16 11:35:31 +010060
Lalit Maganti24305ca72020-10-15 17:18:32 +010061struct FtraceEventData {
62 TraceBlobView event;
Lalit Maganti9a843112020-11-10 13:39:05 +000063 std::shared_ptr<PacketSequenceStateGeneration> sequence_state;
Eric Seckler67e15a92020-01-03 13:20:46 +000064};
Eric Seckler1a2ea132019-10-16 11:35:31 +010065
Eric Seckler67e15a92020-01-03 13:20:46 +000066struct TrackEventData : public TracePacketData {
Lalit Maganti9a843112020-11-10 13:39:05 +000067 TrackEventData(TraceBlobView pv,
68 std::shared_ptr<PacketSequenceStateGeneration> generation)
69 : TracePacketData{std::move(pv), std::move(generation)} {}
Ryan Savitskic53ec7e2019-11-07 17:04:50 +000070
Eric Secklerfbd9aed2020-03-10 18:07:38 +000071 static constexpr size_t kMaxNumExtraCounters = 8;
72
Stephen Nuskof848d462021-04-06 13:28:04 +010073 base::Optional<int64_t> thread_timestamp;
74 base::Optional<int64_t> thread_instruction_count;
Sami Kyostilab51e3802021-02-03 16:56:35 +000075 double counter_value = 0;
76 std::array<double, kMaxNumExtraCounters> extra_counter_values = {};
Eric Seckler1a2ea132019-10-16 11:35:31 +010077};
78
79// A TimestampedTracePiece is (usually a reference to) a piece of a trace that
80// is sorted by TraceSorter.
81struct TimestampedTracePiece {
Eric Seckler67e15a92020-01-03 13:20:46 +000082 enum class Type {
83 kInvalid = 0,
84 kFtraceEvent,
85 kTracePacket,
86 kInlineSchedSwitch,
87 kInlineSchedWaking,
88 kJsonValue,
89 kFuchsiaRecord,
Lalit Maganti31afb822020-03-05 17:36:57 +000090 kTrackEvent,
91 kSystraceLine,
Eric Seckler67e15a92020-01-03 13:20:46 +000092 };
93
Lalit Maganti9a843112020-11-10 13:39:05 +000094 TimestampedTracePiece(
95 int64_t ts,
96 uint64_t idx,
97 TraceBlobView tbv,
98 std::shared_ptr<PacketSequenceStateGeneration> sequence_state)
99 : packet_data{std::move(tbv), std::move(sequence_state)},
Eric Seckler67e15a92020-01-03 13:20:46 +0000100 timestamp(ts),
101 packet_idx(idx),
102 type(Type::kTracePacket) {}
Eric Seckler1a2ea132019-10-16 11:35:31 +0100103
Lalit Maganti24305ca72020-10-15 17:18:32 +0100104 TimestampedTracePiece(int64_t ts, uint64_t idx, FtraceEventData fed)
105 : ftrace_event(std::move(fed)),
Eric Seckler67e15a92020-01-03 13:20:46 +0000106 timestamp(ts),
107 packet_idx(idx),
108 type(Type::kFtraceEvent) {}
Eric Seckler1a2ea132019-10-16 11:35:31 +0100109
Lalit Maganti0732e002021-03-10 17:05:18 +0000110 TimestampedTracePiece(int64_t ts, uint64_t idx, std::string value)
Eric Seckler1a2ea132019-10-16 11:35:31 +0100111 : json_value(std::move(value)),
Eric Seckler1a2ea132019-10-16 11:35:31 +0100112 timestamp(ts),
Eric Seckler67e15a92020-01-03 13:20:46 +0000113 packet_idx(idx),
114 type(Type::kJsonValue) {}
Eric Seckler1a2ea132019-10-16 11:35:31 +0100115
Eric Seckler67e15a92020-01-03 13:20:46 +0000116 TimestampedTracePiece(int64_t ts,
117 uint64_t idx,
118 std::unique_ptr<FuchsiaRecord> fr)
119 : fuchsia_record(std::move(fr)),
120 timestamp(ts),
121 packet_idx(idx),
122 type(Type::kFuchsiaRecord) {}
123
124 TimestampedTracePiece(int64_t ts,
125 uint64_t idx,
126 std::unique_ptr<TrackEventData> ted)
127 : track_event_data(std::move(ted)),
128 timestamp(ts),
129 packet_idx(idx),
130 type(Type::kTrackEvent) {}
131
Lalit Maganti31afb822020-03-05 17:36:57 +0000132 TimestampedTracePiece(int64_t ts,
133 uint64_t idx,
134 std::unique_ptr<SystraceLine> ted)
135 : systrace_line(std::move(ted)),
136 timestamp(ts),
137 packet_idx(idx),
138 type(Type::kSystraceLine) {}
139
Eric Seckler67e15a92020-01-03 13:20:46 +0000140 TimestampedTracePiece(int64_t ts, uint64_t idx, InlineSchedSwitch iss)
141 : sched_switch(std::move(iss)),
142 timestamp(ts),
143 packet_idx(idx),
144 type(Type::kInlineSchedSwitch) {}
145
146 TimestampedTracePiece(int64_t ts, uint64_t idx, InlineSchedWaking isw)
147 : sched_waking(std::move(isw)),
148 timestamp(ts),
149 packet_idx(idx),
150 type(Type::kInlineSchedWaking) {}
151
152 TimestampedTracePiece(TimestampedTracePiece&& ttp) noexcept {
153 // Adopt |ttp|'s data. We have to use placement-new to fill the fields
154 // because their original values may be uninitialized and thus
155 // move-assignment won't work correctly.
156 switch (ttp.type) {
157 case Type::kInvalid:
158 break;
159 case Type::kFtraceEvent:
Lalit Maganti24305ca72020-10-15 17:18:32 +0100160 new (&ftrace_event) FtraceEventData(std::move(ttp.ftrace_event));
Eric Seckler67e15a92020-01-03 13:20:46 +0000161 break;
162 case Type::kTracePacket:
163 new (&packet_data) TracePacketData(std::move(ttp.packet_data));
164 break;
165 case Type::kInlineSchedSwitch:
166 new (&sched_switch) InlineSchedSwitch(std::move(ttp.sched_switch));
167 break;
168 case Type::kInlineSchedWaking:
169 new (&sched_waking) InlineSchedWaking(std::move(ttp.sched_waking));
170 break;
171 case Type::kJsonValue:
Lalit Maganti0732e002021-03-10 17:05:18 +0000172 new (&json_value) std::string(std::move(ttp.json_value));
Eric Seckler67e15a92020-01-03 13:20:46 +0000173 break;
174 case Type::kFuchsiaRecord:
175 new (&fuchsia_record)
176 std::unique_ptr<FuchsiaRecord>(std::move(ttp.fuchsia_record));
177 break;
178 case Type::kTrackEvent:
179 new (&track_event_data)
180 std::unique_ptr<TrackEventData>(std::move(ttp.track_event_data));
181 break;
Lalit Maganti31afb822020-03-05 17:36:57 +0000182 case Type::kSystraceLine:
183 new (&systrace_line)
184 std::unique_ptr<SystraceLine>(std::move(ttp.systrace_line));
Eric Seckler67e15a92020-01-03 13:20:46 +0000185 }
186 timestamp = ttp.timestamp;
187 packet_idx = ttp.packet_idx;
188 type = ttp.type;
189
190 // Invalidate |ttp|.
191 ttp.type = Type::kInvalid;
192 }
193
194 TimestampedTracePiece& operator=(TimestampedTracePiece&& ttp) {
195 if (this != &ttp) {
196 // First invoke the destructor and then invoke the move constructor
197 // inline via placement-new to implement move-assignment.
198 this->~TimestampedTracePiece();
199 new (this) TimestampedTracePiece(std::move(ttp));
200 }
201 return *this;
202 }
203
Lalit Magantic81e8042020-04-07 21:13:02 +0100204 TimestampedTracePiece(const TimestampedTracePiece&) = delete;
205 TimestampedTracePiece& operator=(const TimestampedTracePiece&) = delete;
206
Eric Seckler67e15a92020-01-03 13:20:46 +0000207 ~TimestampedTracePiece() {
208 switch (type) {
209 case Type::kInvalid:
210 case Type::kInlineSchedSwitch:
211 case Type::kInlineSchedWaking:
212 break;
213 case Type::kFtraceEvent:
Lalit Maganti24305ca72020-10-15 17:18:32 +0100214 ftrace_event.~FtraceEventData();
Eric Seckler67e15a92020-01-03 13:20:46 +0000215 break;
216 case Type::kTracePacket:
217 packet_data.~TracePacketData();
218 break;
219 case Type::kJsonValue:
Lalit Maganti0732e002021-03-10 17:05:18 +0000220 json_value.~basic_string();
Eric Seckler67e15a92020-01-03 13:20:46 +0000221 break;
222 case Type::kFuchsiaRecord:
223 fuchsia_record.~unique_ptr();
224 break;
225 case Type::kTrackEvent:
226 track_event_data.~unique_ptr();
227 break;
Lalit Maganti31afb822020-03-05 17:36:57 +0000228 case Type::kSystraceLine:
229 systrace_line.~unique_ptr();
230 break;
Eric Seckler67e15a92020-01-03 13:20:46 +0000231 }
232 }
Eric Seckler1a2ea132019-10-16 11:35:31 +0100233
234 // For std::lower_bound().
235 static inline bool Compare(const TimestampedTracePiece& x, int64_t ts) {
236 return x.timestamp < ts;
237 }
238
239 // For std::sort().
240 inline bool operator<(const TimestampedTracePiece& o) const {
241 return timestamp < o.timestamp ||
Eric Seckler67e15a92020-01-03 13:20:46 +0000242 (timestamp == o.timestamp && packet_idx < o.packet_idx);
Eric Seckler1a2ea132019-10-16 11:35:31 +0100243 }
244
Eric Seckler67e15a92020-01-03 13:20:46 +0000245 // Fields ordered for packing.
246
247 // Data for different types of TimestampedTracePiece.
248 union {
Lalit Maganti24305ca72020-10-15 17:18:32 +0100249 FtraceEventData ftrace_event;
Eric Seckler67e15a92020-01-03 13:20:46 +0000250 TracePacketData packet_data;
251 InlineSchedSwitch sched_switch;
252 InlineSchedWaking sched_waking;
Lalit Maganti0732e002021-03-10 17:05:18 +0000253 std::string json_value;
Eric Seckler67e15a92020-01-03 13:20:46 +0000254 std::unique_ptr<FuchsiaRecord> fuchsia_record;
255 std::unique_ptr<TrackEventData> track_event_data;
Lalit Maganti31afb822020-03-05 17:36:57 +0000256 std::unique_ptr<SystraceLine> systrace_line;
Eric Seckler67e15a92020-01-03 13:20:46 +0000257 };
Eric Seckler1a2ea132019-10-16 11:35:31 +0100258
259 int64_t timestamp;
Eric Seckler67e15a92020-01-03 13:20:46 +0000260 uint64_t packet_idx;
261 Type type;
Eric Seckler1a2ea132019-10-16 11:35:31 +0100262};
263
264} // namespace trace_processor
265} // namespace perfetto
266
Eric Seckler67e15a92020-01-03 13:20:46 +0000267#if PERFETTO_BUILDFLAG(PERFETTO_COMPILER_GCC)
268#pragma GCC diagnostic pop
269#endif
270
Eric Seckler1a2ea132019-10-16 11:35:31 +0100271#endif // SRC_TRACE_PROCESSOR_TIMESTAMPED_TRACE_PIECE_H_