blob: b68881424b68bd1adccb649324690215d80d6c13 [file] [log] [blame]
Lalit Maganticaed37e2018-06-01 03:03:08 +01001/*
2 * Copyright (C) 2017 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_TRACE_STORAGE_H_
18#define SRC_TRACE_PROCESSOR_TRACE_STORAGE_H_
19
Lalit Maganti35622b72018-06-06 12:03:11 +010020#include <array>
Lalit Maganticaed37e2018-06-01 03:03:08 +010021#include <deque>
Isabelle Taylor47328cf2018-06-12 14:33:59 +010022#include <map>
Lalit Maganticaed37e2018-06-01 03:03:08 +010023#include <string>
24#include <unordered_map>
25#include <vector>
26
Lalit Maganti35622b72018-06-06 12:03:11 +010027#include "perfetto/base/logging.h"
Lalit Maganti770886a2018-11-16 17:40:21 +000028#include "perfetto/base/optional.h"
Primiano Tucci2da5d2e2018-08-10 14:23:31 +010029#include "perfetto/base/string_view.h"
Hector Dearmanc8339932018-08-10 11:22:46 +010030#include "perfetto/base/utils.h"
Lalit Magantib0b53ee2019-01-24 17:53:39 +000031#include "src/trace_processor/ftrace_utils.h"
Primiano Tucci0e38a142019-01-07 20:51:09 +000032#include "src/trace_processor/stats.h"
Lalit Maganti35622b72018-06-06 12:03:11 +010033
Lalit Maganticaed37e2018-06-01 03:03:08 +010034namespace perfetto {
35namespace trace_processor {
36
Isabelle Taylora0a22972018-08-03 12:06:12 +010037// UniquePid is an offset into |unique_processes_|. This is necessary because
38// Unix pids are reused and thus not guaranteed to be unique over a long
39// period of time.
40using UniquePid = uint32_t;
Primiano Tucci0d72a312018-08-07 14:42:45 +010041
Isabelle Taylora0a22972018-08-03 12:06:12 +010042// UniqueTid is an offset into |unique_threads_|. Necessary because tids can
43// be reused.
44using UniqueTid = uint32_t;
45
Primiano Tucci0d72a312018-08-07 14:42:45 +010046// StringId is an offset into |string_pool_|.
Lalit Maganti85ca4a82018-12-07 17:28:02 +000047using StringId = uint32_t;
Primiano Tucci0d72a312018-08-07 14:42:45 +010048
Lalit Maganti5ea9e932018-11-30 14:19:39 +000049// Identifiers for all the tables in the database.
50enum TableId : uint8_t {
51 // Intentionally don't have TableId == 0 so that RowId == 0 can refer to an
52 // invalid row id.
53 kCounters = 1,
Lalit Maganti1d915a62019-01-07 12:10:42 +000054 kRawEvents = 2,
Lalit Maganti66ed7ad2019-01-11 16:47:26 +000055 kInstants = 3,
Lalit Maganti5ea9e932018-11-30 14:19:39 +000056};
57
58// The top 8 bits are set to the TableId and the bottom 32 to the row of the
59// table.
Lalit Maganti85ca4a82018-12-07 17:28:02 +000060using RowId = int64_t;
Lalit Maganti5ea9e932018-11-30 14:19:39 +000061
62static const RowId kInvalidRowId = 0;
63
Isabelle Taylora97c5f52018-10-23 17:36:12 +010064enum RefType {
Primiano Tucci5403e4f2018-11-27 10:07:03 +000065 kRefNoRef = 0,
66 kRefUtid = 1,
67 kRefCpuId = 2,
68 kRefIrq = 3,
69 kRefSoftIrq = 4,
70 kRefUpid = 5,
71 kRefUtidLookupUpid = 6,
72 kRefMax
Isabelle Taylora97c5f52018-10-23 17:36:12 +010073};
Isabelle Taylor14674d42018-09-07 11:33:11 +010074
Lalit Maganticaed37e2018-06-01 03:03:08 +010075// Stores a data inside a trace file in a columnar form. This makes it efficient
76// to read or search across a single field of the trace (e.g. all the thread
77// names for a given CPU).
78class TraceStorage {
79 public:
Isabelle Taylor47328cf2018-06-12 14:33:59 +010080 TraceStorage();
Isabelle Taylora0a22972018-08-03 12:06:12 +010081 TraceStorage(const TraceStorage&) = delete;
82
83 virtual ~TraceStorage();
Isabelle Taylor47328cf2018-06-12 14:33:59 +010084
Isabelle Taylora0a22972018-08-03 12:06:12 +010085 // Information about a unique process seen in a trace.
86 struct Process {
Primiano Tuccib75dcee2018-08-08 12:21:36 +010087 explicit Process(uint32_t p) : pid(p) {}
Lalit Maganti85ca4a82018-12-07 17:28:02 +000088 int64_t start_ns = 0;
89 int64_t end_ns = 0;
Isabelle Taylora0a22972018-08-03 12:06:12 +010090 StringId name_id = 0;
Primiano Tuccib75dcee2018-08-08 12:21:36 +010091 uint32_t pid = 0;
Isabelle Taylora0a22972018-08-03 12:06:12 +010092 };
93
94 // Information about a unique thread seen in a trace.
95 struct Thread {
Primiano Tuccib75dcee2018-08-08 12:21:36 +010096 explicit Thread(uint32_t t) : tid(t) {}
Lalit Maganti85ca4a82018-12-07 17:28:02 +000097 int64_t start_ns = 0;
98 int64_t end_ns = 0;
Isabelle Taylora0a22972018-08-03 12:06:12 +010099 StringId name_id = 0;
Lalit Maganti770886a2018-11-16 17:40:21 +0000100 base::Optional<UniquePid> upid;
Primiano Tuccib75dcee2018-08-08 12:21:36 +0100101 uint32_t tid = 0;
Isabelle Taylora0a22972018-08-03 12:06:12 +0100102 };
Isabelle Taylor3dd366c2018-06-22 16:21:41 +0100103
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000104 // Generic key value storage which can be referenced by other tables.
105 class Args {
106 public:
Lalit Maganti1d915a62019-01-07 12:10:42 +0000107 // Variadic type representing the possible values for the args table.
108 struct Variadic {
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000109 enum Type { kInt, kString, kReal };
110
Lalit Maganti1d915a62019-01-07 12:10:42 +0000111 static Variadic Integer(int64_t int_value) {
112 Variadic variadic;
113 variadic.type = Type::kInt;
114 variadic.int_value = int_value;
115 return variadic;
116 }
117
118 static Variadic String(StringId string_id) {
119 Variadic variadic;
120 variadic.type = Type::kString;
121 variadic.string_value = string_id;
122 return variadic;
123 }
124
125 static Variadic Real(double real_value) {
126 Variadic variadic;
127 variadic.type = Type::kReal;
128 variadic.real_value = real_value;
129 return variadic;
130 }
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000131
132 Type type;
133 union {
134 int64_t int_value;
135 StringId string_value;
136 double real_value;
137 };
138 };
139
Lalit Maganti5ea9e932018-11-30 14:19:39 +0000140 const std::deque<RowId>& ids() const { return ids_; }
141 const std::deque<StringId>& flat_keys() const { return flat_keys_; }
142 const std::deque<StringId>& keys() const { return keys_; }
Lalit Maganti1d915a62019-01-07 12:10:42 +0000143 const std::deque<Variadic>& arg_values() const { return arg_values_; }
Lalit Maganti79472be2018-12-04 13:41:27 +0000144 const std::multimap<RowId, uint32_t>& args_for_id() const {
145 return args_for_id_;
146 }
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000147 size_t args_count() const { return ids_.size(); }
148
Lalit Maganti1d915a62019-01-07 12:10:42 +0000149 void AddArg(RowId id, StringId flat_key, StringId key, Variadic value) {
Lalit Maganticc674222019-01-23 17:54:00 +0000150 // TODO(b/123252504): disable this code to stop blow-ups in ingestion time
151 // and memory.
152 perfetto::base::ignore_result(id);
153 perfetto::base::ignore_result(flat_key);
154 perfetto::base::ignore_result(key);
155 perfetto::base::ignore_result(value);
156 /*
Lalit Maganti5ea9e932018-11-30 14:19:39 +0000157 if (id == kInvalidRowId)
158 return;
159
160 ids_.emplace_back(id);
161 flat_keys_.emplace_back(flat_key);
162 keys_.emplace_back(key);
163 arg_values_.emplace_back(value);
Lalit Maganti79472be2018-12-04 13:41:27 +0000164 args_for_id_.emplace(id, static_cast<uint32_t>(args_count() - 1));
Lalit Maganticc674222019-01-23 17:54:00 +0000165 */
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000166 }
167
Lalit Maganti5ea9e932018-11-30 14:19:39 +0000168 private:
169 std::deque<RowId> ids_;
170 std::deque<StringId> flat_keys_;
171 std::deque<StringId> keys_;
Lalit Maganti1d915a62019-01-07 12:10:42 +0000172 std::deque<Variadic> arg_values_;
Lalit Maganti79472be2018-12-04 13:41:27 +0000173 std::multimap<RowId, uint32_t> args_for_id_;
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000174 };
175
Lalit Magantiff69c112018-09-24 12:07:47 +0100176 class Slices {
Lalit Maganti35622b72018-06-06 12:03:11 +0100177 public:
Lalit Magantifde29042018-10-04 13:28:52 +0100178 inline size_t AddSlice(uint32_t cpu,
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000179 int64_t start_ns,
180 int64_t duration_ns,
Lalit Magantib0b53ee2019-01-24 17:53:39 +0000181 UniqueTid utid,
182 ftrace_utils::TaskState end_state,
183 int32_t priority) {
Lalit Magantiff69c112018-09-24 12:07:47 +0100184 cpus_.emplace_back(cpu);
Lalit Maganti35622b72018-06-06 12:03:11 +0100185 start_ns_.emplace_back(start_ns);
186 durations_.emplace_back(duration_ns);
Isabelle Taylora0a22972018-08-03 12:06:12 +0100187 utids_.emplace_back(utid);
Lalit Magantib0b53ee2019-01-24 17:53:39 +0000188 end_states_.emplace_back(end_state);
189 priorities_.emplace_back(priority);
Lalit Magantif0f09c32019-01-18 17:29:31 +0000190 rows_for_utids_.emplace(utid, slice_count() - 1);
Lalit Magantifde29042018-10-04 13:28:52 +0100191 return slice_count() - 1;
192 }
193
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000194 void set_duration(size_t index, int64_t duration_ns) {
Lalit Magantifde29042018-10-04 13:28:52 +0100195 durations_[index] = duration_ns;
Lalit Maganti35622b72018-06-06 12:03:11 +0100196 }
197
Lalit Magantib0b53ee2019-01-24 17:53:39 +0000198 void set_end_state(size_t index, ftrace_utils::TaskState end_state) {
199 end_states_[index] = end_state;
200 }
201
Isabelle Taylor47328cf2018-06-12 14:33:59 +0100202 size_t slice_count() const { return start_ns_.size(); }
Lalit Maganti35622b72018-06-06 12:03:11 +0100203
Lalit Magantiff69c112018-09-24 12:07:47 +0100204 const std::deque<uint32_t>& cpus() const { return cpus_; }
205
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000206 const std::deque<int64_t>& start_ns() const { return start_ns_; }
Lalit Maganti35622b72018-06-06 12:03:11 +0100207
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000208 const std::deque<int64_t>& durations() const { return durations_; }
Lalit Maganti35622b72018-06-06 12:03:11 +0100209
Isabelle Taylor68e42192018-06-19 16:19:31 +0100210 const std::deque<UniqueTid>& utids() const { return utids_; }
211
Lalit Magantib0b53ee2019-01-24 17:53:39 +0000212 const std::deque<ftrace_utils::TaskState>& end_state() const {
213 return end_states_;
214 }
215
216 const std::deque<int32_t>& priorities() const { return priorities_; }
217
Lalit Magantif0f09c32019-01-18 17:29:31 +0000218 const std::multimap<UniqueTid, uint32_t>& rows_for_utids() const {
219 return rows_for_utids_;
220 }
221
Lalit Maganti35622b72018-06-06 12:03:11 +0100222 private:
Hector Dearman947f12a2018-09-11 16:50:36 +0100223 // Each deque below has the same number of entries (the number of slices
Lalit Maganti35622b72018-06-06 12:03:11 +0100224 // in the trace for the CPU).
Lalit Magantiff69c112018-09-24 12:07:47 +0100225 std::deque<uint32_t> cpus_;
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000226 std::deque<int64_t> start_ns_;
227 std::deque<int64_t> durations_;
Isabelle Taylor68e42192018-06-19 16:19:31 +0100228 std::deque<UniqueTid> utids_;
Lalit Magantib0b53ee2019-01-24 17:53:39 +0000229 std::deque<ftrace_utils::TaskState> end_states_;
230 std::deque<int32_t> priorities_;
Lalit Magantif0f09c32019-01-18 17:29:31 +0000231 std::multimap<UniqueTid, uint32_t> rows_for_utids_;
Primiano Tucci0d72a312018-08-07 14:42:45 +0100232 };
Isabelle Taylor68e42192018-06-19 16:19:31 +0100233
Primiano Tucci0d72a312018-08-07 14:42:45 +0100234 class NestableSlices {
235 public:
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000236 inline size_t AddSlice(int64_t start_ns,
237 int64_t duration_ns,
Lalit Maganti7b37bbf2018-11-09 15:58:54 +0000238 UniqueTid utid,
239 StringId cat,
240 StringId name,
241 uint8_t depth,
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000242 int64_t stack_id,
243 int64_t parent_stack_id) {
Primiano Tucci0d72a312018-08-07 14:42:45 +0100244 start_ns_.emplace_back(start_ns);
245 durations_.emplace_back(duration_ns);
246 utids_.emplace_back(utid);
247 cats_.emplace_back(cat);
248 names_.emplace_back(name);
249 depths_.emplace_back(depth);
Primiano Tuccib75dcee2018-08-08 12:21:36 +0100250 stack_ids_.emplace_back(stack_id);
251 parent_stack_ids_.emplace_back(parent_stack_id);
Lalit Maganti7b37bbf2018-11-09 15:58:54 +0000252 return slice_count() - 1;
253 }
254
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000255 void set_duration(size_t index, int64_t duration_ns) {
Lalit Maganti7b37bbf2018-11-09 15:58:54 +0000256 durations_[index] = duration_ns;
257 }
258
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000259 void set_stack_id(size_t index, int64_t stack_id) {
Lalit Maganti7b37bbf2018-11-09 15:58:54 +0000260 stack_ids_[index] = stack_id;
Primiano Tucci0d72a312018-08-07 14:42:45 +0100261 }
262
263 size_t slice_count() const { return start_ns_.size(); }
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000264 const std::deque<int64_t>& start_ns() const { return start_ns_; }
265 const std::deque<int64_t>& durations() const { return durations_; }
Primiano Tucci0d72a312018-08-07 14:42:45 +0100266 const std::deque<UniqueTid>& utids() const { return utids_; }
267 const std::deque<StringId>& cats() const { return cats_; }
268 const std::deque<StringId>& names() const { return names_; }
269 const std::deque<uint8_t>& depths() const { return depths_; }
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000270 const std::deque<int64_t>& stack_ids() const { return stack_ids_; }
271 const std::deque<int64_t>& parent_stack_ids() const {
Primiano Tuccib75dcee2018-08-08 12:21:36 +0100272 return parent_stack_ids_;
273 }
Primiano Tucci0d72a312018-08-07 14:42:45 +0100274
275 private:
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000276 std::deque<int64_t> start_ns_;
277 std::deque<int64_t> durations_;
Primiano Tucci0d72a312018-08-07 14:42:45 +0100278 std::deque<UniqueTid> utids_;
279 std::deque<StringId> cats_;
280 std::deque<StringId> names_;
281 std::deque<uint8_t> depths_;
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000282 std::deque<int64_t> stack_ids_;
283 std::deque<int64_t> parent_stack_ids_;
Lalit Maganti35622b72018-06-06 12:03:11 +0100284 };
285
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100286 class Counters {
287 public:
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000288 inline size_t AddCounter(int64_t timestamp,
289 int64_t duration,
Lalit Magantifde29042018-10-04 13:28:52 +0100290 StringId name_id,
291 double value,
Lalit Magantifde29042018-10-04 13:28:52 +0100292 int64_t ref,
293 RefType type) {
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100294 timestamps_.emplace_back(timestamp);
295 durations_.emplace_back(duration);
296 name_ids_.emplace_back(name_id);
297 values_.emplace_back(value);
298 refs_.emplace_back(ref);
299 types_.emplace_back(type);
Lalit Magantifde29042018-10-04 13:28:52 +0100300 return counter_count() - 1;
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100301 }
Lalit Magantifde29042018-10-04 13:28:52 +0100302
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000303 void set_duration(size_t index, int64_t duration) {
Lalit Magantifde29042018-10-04 13:28:52 +0100304 durations_[index] = duration;
305 }
306
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100307 size_t counter_count() const { return timestamps_.size(); }
308
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000309 const std::deque<int64_t>& timestamps() const { return timestamps_; }
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100310
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000311 const std::deque<int64_t>& durations() const { return durations_; }
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100312
313 const std::deque<StringId>& name_ids() const { return name_ids_; }
314
315 const std::deque<double>& values() const { return values_; }
316
317 const std::deque<int64_t>& refs() const { return refs_; }
318
319 const std::deque<RefType>& types() const { return types_; }
320
321 private:
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000322 std::deque<int64_t> timestamps_;
323 std::deque<int64_t> durations_;
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100324 std::deque<StringId> name_ids_;
325 std::deque<double> values_;
326 std::deque<int64_t> refs_;
327 std::deque<RefType> types_;
328 };
329
Primiano Tucci5cb84f82018-10-31 21:46:36 -0700330 class SqlStats {
331 public:
332 static constexpr size_t kMaxLogEntries = 100;
333 void RecordQueryBegin(const std::string& query,
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000334 int64_t time_queued,
335 int64_t time_started);
336 void RecordQueryEnd(int64_t time_ended);
Primiano Tucci5cb84f82018-10-31 21:46:36 -0700337 size_t size() const { return queries_.size(); }
338 const std::deque<std::string>& queries() const { return queries_; }
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000339 const std::deque<int64_t>& times_queued() const { return times_queued_; }
340 const std::deque<int64_t>& times_started() const { return times_started_; }
341 const std::deque<int64_t>& times_ended() const { return times_ended_; }
Primiano Tucci5cb84f82018-10-31 21:46:36 -0700342
343 private:
344 std::deque<std::string> queries_;
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000345 std::deque<int64_t> times_queued_;
346 std::deque<int64_t> times_started_;
347 std::deque<int64_t> times_ended_;
Primiano Tucci5cb84f82018-10-31 21:46:36 -0700348 };
349
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000350 class Instants {
351 public:
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000352 inline uint32_t AddInstantEvent(int64_t timestamp,
353 StringId name_id,
354 double value,
355 int64_t ref,
356 RefType type) {
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000357 timestamps_.emplace_back(timestamp);
358 name_ids_.emplace_back(name_id);
359 values_.emplace_back(value);
360 refs_.emplace_back(ref);
361 types_.emplace_back(type);
Lalit Maganti66ed7ad2019-01-11 16:47:26 +0000362 return static_cast<uint32_t>(instant_count() - 1);
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000363 }
364
365 size_t instant_count() const { return timestamps_.size(); }
366
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000367 const std::deque<int64_t>& timestamps() const { return timestamps_; }
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000368
369 const std::deque<StringId>& name_ids() const { return name_ids_; }
370
371 const std::deque<double>& values() const { return values_; }
372
373 const std::deque<int64_t>& refs() const { return refs_; }
374
375 const std::deque<RefType>& types() const { return types_; }
376
377 private:
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000378 std::deque<int64_t> timestamps_;
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000379 std::deque<StringId> name_ids_;
380 std::deque<double> values_;
381 std::deque<int64_t> refs_;
382 std::deque<RefType> types_;
383 };
384
Lalit Maganti1d915a62019-01-07 12:10:42 +0000385 class RawEvents {
386 public:
387 inline RowId AddRawEvent(int64_t timestamp,
388 StringId name_id,
Lalit Magantie87cc812019-01-10 15:20:06 +0000389 uint32_t cpu,
Lalit Maganti1d915a62019-01-07 12:10:42 +0000390 UniqueTid utid) {
391 timestamps_.emplace_back(timestamp);
392 name_ids_.emplace_back(name_id);
Lalit Magantie87cc812019-01-10 15:20:06 +0000393 cpus_.emplace_back(cpu);
Lalit Maganti1d915a62019-01-07 12:10:42 +0000394 utids_.emplace_back(utid);
395 return CreateRowId(TableId::kRawEvents,
396 static_cast<uint32_t>(raw_event_count() - 1));
397 }
398
399 size_t raw_event_count() const { return timestamps_.size(); }
400
401 const std::deque<int64_t>& timestamps() const { return timestamps_; }
402
403 const std::deque<StringId>& name_ids() const { return name_ids_; }
404
Lalit Magantie87cc812019-01-10 15:20:06 +0000405 const std::deque<uint32_t>& cpus() const { return cpus_; }
406
Lalit Maganti1d915a62019-01-07 12:10:42 +0000407 const std::deque<UniqueTid>& utids() const { return utids_; }
408
409 private:
410 std::deque<int64_t> timestamps_;
411 std::deque<StringId> name_ids_;
Lalit Magantie87cc812019-01-10 15:20:06 +0000412 std::deque<uint32_t> cpus_;
Lalit Maganti1d915a62019-01-07 12:10:42 +0000413 std::deque<UniqueTid> utids_;
414 };
415
Primiano Tucci2c761ef2019-01-07 20:20:46 +0000416 class AndroidLogs {
417 public:
418 inline size_t AddLogEvent(int64_t timestamp,
419 UniqueTid utid,
420 uint8_t prio,
421 StringId tag_id,
422 StringId msg_id) {
423 timestamps_.emplace_back(timestamp);
424 utids_.emplace_back(utid);
425 prios_.emplace_back(prio);
426 tag_ids_.emplace_back(tag_id);
427 msg_ids_.emplace_back(msg_id);
428 return size() - 1;
429 }
430
431 size_t size() const { return timestamps_.size(); }
432
433 const std::deque<int64_t>& timestamps() const { return timestamps_; }
434 const std::deque<UniqueTid>& utids() const { return utids_; }
435 const std::deque<uint8_t>& prios() const { return prios_; }
436 const std::deque<StringId>& tag_ids() const { return tag_ids_; }
437 const std::deque<StringId>& msg_ids() const { return msg_ids_; }
438
439 private:
440 std::deque<int64_t> timestamps_;
441 std::deque<UniqueTid> utids_;
442 std::deque<uint8_t> prios_;
443 std::deque<StringId> tag_ids_;
444 std::deque<StringId> msg_ids_;
445 };
446
Primiano Tucci0e38a142019-01-07 20:51:09 +0000447 struct Stats {
448 using IndexMap = std::map<int, int64_t>;
449 int64_t value = 0;
450 IndexMap indexed_values;
451 };
452 using StatsMap = std::array<Stats, stats::kNumKeys>;
453
Isabelle Taylora0a22972018-08-03 12:06:12 +0100454 void ResetStorage();
Lalit Maganti35622b72018-06-06 12:03:11 +0100455
Primiano Tuccib75dcee2018-08-08 12:21:36 +0100456 UniqueTid AddEmptyThread(uint32_t tid) {
457 unique_threads_.emplace_back(tid);
Isabelle Taylora0a22972018-08-03 12:06:12 +0100458 return static_cast<UniqueTid>(unique_threads_.size() - 1);
459 }
Isabelle Taylor47328cf2018-06-12 14:33:59 +0100460
Primiano Tuccib75dcee2018-08-08 12:21:36 +0100461 UniquePid AddEmptyProcess(uint32_t pid) {
462 unique_processes_.emplace_back(pid);
Isabelle Taylora0a22972018-08-03 12:06:12 +0100463 return static_cast<UniquePid>(unique_processes_.size() - 1);
464 }
Isabelle Taylor3dd366c2018-06-22 16:21:41 +0100465
Isabelle Taylora0a22972018-08-03 12:06:12 +0100466 // Return an unqiue identifier for the contents of each string.
467 // The string is copied internally and can be destroyed after this called.
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100468 // Virtual for testing.
469 virtual StringId InternString(base::StringView);
Isabelle Taylor47328cf2018-06-12 14:33:59 +0100470
Isabelle Taylora0a22972018-08-03 12:06:12 +0100471 Process* GetMutableProcess(UniquePid upid) {
Lalit Maganti676658b2018-11-20 18:24:31 +0000472 PERFETTO_DCHECK(upid < unique_processes_.size());
Isabelle Taylora0a22972018-08-03 12:06:12 +0100473 return &unique_processes_[upid];
474 }
Isabelle Taylor3dd366c2018-06-22 16:21:41 +0100475
Isabelle Taylora0a22972018-08-03 12:06:12 +0100476 Thread* GetMutableThread(UniqueTid utid) {
Florian Mayera1aaec22018-09-19 17:02:26 +0100477 PERFETTO_DCHECK(utid < unique_threads_.size());
Isabelle Taylora0a22972018-08-03 12:06:12 +0100478 return &unique_threads_[utid];
479 }
Isabelle Taylor3dd366c2018-06-22 16:21:41 +0100480
Primiano Tucci0e38a142019-01-07 20:51:09 +0000481 // Example usage: SetStats(stats::android_log_num_failed, 42);
482 void SetStats(size_t key, int64_t value) {
483 PERFETTO_DCHECK(key < stats::kNumKeys);
484 PERFETTO_DCHECK(stats::kTypes[key] == stats::kSingle);
485 stats_[key].value = value;
486 }
487
488 // Example usage: IncrementStats(stats::android_log_num_failed, -1);
489 void IncrementStats(size_t key, int64_t increment = 1) {
490 PERFETTO_DCHECK(key < stats::kNumKeys);
491 PERFETTO_DCHECK(stats::kTypes[key] == stats::kSingle);
492 stats_[key].value += increment;
493 }
494
495 // Example usage: SetIndexedStats(stats::cpu_failure, 1, 42);
496 void SetIndexedStats(size_t key, int index, int64_t value) {
497 PERFETTO_DCHECK(key < stats::kNumKeys);
498 PERFETTO_DCHECK(stats::kTypes[key] == stats::kIndexed);
499 stats_[key].indexed_values[index] = value;
500 }
501
Lalit Maganticaed37e2018-06-01 03:03:08 +0100502 // Reading methods.
Isabelle Taylora0a22972018-08-03 12:06:12 +0100503 const std::string& GetString(StringId id) const {
504 PERFETTO_DCHECK(id < string_pool_.size());
505 return string_pool_[id];
506 }
507
Lalit Magantie9d40532018-06-29 13:15:06 +0100508 const Process& GetProcess(UniquePid upid) const {
Lalit Maganti676658b2018-11-20 18:24:31 +0000509 PERFETTO_DCHECK(upid < unique_processes_.size());
Isabelle Taylor47328cf2018-06-12 14:33:59 +0100510 return unique_processes_[upid];
511 }
512
Lalit Magantie9d40532018-06-29 13:15:06 +0100513 const Thread& GetThread(UniqueTid utid) const {
Lalit Maganti1f64cfa2018-09-18 13:20:02 +0100514 // Allow utid == 0 for idle thread retrieval.
Florian Mayera1aaec22018-09-19 17:02:26 +0100515 PERFETTO_DCHECK(utid < unique_threads_.size());
Isabelle Taylor68e42192018-06-19 16:19:31 +0100516 return unique_threads_[utid];
517 }
518
Lalit Maganti5ea9e932018-11-30 14:19:39 +0000519 static RowId CreateRowId(TableId table, uint32_t row) {
520 static constexpr uint8_t kRowIdTableShift = 32;
Lalit Maganti85ca4a82018-12-07 17:28:02 +0000521 return (static_cast<RowId>(table) << kRowIdTableShift) | row;
Lalit Maganti5ea9e932018-11-30 14:19:39 +0000522 }
523
Lalit Magantiff69c112018-09-24 12:07:47 +0100524 const Slices& slices() const { return slices_; }
Lalit Magantifde29042018-10-04 13:28:52 +0100525 Slices* mutable_slices() { return &slices_; }
526
Primiano Tucci0d72a312018-08-07 14:42:45 +0100527 const NestableSlices& nestable_slices() const { return nestable_slices_; }
528 NestableSlices* mutable_nestable_slices() { return &nestable_slices_; }
529
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100530 const Counters& counters() const { return counters_; }
531 Counters* mutable_counters() { return &counters_; }
Isabelle Taylor14674d42018-09-07 11:33:11 +0100532
Primiano Tucci5cb84f82018-10-31 21:46:36 -0700533 const SqlStats& sql_stats() const { return sql_stats_; }
534 SqlStats* mutable_sql_stats() { return &sql_stats_; }
535
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000536 const Instants& instants() const { return instants_; }
537 Instants* mutable_instants() { return &instants_; }
538
Primiano Tucci2c761ef2019-01-07 20:20:46 +0000539 const AndroidLogs& android_logs() const { return android_log_; }
540 AndroidLogs* mutable_android_log() { return &android_log_; }
541
Primiano Tucci0e38a142019-01-07 20:51:09 +0000542 const StatsMap& stats() const { return stats_; }
Lalit Maganti05e8c132018-11-09 18:16:12 +0000543
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000544 const Args& args() const { return args_; }
545 Args* mutable_args() { return &args_; }
546
Lalit Maganti1d915a62019-01-07 12:10:42 +0000547 const RawEvents& raw_events() const { return raw_events_; }
548 RawEvents* mutable_raw_events() { return &raw_events_; }
549
Lalit Magantiacda68b2018-10-29 15:23:25 +0000550 const std::deque<std::string>& string_pool() const { return string_pool_; }
551
Isabelle Taylore7003fb2018-07-17 11:39:01 +0100552 // |unique_processes_| always contains at least 1 element becuase the 0th ID
553 // is reserved to indicate an invalid process.
Lalit Maganti9c6395b2019-01-17 00:25:09 +0000554 size_t process_count() const { return unique_processes_.size(); }
Primiano Tucci0d72a312018-08-07 14:42:45 +0100555
Isabelle Taylore7003fb2018-07-17 11:39:01 +0100556 // |unique_threads_| always contains at least 1 element becuase the 0th ID
557 // is reserved to indicate an invalid thread.
Lalit Maganti9c6395b2019-01-17 00:25:09 +0000558 size_t thread_count() const { return unique_threads_.size(); }
Isabelle Taylore7003fb2018-07-17 11:39:01 +0100559
Hector Dearman12323362018-08-09 16:09:28 +0100560 // Number of interned strings in the pool. Includes the empty string w/ ID=0.
561 size_t string_count() const { return string_pool_.size(); }
562
Lalit Maganticaed37e2018-06-01 03:03:08 +0100563 private:
Isabelle Taylora0a22972018-08-03 12:06:12 +0100564 TraceStorage& operator=(const TraceStorage&) = default;
565
Primiano Tucci2da5d2e2018-08-10 14:23:31 +0100566 using StringHash = uint64_t;
Lalit Maganticaed37e2018-06-01 03:03:08 +0100567
Lalit Maganti05e8c132018-11-09 18:16:12 +0000568 // Stats about parsing the trace.
Primiano Tucci0e38a142019-01-07 20:51:09 +0000569 StatsMap stats_{};
Lalit Maganti35622b72018-06-06 12:03:11 +0100570
Lalit Maganticaed37e2018-06-01 03:03:08 +0100571 // One entry for each CPU in the trace.
Lalit Magantiff69c112018-09-24 12:07:47 +0100572 Slices slices_;
Lalit Maganticaed37e2018-06-01 03:03:08 +0100573
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000574 // Args for all other tables.
575 Args args_;
576
Lalit Maganticaed37e2018-06-01 03:03:08 +0100577 // One entry for each unique string in the trace.
Lalit Maganti35622b72018-06-06 12:03:11 +0100578 std::deque<std::string> string_pool_;
Lalit Maganticaed37e2018-06-01 03:03:08 +0100579
580 // One entry for each unique string in the trace.
Lalit Maganti35622b72018-06-06 12:03:11 +0100581 std::unordered_map<StringHash, StringId> string_index_;
Isabelle Taylor47328cf2018-06-12 14:33:59 +0100582
Isabelle Taylor47328cf2018-06-12 14:33:59 +0100583 // One entry for each UniquePid, with UniquePid as the index.
Isabelle Taylor3dd366c2018-06-22 16:21:41 +0100584 std::deque<Process> unique_processes_;
Isabelle Taylor68e42192018-06-19 16:19:31 +0100585
Isabelle Taylor68e42192018-06-19 16:19:31 +0100586 // One entry for each UniqueTid, with UniqueTid as the index.
Isabelle Taylor3dd366c2018-06-22 16:21:41 +0100587 std::deque<Thread> unique_threads_;
Primiano Tucci0d72a312018-08-07 14:42:45 +0100588
589 // Slices coming from userspace events (e.g. Chromium TRACE_EVENT macros).
590 NestableSlices nestable_slices_;
Isabelle Taylor15314ea2018-09-19 11:35:19 +0100591
592 // Counter events from the trace. This includes CPU frequency events as well
593 // systrace trace_marker counter events.
594 Counters counters_;
Primiano Tucci5cb84f82018-10-31 21:46:36 -0700595
596 SqlStats sql_stats_;
Lalit Maganti6e9c55e2018-11-29 12:00:39 +0000597
Isabelle Taylorc8c11202018-11-05 11:36:22 +0000598 // These are instantaneous events in the trace. They have no duration
599 // and do not have a value that make sense to track over time.
600 // e.g. signal events
601 Instants instants_;
Lalit Maganti1d915a62019-01-07 12:10:42 +0000602
603 // Raw events are every ftrace event in the trace. The raw event includes
604 // the timestamp and the pid. The args for the raw event will be in the
605 // args table. This table can be used to generate a text version of the
606 // trace.
607 RawEvents raw_events_;
Primiano Tucci2c761ef2019-01-07 20:20:46 +0000608 AndroidLogs android_log_;
Lalit Maganticaed37e2018-06-01 03:03:08 +0100609};
610
611} // namespace trace_processor
612} // namespace perfetto
613
614#endif // SRC_TRACE_PROCESSOR_TRACE_STORAGE_H_