blob: 58a2d0134e285b515161764e7d4b45c9050c60bf [file] [log] [blame]
Lalit Maganticaed37e2018-06-01 03:03:08 +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#include "src/trace_processor/trace_storage.h"
18
19#include <string.h>
Ioannis Ilkosb8b11102019-01-29 17:56:55 +000020#include <algorithm>
21#include <limits>
22
Primiano Tucci2c5488f2019-06-01 03:27:28 +010023#include "perfetto/ext/base/no_destructor.h"
Eric Seckler972225e2019-04-18 11:07:12 +010024
25namespace perfetto {
26namespace trace_processor {
27
Ioannis Ilkosb8b11102019-01-29 17:56:55 +000028namespace {
Eric Seckler972225e2019-04-18 11:07:12 +010029
Ioannis Ilkosb8b11102019-01-29 17:56:55 +000030template <typename T>
31void MaybeUpdateMinMax(T begin_it,
32 T end_it,
33 int64_t* min_value,
34 int64_t* max_value) {
35 if (begin_it == end_it) {
36 return;
37 }
38 std::pair<T, T> minmax = std::minmax_element(begin_it, end_it);
39 *min_value = std::min(*min_value, *minmax.first);
40 *max_value = std::max(*max_value, *minmax.second);
41}
Eric Seckler972225e2019-04-18 11:07:12 +010042
43std::vector<const char*> CreateRefTypeStringMap() {
44 std::vector<const char*> map(RefType::kRefMax);
45 map[RefType::kRefNoRef] = nullptr;
46 map[RefType::kRefUtid] = "utid";
47 map[RefType::kRefCpuId] = "cpu";
48 map[RefType::kRefIrq] = "irq";
49 map[RefType::kRefSoftIrq] = "softirq";
50 map[RefType::kRefUpid] = "upid";
Eric Seckler972225e2019-04-18 11:07:12 +010051 return map;
52}
53
Ioannis Ilkosb8b11102019-01-29 17:56:55 +000054} // namespace
Lalit Maganticaed37e2018-06-01 03:03:08 +010055
Eric Seckler972225e2019-04-18 11:07:12 +010056const std::vector<const char*>& GetRefTypeStringMap() {
57 static const base::NoDestructor<std::vector<const char*>> map(
58 CreateRefTypeStringMap());
59 return map.ref();
60}
Lalit Maganticaed37e2018-06-01 03:03:08 +010061
Isabelle Taylor47328cf2018-06-12 14:33:59 +010062TraceStorage::TraceStorage() {
Lalit Maganti1f64cfa2018-09-18 13:20:02 +010063 // Upid/utid 0 is reserved for idle processes/threads.
Primiano Tuccib75dcee2018-08-08 12:21:36 +010064 unique_processes_.emplace_back(0);
65 unique_threads_.emplace_back(0);
Isabelle Taylor47328cf2018-06-12 14:33:59 +010066}
67
Lalit Maganti35622b72018-06-06 12:03:11 +010068TraceStorage::~TraceStorage() {}
Lalit Maganticaed37e2018-06-01 03:03:08 +010069
Isabelle Taylora0a22972018-08-03 12:06:12 +010070void TraceStorage::ResetStorage() {
71 *this = TraceStorage();
72}
73
Lalit Magantiaac2f652019-04-30 12:16:21 +010074uint32_t TraceStorage::SqlStats::RecordQueryBegin(const std::string& query,
75 int64_t time_queued,
76 int64_t time_started) {
Primiano Tucci5cb84f82018-10-31 21:46:36 -070077 if (queries_.size() >= kMaxLogEntries) {
78 queries_.pop_front();
79 times_queued_.pop_front();
80 times_started_.pop_front();
Lalit Magantiaac2f652019-04-30 12:16:21 +010081 times_first_next_.pop_front();
Primiano Tucci5cb84f82018-10-31 21:46:36 -070082 times_ended_.pop_front();
Lalit Magantiaac2f652019-04-30 12:16:21 +010083 popped_queries_++;
Primiano Tucci5cb84f82018-10-31 21:46:36 -070084 }
85 queries_.push_back(query);
86 times_queued_.push_back(time_queued);
87 times_started_.push_back(time_started);
Lalit Magantiaac2f652019-04-30 12:16:21 +010088 times_first_next_.push_back(0);
Primiano Tucci5cb84f82018-10-31 21:46:36 -070089 times_ended_.push_back(0);
Lalit Magantiaac2f652019-04-30 12:16:21 +010090 return static_cast<uint32_t>(popped_queries_ + queries_.size() - 1);
Primiano Tucci5cb84f82018-10-31 21:46:36 -070091}
92
Lalit Magantiaac2f652019-04-30 12:16:21 +010093void TraceStorage::SqlStats::RecordQueryFirstNext(uint32_t row,
94 int64_t time_first_next) {
95 // This means we've popped this query off the queue of queries before it had
96 // a chance to finish. Just silently drop this number.
97 if (popped_queries_ > row)
98 return;
99 uint32_t queue_row = row - popped_queries_;
100 PERFETTO_DCHECK(queue_row < queries_.size());
101 times_first_next_[queue_row] = time_first_next;
102}
103
104void TraceStorage::SqlStats::RecordQueryEnd(uint32_t row, int64_t time_ended) {
105 // This means we've popped this query off the queue of queries before it had
106 // a chance to finish. Just silently drop this number.
107 if (popped_queries_ > row)
108 return;
109 uint32_t queue_row = row - popped_queries_;
110 PERFETTO_DCHECK(queue_row < queries_.size());
111 times_ended_[queue_row] = time_ended;
Primiano Tucci5cb84f82018-10-31 21:46:36 -0700112}
113
Ioannis Ilkosb8b11102019-01-29 17:56:55 +0000114std::pair<int64_t, int64_t> TraceStorage::GetTraceTimestampBoundsNs() const {
115 int64_t start_ns = std::numeric_limits<int64_t>::max();
116 int64_t end_ns = std::numeric_limits<int64_t>::min();
117 MaybeUpdateMinMax(slices_.start_ns().begin(), slices_.start_ns().end(),
118 &start_ns, &end_ns);
Lalit Maganti8320e6d2019-03-14 18:49:33 +0000119 MaybeUpdateMinMax(counter_values_.timestamps().begin(),
120 counter_values_.timestamps().end(), &start_ns, &end_ns);
Ioannis Ilkosb8b11102019-01-29 17:56:55 +0000121 MaybeUpdateMinMax(instants_.timestamps().begin(),
122 instants_.timestamps().end(), &start_ns, &end_ns);
123 MaybeUpdateMinMax(nestable_slices_.start_ns().begin(),
124 nestable_slices_.start_ns().end(), &start_ns, &end_ns);
125 MaybeUpdateMinMax(android_log_.timestamps().begin(),
126 android_log_.timestamps().end(), &start_ns, &end_ns);
Ioannis Ilkos20d5e8b2019-05-16 15:43:26 +0100127 MaybeUpdateMinMax(raw_events_.timestamps().begin(),
128 raw_events_.timestamps().end(), &start_ns, &end_ns);
Ioannis Ilkosb8b11102019-01-29 17:56:55 +0000129
130 if (start_ns == std::numeric_limits<int64_t>::max()) {
131 return std::make_pair(0, 0);
132 }
133 return std::make_pair(start_ns, end_ns);
134}
135
Lalit Maganticaed37e2018-06-01 03:03:08 +0100136} // namespace trace_processor
137} // namespace perfetto