• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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/storage/trace_storage.h"
18 
19 #include <string.h>
20 #include <algorithm>
21 #include <limits>
22 
23 #include "perfetto/ext/base/no_destructor.h"
24 
25 namespace perfetto {
26 namespace trace_processor {
27 
28 namespace {
29 
DbTableMaybeUpdateMinMax(const TypedColumn<int64_t> & ts_col,int64_t * min_value,int64_t * max_value,const TypedColumn<int64_t> * dur_col=nullptr)30 void DbTableMaybeUpdateMinMax(const TypedColumn<int64_t>& ts_col,
31                               int64_t* min_value,
32                               int64_t* max_value,
33                               const TypedColumn<int64_t>* dur_col = nullptr) {
34   if (ts_col.overlay().empty())
35     return;
36 
37   int64_t col_min = ts_col.Min()->AsLong();
38   int64_t col_max = ts_col.Max()->AsLong();
39 
40   if (dur_col) {
41     PERFETTO_CHECK(ts_col.IsSorted());
42     PERFETTO_CHECK(dur_col->overlay().size() == ts_col.overlay().size());
43     for (uint32_t i = 0; i < dur_col->overlay().size(); i++) {
44       col_max = std::max(ts_col[i] + (*dur_col)[i], col_max);
45     }
46   }
47 
48   *min_value = std::min(*min_value, col_min);
49   *max_value = std::max(*max_value, col_max);
50 }
51 
CreateRefTypeStringMap()52 std::vector<NullTermStringView> CreateRefTypeStringMap() {
53   std::vector<NullTermStringView> map(static_cast<size_t>(RefType::kRefMax));
54   map[static_cast<size_t>(RefType::kRefNoRef)] = NullTermStringView();
55   map[static_cast<size_t>(RefType::kRefUtid)] = "utid";
56   map[static_cast<size_t>(RefType::kRefCpuId)] = "cpu";
57   map[static_cast<size_t>(RefType::kRefGpuId)] = "gpu";
58   map[static_cast<size_t>(RefType::kRefIrq)] = "irq";
59   map[static_cast<size_t>(RefType::kRefSoftIrq)] = "softirq";
60   map[static_cast<size_t>(RefType::kRefUpid)] = "upid";
61   map[static_cast<size_t>(RefType::kRefTrack)] = "track";
62   return map;
63 }
64 
65 }  // namespace
66 
GetRefTypeStringMap()67 const std::vector<NullTermStringView>& GetRefTypeStringMap() {
68   static const base::NoDestructor<std::vector<NullTermStringView>> map(
69       CreateRefTypeStringMap());
70   return map.ref();
71 }
72 
TraceStorage(const Config &)73 TraceStorage::TraceStorage(const Config&) {
74   for (uint32_t i = 0; i < variadic_type_ids_.size(); ++i) {
75     variadic_type_ids_[i] = InternString(Variadic::kTypeNames[i]);
76   }
77 }
78 
~TraceStorage()79 TraceStorage::~TraceStorage() {}
80 
RecordQueryBegin(const std::string & query,int64_t time_started)81 uint32_t TraceStorage::SqlStats::RecordQueryBegin(const std::string& query,
82                                                   int64_t time_started) {
83   if (queries_.size() >= kMaxLogEntries) {
84     queries_.pop_front();
85     times_started_.pop_front();
86     times_first_next_.pop_front();
87     times_ended_.pop_front();
88     popped_queries_++;
89   }
90   queries_.push_back(query);
91   times_started_.push_back(time_started);
92   times_first_next_.push_back(0);
93   times_ended_.push_back(0);
94   return static_cast<uint32_t>(popped_queries_ + queries_.size() - 1);
95 }
96 
RecordQueryFirstNext(uint32_t row,int64_t time_first_next)97 void TraceStorage::SqlStats::RecordQueryFirstNext(uint32_t row,
98                                                   int64_t time_first_next) {
99   // This means we've popped this query off the queue of queries before it had
100   // a chance to finish. Just silently drop this number.
101   if (popped_queries_ > row)
102     return;
103   uint32_t queue_row = row - popped_queries_;
104   PERFETTO_DCHECK(queue_row < queries_.size());
105   times_first_next_[queue_row] = time_first_next;
106 }
107 
RecordQueryEnd(uint32_t row,int64_t time_ended)108 void TraceStorage::SqlStats::RecordQueryEnd(uint32_t row, int64_t time_ended) {
109   // This means we've popped this query off the queue of queries before it had
110   // a chance to finish. Just silently drop this number.
111   if (popped_queries_ > row)
112     return;
113   uint32_t queue_row = row - popped_queries_;
114   PERFETTO_DCHECK(queue_row < queries_.size());
115   times_ended_[queue_row] = time_ended;
116 }
117 
GetTraceTimestampBoundsNs() const118 std::pair<int64_t, int64_t> TraceStorage::GetTraceTimestampBoundsNs() const {
119   int64_t start_ns = std::numeric_limits<int64_t>::max();
120   int64_t end_ns = std::numeric_limits<int64_t>::min();
121 
122   DbTableMaybeUpdateMinMax(raw_table_.ts(), &start_ns, &end_ns);
123   DbTableMaybeUpdateMinMax(sched_slice_table_.ts(), &start_ns, &end_ns,
124                            &sched_slice_table_.dur());
125   DbTableMaybeUpdateMinMax(counter_table_.ts(), &start_ns, &end_ns);
126   DbTableMaybeUpdateMinMax(slice_table_.ts(), &start_ns, &end_ns,
127                            &slice_table_.dur());
128   DbTableMaybeUpdateMinMax(heap_profile_allocation_table_.ts(), &start_ns,
129                            &end_ns);
130   DbTableMaybeUpdateMinMax(thread_state_table_.ts(), &start_ns, &end_ns);
131   DbTableMaybeUpdateMinMax(android_log_table_.ts(), &start_ns, &end_ns);
132   DbTableMaybeUpdateMinMax(heap_graph_object_table_.graph_sample_ts(),
133                            &start_ns, &end_ns);
134   DbTableMaybeUpdateMinMax(perf_sample_table_.ts(), &start_ns, &end_ns);
135 
136   if (start_ns == std::numeric_limits<int64_t>::max()) {
137     return std::make_pair(0, 0);
138   }
139   if (start_ns == end_ns) {
140     end_ns += 1;
141   }
142   return std::make_pair(start_ns, end_ns);
143 }
144 
145 }  // namespace trace_processor
146 }  // namespace perfetto
147