Merge changes I5ad9e5a5,Ief74d748
* changes:
trace_processor: Remove PERFETTO_TP_ANDROID_PROBES build flag
trace_processor: Remove PERFETTO_TP_SYSTEM_PROBES build flag
diff --git a/Android.bp b/Android.bp
index 827c726..5d95ca4 100644
--- a/Android.bp
+++ b/Android.bp
@@ -5628,14 +5628,31 @@
],
}
+// GN: //src/trace_processor/containers:containers
+filegroup {
+ name: "perfetto_src_trace_processor_containers_containers",
+ srcs: [
+ "src/trace_processor/containers/bit_vector.cc",
+ "src/trace_processor/containers/bit_vector_iterators.cc",
+ "src/trace_processor/containers/row_map.cc",
+ ],
+}
+
+// GN: //src/trace_processor/containers:unittests
+filegroup {
+ name: "perfetto_src_trace_processor_containers_unittests",
+ srcs: [
+ "src/trace_processor/containers/bit_vector_unittest.cc",
+ "src/trace_processor/containers/row_map_unittest.cc",
+ "src/trace_processor/containers/sparse_vector_unittest.cc",
+ ],
+}
+
// GN: //src/trace_processor/db:lib
filegroup {
name: "perfetto_src_trace_processor_db_lib",
srcs: [
- "src/trace_processor/db/bit_vector.cc",
- "src/trace_processor/db/bit_vector_iterators.cc",
"src/trace_processor/db/column.cc",
- "src/trace_processor/db/row_map.cc",
"src/trace_processor/db/table.cc",
],
}
@@ -5644,10 +5661,7 @@
filegroup {
name: "perfetto_src_trace_processor_db_unittests",
srcs: [
- "src/trace_processor/db/bit_vector_unittest.cc",
"src/trace_processor/db/compare_unittest.cc",
- "src/trace_processor/db/row_map_unittest.cc",
- "src/trace_processor/db/sparse_vector_unittest.cc",
],
}
@@ -6590,6 +6604,8 @@
":perfetto_src_protozero_testing_messages_zero_gen",
":perfetto_src_protozero_unittests",
":perfetto_src_trace_processor_common",
+ ":perfetto_src_trace_processor_containers_containers",
+ ":perfetto_src_trace_processor_containers_unittests",
":perfetto_src_trace_processor_db_lib",
":perfetto_src_trace_processor_db_unittests",
":perfetto_src_trace_processor_descriptors",
@@ -6804,6 +6820,7 @@
":perfetto_src_base_base",
":perfetto_src_protozero_protozero",
":perfetto_src_trace_processor_common",
+ ":perfetto_src_trace_processor_containers_containers",
":perfetto_src_trace_processor_db_lib",
":perfetto_src_trace_processor_descriptors",
":perfetto_src_trace_processor_lib",
@@ -6911,6 +6928,7 @@
":perfetto_src_profiling_deobfuscator",
":perfetto_src_protozero_protozero",
":perfetto_src_trace_processor_common",
+ ":perfetto_src_trace_processor_containers_containers",
":perfetto_src_trace_processor_db_lib",
":perfetto_src_trace_processor_descriptors",
":perfetto_src_trace_processor_lib",
diff --git a/BUILD b/BUILD
index 71698f7..2435b10 100644
--- a/BUILD
+++ b/BUILD
@@ -572,20 +572,27 @@
],
)
+# GN target: //src/trace_processor/containers:containers
+filegroup(
+ name = "src_trace_processor_containers_containers",
+ srcs = [
+ "src/trace_processor/containers/bit_vector.cc",
+ "src/trace_processor/containers/bit_vector.h",
+ "src/trace_processor/containers/bit_vector_iterators.cc",
+ "src/trace_processor/containers/bit_vector_iterators.h",
+ "src/trace_processor/containers/row_map.cc",
+ "src/trace_processor/containers/row_map.h",
+ "src/trace_processor/containers/sparse_vector.h",
+ ],
+)
+
# GN target: //src/trace_processor/db:lib
filegroup(
name = "src_trace_processor_db_lib",
srcs = [
- "src/trace_processor/db/bit_vector.cc",
- "src/trace_processor/db/bit_vector.h",
- "src/trace_processor/db/bit_vector_iterators.cc",
- "src/trace_processor/db/bit_vector_iterators.h",
"src/trace_processor/db/column.cc",
"src/trace_processor/db/column.h",
"src/trace_processor/db/compare.h",
- "src/trace_processor/db/row_map.cc",
- "src/trace_processor/db/row_map.h",
- "src/trace_processor/db/sparse_vector.h",
"src/trace_processor/db/table.cc",
"src/trace_processor/db/table.h",
"src/trace_processor/db/typed_column.h",
@@ -2521,6 +2528,7 @@
":src_base_base",
":src_protozero_protozero",
":src_trace_processor_common",
+ ":src_trace_processor_containers_containers",
":src_trace_processor_db_lib",
":src_trace_processor_descriptors",
":src_trace_processor_export_json",
@@ -2599,6 +2607,7 @@
":src_base_unix_socket",
":src_protozero_protozero",
":src_trace_processor_common",
+ ":src_trace_processor_containers_containers",
":src_trace_processor_db_lib",
":src_trace_processor_descriptors",
":src_trace_processor_export_json",
@@ -2752,6 +2761,7 @@
":src_profiling_deobfuscator",
":src_protozero_protozero",
":src_trace_processor_common",
+ ":src_trace_processor_containers_containers",
":src_trace_processor_db_lib",
":src_trace_processor_descriptors",
":src_trace_processor_export_json",
diff --git a/BUILD.gn b/BUILD.gn
index 30f269d..4fdd937 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -82,6 +82,17 @@
]
}
+if (enable_perfetto_trace_processor_json) {
+ executable("trace_processor_minimal_smoke_tests") {
+ testonly = true
+ deps = [
+ "gn:default_deps",
+ "src/trace_processor:storage_minimal_smoke_tests",
+ ]
+ }
+ all_targets += [ ":trace_processor_minimal_smoke_tests" ]
+}
+
if (enable_perfetto_benchmarks) {
import("gn/perfetto_benchmarks.gni")
executable("perfetto_benchmarks") {
diff --git a/gn/perfetto_benchmarks.gni b/gn/perfetto_benchmarks.gni
index 4b0f331..122c6ff 100644
--- a/gn/perfetto_benchmarks.gni
+++ b/gn/perfetto_benchmarks.gni
@@ -18,7 +18,7 @@
"gn:default_deps",
"src/base:benchmarks",
"src/traced/probes/ftrace:benchmarks",
- "src/trace_processor/db:benchmarks",
+ "src/trace_processor/containers:benchmarks",
"src/trace_processor/tables:benchmarks",
"src/tracing:benchmarks",
"test:benchmark_main",
diff --git a/src/trace_processor/BUILD.gn b/src/trace_processor/BUILD.gn
index 9604696..9d34b96 100644
--- a/src/trace_processor/BUILD.gn
+++ b/src/trace_processor/BUILD.gn
@@ -460,6 +460,7 @@
"../base",
"../protozero",
"../protozero:testing_messages_zero",
+ "containers:unittests",
"db:unittests",
"tables:unittests",
]
@@ -537,6 +538,24 @@
}
}
+if (enable_perfetto_trace_processor_json) {
+ source_set("storage_minimal_smoke_tests") {
+ testonly = true
+ sources = [
+ "storage_minimal_smoke_test.cc",
+ ]
+ deps = [
+ ":export_json",
+ ":storage_minimal",
+ "../../gn:default_deps",
+ "../../gn:gtest_and_gmock",
+ "../../gn:gtest_main",
+ "../../gn:jsoncpp",
+ "../base:test_support",
+ ]
+ }
+}
+
perfetto_fuzzer_test("trace_processor_fuzzer") {
testonly = true
sources = [
diff --git a/src/trace_processor/containers/BUILD.gn b/src/trace_processor/containers/BUILD.gn
new file mode 100644
index 0000000..c6c5d73
--- /dev/null
+++ b/src/trace_processor/containers/BUILD.gn
@@ -0,0 +1,63 @@
+# Copyright (C) 2019 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../../gn/test.gni")
+
+source_set("containers") {
+ sources = [
+ "bit_vector.cc",
+ "bit_vector.h",
+ "bit_vector_iterators.cc",
+ "bit_vector_iterators.h",
+ "row_map.cc",
+ "row_map.h",
+ "sparse_vector.h",
+ ]
+ deps = [
+ "../:common",
+ "../../../gn:default_deps",
+ "../../../include/perfetto/base",
+ "../../../include/perfetto/ext/base",
+ ]
+}
+
+perfetto_unittest_source_set("unittests") {
+ testonly = true
+ sources = [
+ "bit_vector_unittest.cc",
+ "row_map_unittest.cc",
+ "sparse_vector_unittest.cc",
+ ]
+ deps = [
+ ":containers",
+ "../../../gn:default_deps",
+ "../../../gn:gtest_and_gmock",
+ ]
+}
+
+if (enable_perfetto_benchmarks) {
+ source_set("benchmarks") {
+ testonly = true
+ deps = [
+ ":containers",
+ "../../../gn:benchmark",
+ "../../../gn:default_deps",
+ ]
+ sources = [
+ "bit_vector_benchmark.cc",
+ "row_map_benchmark.cc",
+ "sparse_vector_benchmark.cc",
+ ]
+ }
+}
diff --git a/src/trace_processor/db/bit_vector.cc b/src/trace_processor/containers/bit_vector.cc
similarity index 94%
rename from src/trace_processor/db/bit_vector.cc
rename to src/trace_processor/containers/bit_vector.cc
index 0d2f3d8..0ec5bcc 100644
--- a/src/trace_processor/db/bit_vector.cc
+++ b/src/trace_processor/containers/bit_vector.cc
@@ -14,9 +14,9 @@
* limitations under the License.
*/
-#include "src/trace_processor/db/bit_vector.h"
+#include "src/trace_processor/containers/bit_vector.h"
-#include "src/trace_processor/db/bit_vector_iterators.h"
+#include "src/trace_processor/containers/bit_vector_iterators.h"
namespace perfetto {
namespace trace_processor {
diff --git a/src/trace_processor/db/bit_vector.h b/src/trace_processor/containers/bit_vector.h
similarity index 98%
rename from src/trace_processor/db/bit_vector.h
rename to src/trace_processor/containers/bit_vector.h
index bed71a6..58b9e23 100644
--- a/src/trace_processor/db/bit_vector.h
+++ b/src/trace_processor/containers/bit_vector.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef SRC_TRACE_PROCESSOR_DB_BIT_VECTOR_H_
-#define SRC_TRACE_PROCESSOR_DB_BIT_VECTOR_H_
+#ifndef SRC_TRACE_PROCESSOR_CONTAINERS_BIT_VECTOR_H_
+#define SRC_TRACE_PROCESSOR_CONTAINERS_BIT_VECTOR_H_
#include <stddef.h>
#include <stdint.h>
@@ -655,4 +655,4 @@
} // namespace trace_processor
} // namespace perfetto
-#endif // SRC_TRACE_PROCESSOR_DB_BIT_VECTOR_H_
+#endif // SRC_TRACE_PROCESSOR_CONTAINERS_BIT_VECTOR_H_
diff --git a/src/trace_processor/db/bit_vector_benchmark.cc b/src/trace_processor/containers/bit_vector_benchmark.cc
similarity index 98%
rename from src/trace_processor/db/bit_vector_benchmark.cc
rename to src/trace_processor/containers/bit_vector_benchmark.cc
index 54c00f9..b4a0c27 100644
--- a/src/trace_processor/db/bit_vector_benchmark.cc
+++ b/src/trace_processor/containers/bit_vector_benchmark.cc
@@ -16,7 +16,7 @@
#include <benchmark/benchmark.h>
-#include "src/trace_processor/db/bit_vector.h"
+#include "src/trace_processor/containers/bit_vector.h"
namespace {
@@ -36,7 +36,7 @@
b->Arg(1234567);
}
}
-}
+} // namespace
static void BM_BitVectorAppendTrue(benchmark::State& state) {
BitVector bv;
diff --git a/src/trace_processor/db/bit_vector_iterators.cc b/src/trace_processor/containers/bit_vector_iterators.cc
similarity index 98%
rename from src/trace_processor/db/bit_vector_iterators.cc
rename to src/trace_processor/containers/bit_vector_iterators.cc
index 281384c..5424365 100644
--- a/src/trace_processor/db/bit_vector_iterators.cc
+++ b/src/trace_processor/containers/bit_vector_iterators.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "src/trace_processor/db/bit_vector_iterators.h"
+#include "src/trace_processor/containers/bit_vector_iterators.h"
namespace perfetto {
namespace trace_processor {
diff --git a/src/trace_processor/db/bit_vector_iterators.h b/src/trace_processor/containers/bit_vector_iterators.h
similarity index 95%
rename from src/trace_processor/db/bit_vector_iterators.h
rename to src/trace_processor/containers/bit_vector_iterators.h
index 365e8ef..0047812 100644
--- a/src/trace_processor/db/bit_vector_iterators.h
+++ b/src/trace_processor/containers/bit_vector_iterators.h
@@ -14,10 +14,10 @@
* limitations under the License.
*/
-#ifndef SRC_TRACE_PROCESSOR_DB_BIT_VECTOR_ITERATORS_H_
-#define SRC_TRACE_PROCESSOR_DB_BIT_VECTOR_ITERATORS_H_
+#ifndef SRC_TRACE_PROCESSOR_CONTAINERS_BIT_VECTOR_ITERATORS_H_
+#define SRC_TRACE_PROCESSOR_CONTAINERS_BIT_VECTOR_ITERATORS_H_
-#include "src/trace_processor/db/bit_vector.h"
+#include "src/trace_processor/containers/bit_vector.h"
namespace perfetto {
namespace trace_processor {
@@ -187,4 +187,4 @@
} // namespace trace_processor
} // namespace perfetto
-#endif // SRC_TRACE_PROCESSOR_DB_BIT_VECTOR_ITERATORS_H_
+#endif // SRC_TRACE_PROCESSOR_CONTAINERS_BIT_VECTOR_ITERATORS_H_
diff --git a/src/trace_processor/db/bit_vector_unittest.cc b/src/trace_processor/containers/bit_vector_unittest.cc
similarity index 98%
rename from src/trace_processor/db/bit_vector_unittest.cc
rename to src/trace_processor/containers/bit_vector_unittest.cc
index 7b5aad7..e185afd 100644
--- a/src/trace_processor/db/bit_vector_unittest.cc
+++ b/src/trace_processor/containers/bit_vector_unittest.cc
@@ -14,11 +14,11 @@
* limitations under the License.
*/
-#include "src/trace_processor/db/bit_vector.h"
+#include "src/trace_processor/containers/bit_vector.h"
#include <random>
-#include "src/trace_processor/db/bit_vector_iterators.h"
+#include "src/trace_processor/containers/bit_vector_iterators.h"
#include "test/gtest_and_gmock.h"
namespace perfetto {
diff --git a/src/trace_processor/db/row_map.cc b/src/trace_processor/containers/row_map.cc
similarity index 98%
rename from src/trace_processor/db/row_map.cc
rename to src/trace_processor/containers/row_map.cc
index cb16e4d..b10d0cb 100644
--- a/src/trace_processor/db/row_map.cc
+++ b/src/trace_processor/containers/row_map.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "src/trace_processor/db/row_map.h"
+#include "src/trace_processor/containers/row_map.h"
namespace perfetto {
namespace trace_processor {
diff --git a/src/trace_processor/db/row_map.h b/src/trace_processor/containers/row_map.h
similarity index 95%
rename from src/trace_processor/db/row_map.h
rename to src/trace_processor/containers/row_map.h
index 9b2805e..00ad7d2 100644
--- a/src/trace_processor/db/row_map.h
+++ b/src/trace_processor/containers/row_map.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef SRC_TRACE_PROCESSOR_DB_ROW_MAP_H_
-#define SRC_TRACE_PROCESSOR_DB_ROW_MAP_H_
+#ifndef SRC_TRACE_PROCESSOR_CONTAINERS_ROW_MAP_H_
+#define SRC_TRACE_PROCESSOR_CONTAINERS_ROW_MAP_H_
#include <stdint.h>
@@ -24,8 +24,8 @@
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/optional.h"
-#include "src/trace_processor/db/bit_vector.h"
-#include "src/trace_processor/db/bit_vector_iterators.h"
+#include "src/trace_processor/containers/bit_vector.h"
+#include "src/trace_processor/containers/bit_vector_iterators.h"
namespace perfetto {
namespace trace_processor {
@@ -381,31 +381,13 @@
// if (!other.Contains(idx))
// Remove(idx)
void Intersect(const RowMap& other) {
- uint32_t size = other.size();
-
- if (size == 0u) {
- // If other is empty, then we will also end up being empty.
- *this = RowMap();
- return;
- }
-
- if (size == 1u) {
- // If other just has a single row, see if we also have that row. If we
- // do, then just return that row. Otherwise, make ourselves empty.
- uint32_t row = other.Get(0);
- *this = Contains(row) ? RowMap::SingleRow(row) : RowMap();
- return;
- }
-
if (mode_ == Mode::kRange && other.mode_ == Mode::kRange) {
// If both RowMaps have ranges, we can just take the smallest intersection
// of them as the new RowMap.
- // This case is important to optimize as it comes up with sorted columns.
+ // We have this as an explicit fast path as this is very common for
+ // constraints on id and sorted columns to satisfy this condition.
start_idx_ = std::max(start_idx_, other.start_idx_);
- end_idx_ = std::min(end_idx_, other.end_idx_);
-
- if (end_idx_ <= start_idx_)
- *this = RowMap();
+ end_idx_ = std::max(start_idx_, std::min(end_idx_, other.end_idx_));
return;
}
@@ -634,4 +616,4 @@
} // namespace trace_processor
} // namespace perfetto
-#endif // SRC_TRACE_PROCESSOR_DB_ROW_MAP_H_
+#endif // SRC_TRACE_PROCESSOR_CONTAINERS_ROW_MAP_H_
diff --git a/src/trace_processor/db/row_map_benchmark.cc b/src/trace_processor/containers/row_map_benchmark.cc
similarity index 99%
rename from src/trace_processor/db/row_map_benchmark.cc
rename to src/trace_processor/containers/row_map_benchmark.cc
index 1d6892e..47d66cd 100644
--- a/src/trace_processor/db/row_map_benchmark.cc
+++ b/src/trace_processor/containers/row_map_benchmark.cc
@@ -16,7 +16,7 @@
#include <benchmark/benchmark.h>
-#include "src/trace_processor/db/row_map.h"
+#include "src/trace_processor/containers/row_map.h"
using perfetto::trace_processor::BitVector;
using perfetto::trace_processor::RowMap;
diff --git a/src/trace_processor/db/row_map_unittest.cc b/src/trace_processor/containers/row_map_unittest.cc
similarity index 99%
rename from src/trace_processor/db/row_map_unittest.cc
rename to src/trace_processor/containers/row_map_unittest.cc
index 042154d..c85b5fe 100644
--- a/src/trace_processor/db/row_map_unittest.cc
+++ b/src/trace_processor/containers/row_map_unittest.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "src/trace_processor/db/row_map.h"
+#include "src/trace_processor/containers/row_map.h"
#include <memory>
diff --git a/src/trace_processor/db/sparse_vector.h b/src/trace_processor/containers/sparse_vector.h
similarity index 93%
rename from src/trace_processor/db/sparse_vector.h
rename to src/trace_processor/containers/sparse_vector.h
index 7fb0d87..5c803d3 100644
--- a/src/trace_processor/db/sparse_vector.h
+++ b/src/trace_processor/containers/sparse_vector.h
@@ -14,8 +14,8 @@
* limitations under the License.
*/
-#ifndef SRC_TRACE_PROCESSOR_DB_SPARSE_VECTOR_H_
-#define SRC_TRACE_PROCESSOR_DB_SPARSE_VECTOR_H_
+#ifndef SRC_TRACE_PROCESSOR_CONTAINERS_SPARSE_VECTOR_H_
+#define SRC_TRACE_PROCESSOR_CONTAINERS_SPARSE_VECTOR_H_
#include <stdint.h>
@@ -23,7 +23,7 @@
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/optional.h"
-#include "src/trace_processor/db/row_map.h"
+#include "src/trace_processor/containers/row_map.h"
namespace perfetto {
namespace trace_processor {
@@ -115,4 +115,4 @@
} // namespace trace_processor
} // namespace perfetto
-#endif // SRC_TRACE_PROCESSOR_DB_SPARSE_VECTOR_H_
+#endif // SRC_TRACE_PROCESSOR_CONTAINERS_SPARSE_VECTOR_H_
diff --git a/src/trace_processor/db/sparse_vector_benchmark.cc b/src/trace_processor/containers/sparse_vector_benchmark.cc
similarity index 96%
rename from src/trace_processor/db/sparse_vector_benchmark.cc
rename to src/trace_processor/containers/sparse_vector_benchmark.cc
index ed1bed2..626b738 100644
--- a/src/trace_processor/db/sparse_vector_benchmark.cc
+++ b/src/trace_processor/containers/sparse_vector_benchmark.cc
@@ -16,7 +16,7 @@
#include <benchmark/benchmark.h>
-#include "src/trace_processor/db/sparse_vector.h"
+#include "src/trace_processor/containers/sparse_vector.h"
namespace {
diff --git a/src/trace_processor/db/sparse_vector_unittest.cc b/src/trace_processor/containers/sparse_vector_unittest.cc
similarity index 96%
rename from src/trace_processor/db/sparse_vector_unittest.cc
rename to src/trace_processor/containers/sparse_vector_unittest.cc
index cd8e43a..6e81b0b 100644
--- a/src/trace_processor/db/sparse_vector_unittest.cc
+++ b/src/trace_processor/containers/sparse_vector_unittest.cc
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-#include "src/trace_processor/db/sparse_vector.h"
+#include "src/trace_processor/containers/sparse_vector.h"
#include "test/gtest_and_gmock.h"
diff --git a/src/trace_processor/db/BUILD.gn b/src/trace_processor/db/BUILD.gn
index 30e2518..73373e8 100644
--- a/src/trace_processor/db/BUILD.gn
+++ b/src/trace_processor/db/BUILD.gn
@@ -16,16 +16,9 @@
source_set("lib") {
sources = [
- "bit_vector.cc",
- "bit_vector.h",
- "bit_vector_iterators.cc",
- "bit_vector_iterators.h",
"column.cc",
"column.h",
"compare.h",
- "row_map.cc",
- "row_map.h",
- "sparse_vector.h",
"table.cc",
"table.h",
"typed_column.h",
@@ -36,16 +29,14 @@
"../../../include/perfetto/base",
"../../../include/perfetto/ext/base",
"../../../include/perfetto/trace_processor",
+ "../containers",
]
}
perfetto_unittest_source_set("unittests") {
testonly = true
sources = [
- "bit_vector_unittest.cc",
"compare_unittest.cc",
- "row_map_unittest.cc",
- "sparse_vector_unittest.cc",
]
deps = [
":lib",
@@ -53,19 +44,3 @@
"../../../gn:gtest_and_gmock",
]
}
-
-if (enable_perfetto_benchmarks) {
- source_set("benchmarks") {
- testonly = true
- deps = [
- ":lib",
- "../../../gn:benchmark",
- "../../../gn:default_deps",
- ]
- sources = [
- "bit_vector_benchmark.cc",
- "row_map_benchmark.cc",
- "sparse_vector_benchmark.cc",
- ]
- }
-}
diff --git a/src/trace_processor/db/column.h b/src/trace_processor/db/column.h
index 0e3d927..d4e600a 100644
--- a/src/trace_processor/db/column.h
+++ b/src/trace_processor/db/column.h
@@ -22,9 +22,9 @@
#include "perfetto/base/logging.h"
#include "perfetto/ext/base/optional.h"
#include "perfetto/trace_processor/basic_types.h"
+#include "src/trace_processor/containers/row_map.h"
+#include "src/trace_processor/containers/sparse_vector.h"
#include "src/trace_processor/db/compare.h"
-#include "src/trace_processor/db/row_map.h"
-#include "src/trace_processor/db/sparse_vector.h"
#include "src/trace_processor/string_pool.h"
namespace perfetto {
diff --git a/src/trace_processor/importers/proto/packet_sequence_state.h b/src/trace_processor/importers/proto/packet_sequence_state.h
index b6bc5a6..c020758 100644
--- a/src/trace_processor/importers/proto/packet_sequence_state.h
+++ b/src/trace_processor/importers/proto/packet_sequence_state.h
@@ -29,6 +29,8 @@
#include "src/trace_processor/trace_processor_context.h"
#include "src/trace_processor/trace_storage.h"
+#include "protos/perfetto/trace/trace_packet_defaults.pbzero.h"
+
namespace perfetto {
namespace trace_processor {
@@ -43,51 +45,124 @@
class PacketSequenceState {
public:
// Entry in an interning index, refers to the interned message.
- struct InternedMessageView {
- InternedMessageView(TraceBlobView msg) : message(std::move(msg)) {}
+ class InternedMessageView {
+ public:
+ InternedMessageView(TraceBlobView msg) : message_(std::move(msg)) {}
+ InternedMessageView(InternedMessageView&&) noexcept = default;
+ InternedMessageView& operator=(InternedMessageView&&) = default;
+
+ // Allow copy by cloning the TraceBlobView. This is required for
+ // UpdateTracePacketDefaults().
+ InternedMessageView(const InternedMessageView& view)
+ : message_(view.message_.slice(0, view.message_.length())) {}
+ InternedMessageView& operator=(const InternedMessageView& view) {
+ this->message_ = view.message_.slice(0, view.message_.length());
+ this->decoder_ = nullptr;
+ this->decoder_type_ = nullptr;
+ this->submessages_.clear();
+ return *this;
+ }
+
+ // Lazily initializes and returns the decoder object for the message. The
+ // decoder is stored in the InternedMessageView to avoid having to parse the
+ // message multiple times.
template <typename MessageType>
typename MessageType::Decoder* GetOrCreateDecoder() {
- if (!decoder) {
+ if (!decoder_) {
// Lazy init the decoder and save it away, so that we don't have to
// reparse the message every time we access the interning entry.
- decoder = std::unique_ptr<void, std::function<void(void*)>>(
- new typename MessageType::Decoder(message.data(), message.length()),
+ decoder_ = std::unique_ptr<void, std::function<void(void*)>>(
+ new
+ typename MessageType::Decoder(message_.data(), message_.length()),
[](void* obj) {
delete reinterpret_cast<typename MessageType::Decoder*>(obj);
});
- decoder_type = PERFETTO_TYPE_IDENTIFIER;
+ decoder_type_ = PERFETTO_TYPE_IDENTIFIER;
}
// Verify that the type of the decoder didn't change.
if (PERFETTO_TYPE_IDENTIFIER &&
- strcmp(decoder_type,
+ strcmp(decoder_type_,
// GCC complains if this arg can be null.
PERFETTO_TYPE_IDENTIFIER ? PERFETTO_TYPE_IDENTIFIER : "") !=
0) {
PERFETTO_FATAL(
"Interning entry accessed under different types! previous type: "
"%s. new type: %s.",
- decoder_type, __PRETTY_FUNCTION__);
+ decoder_type_, __PRETTY_FUNCTION__);
}
- return reinterpret_cast<typename MessageType::Decoder*>(decoder.get());
+ return reinterpret_cast<typename MessageType::Decoder*>(decoder_.get());
}
- TraceBlobView message;
- std::unique_ptr<void, std::function<void(void*)>> decoder;
+ // Lookup a submessage of the interned message, which is then itself stored
+ // as InternedMessageView, so that we only need to parse it once. Returns
+ // nullptr if the field isn't set.
+ // TODO(eseckler): Support repeated fields.
+ template <typename MessageType, uint32_t FieldId>
+ InternedMessageView* GetOrCreateSubmessageView() {
+ auto it = submessages_.find(FieldId);
+ if (it != submessages_.end())
+ return it->second.get();
+ auto* decoder = GetOrCreateDecoder<MessageType>();
+ // Calls the at() template method on the decoder.
+ auto field = decoder->template at<FieldId>().as_bytes();
+ if (!field.data)
+ return nullptr;
+ const size_t offset = message_.offset_of(field.data);
+ TraceBlobView submessage = message_.slice(offset, field.size);
+ InternedMessageView* submessage_view =
+ new InternedMessageView(std::move(submessage));
+ submessages_.emplace_hint(
+ it, FieldId, std::unique_ptr<InternedMessageView>(submessage_view));
+ return submessage_view;
+ }
+
+ const TraceBlobView& message() { return message_; }
private:
- const char* decoder_type = nullptr;
+ using SubMessageViewMap =
+ std::unordered_map<uint32_t /*field_id*/,
+ std::unique_ptr<InternedMessageView>>;
+
+ TraceBlobView message_;
+
+ // Stores the decoder for the message_, so that the message does not have to
+ // be re-decoded every time the interned message is looked up. Lazily
+ // initialized in GetOrCreateDecoder(). Since we don't know the type of the
+ // decoder until GetOrCreateDecoder() is called, we store the decoder as a
+ // void* unique_pointer with a destructor function that's supplied in
+ // GetOrCreateDecoder() when the decoder is created.
+ std::unique_ptr<void, std::function<void(void*)>> decoder_;
+
+ // Type identifier for the decoder. Only valid in debug builds and on
+ // supported platforms. Used to verify that GetOrCreateDecoder() is always
+ // called with the same template argument.
+ const char* decoder_type_ = nullptr;
+
+ // Views of submessages of the interned message. Submessages are lazily
+ // added by GetOrCreateSubmessageView(). By storing submessages and their
+ // decoders, we avoid having to decode submessages multiple times if they
+ // looked up often.
+ SubMessageViewMap submessages_;
};
using InternedMessageMap =
std::unordered_map<uint64_t /*iid*/, InternedMessageView>;
using InternedFieldMap =
std::unordered_map<uint32_t /*field_id*/, InternedMessageMap>;
- using InternedDataGenerationList = std::vector<InternedFieldMap>;
+
+ struct GenerationData {
+ InternedFieldMap interned_data;
+ base::Optional<InternedMessageView> trace_packet_defaults;
+ };
+
+ // TODO(eseckler): Reference count the generations so that we can get rid of
+ // past generations once all packets referring to them have been parsed.
+ using GenerationList = std::vector<GenerationData>;
PacketSequenceState(TraceProcessorContext* context)
: context_(context), stack_profile_tracker_(context) {
- interned_data_.emplace_back();
+ generations_.emplace_back();
}
int64_t IncrementAndGetTrackEventTimeNs(int64_t delta_ns) {
@@ -115,7 +190,7 @@
void OnIncrementalStateCleared() {
packet_loss_ = false;
- interned_data_.emplace_back(); // Bump generation number
+ generations_.emplace_back(); // Bump generation number
}
void SetThreadDescriptor(int32_t pid,
@@ -138,9 +213,8 @@
return stack_profile_tracker_;
}
- // Returns the index of the current generation in the
- // InternedDataGenerationList.
- size_t current_generation() const { return interned_data_.size() - 1; }
+ // Returns the index of the current generation in the GenerationList.
+ size_t current_generation() const { return generations_.size() - 1; }
bool track_event_timestamps_valid() const {
return track_event_timestamps_valid_;
@@ -167,7 +241,7 @@
}
iid = field.as_uint64();
- auto* map = &interned_data_.back()[field_id];
+ auto* map = &generations_.back().interned_data[field_id];
auto res = map->emplace(iid, InternedMessageView(std::move(message)));
// If a message with this ID is already interned in the same generation,
@@ -176,16 +250,18 @@
// TODO(eseckler): This DCHECK assumes that the message is encoded the
// same way if it is re-emitted.
PERFETTO_DCHECK(res.second ||
- (res.first->second.message.length() == message_size &&
- memcmp(res.first->second.message.data(), message_start,
+ (res.first->second.message().length() == message_size &&
+ memcmp(res.first->second.message().data(), message_start,
message_size) == 0));
}
+ // Returns |nullptr| if the message with the given |iid| was not found (also
+ // records a stat in this case).
template <uint32_t FieldId, typename MessageType>
typename MessageType::Decoder* LookupInternedMessage(size_t generation,
uint64_t iid) {
- PERFETTO_CHECK(generation <= interned_data_.size());
- auto* field_map = &interned_data_[generation];
+ PERFETTO_CHECK(generation <= generations_.size());
+ auto* field_map = &generations_[generation].interned_data;
auto field_it = field_map->find(FieldId);
if (field_it != field_map->end()) {
auto* message_map = &field_it->second;
@@ -201,6 +277,37 @@
return nullptr;
}
+ void UpdateTracePacketDefaults(TraceBlobView trace_packet_defaults) {
+ if (generations_.back().trace_packet_defaults) {
+ // The new defaults should only apply to subsequent messages on the
+ // sequence. Add a new generation with the updated defaults but the
+ // current generation's interned data state.
+ const InternedFieldMap& current_interned_data =
+ generations_.back().interned_data;
+ generations_.emplace_back();
+ generations_.back().interned_data = current_interned_data;
+ }
+ generations_.back().trace_packet_defaults =
+ InternedMessageView(std::move(trace_packet_defaults));
+ }
+
+ // Returns |nullptr| if no defaults were set in the given generation.
+ InternedMessageView* GetTracePacketDefaultsView(size_t generation) {
+ PERFETTO_CHECK(generation <= generations_.size());
+ if (!generations_[generation].trace_packet_defaults)
+ return nullptr;
+ return &generations_[generation].trace_packet_defaults.value();
+ }
+
+ // Returns |nullptr| if no defaults were set in the given generation.
+ typename protos::pbzero::TracePacketDefaults::Decoder* GetTracePacketDefaults(
+ size_t generation) {
+ InternedMessageView* view = GetTracePacketDefaultsView(generation);
+ if (!view)
+ return nullptr;
+ return view->GetOrCreateDecoder<protos::pbzero::TracePacketDefaults>();
+ }
+
private:
TraceProcessorContext* context_;
@@ -229,7 +336,7 @@
int64_t track_event_thread_timestamp_ns_ = 0;
int64_t track_event_thread_instruction_count_ = 0;
- InternedDataGenerationList interned_data_;
+ GenerationList generations_;
StackProfileTracker stack_profile_tracker_;
};
diff --git a/src/trace_processor/importers/proto/proto_trace_tokenizer.cc b/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
index 97d7689..8ac2b36 100644
--- a/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
+++ b/src/trace_processor/importers/proto/proto_trace_tokenizer.cc
@@ -186,63 +186,8 @@
return util::ErrStatus(
"Failed to parse proto packet fully; the trace is probably corrupt.");
- auto timestamp =
- decoder.has_timestamp()
- ? static_cast<int64_t>(decoder.timestamp())
- : std::max(latest_timestamp_, context_->sorter->max_timestamp());
-
const uint32_t seq_id = decoder.trusted_packet_sequence_id();
-
- if ((decoder.has_chrome_events() || decoder.has_chrome_metadata()) &&
- (!decoder.timestamp_clock_id() ||
- decoder.timestamp_clock_id() ==
- protos::pbzero::ClockSnapshot::Clock::MONOTONIC)) {
- // Chrome event timestamps are in MONOTONIC domain, but may occur in traces
- // where (a) no clock snapshots exist or (b) no clock_id is specified for
- // their timestamps. Adjust to trace time if we have a clock snapshot.
- // TODO(eseckler): Set timestamp_clock_id and emit ClockSnapshots in chrome
- // and then remove this.
- auto trace_ts = context_->clock_tracker->ToTraceTime(
- protos::pbzero::ClockSnapshot::Clock::MONOTONIC, timestamp);
- if (trace_ts.has_value())
- timestamp = trace_ts.value();
- } else if (decoder.timestamp_clock_id()) {
- // If the TracePacket specifies a non-zero clock-id, translate the timestamp
- // into the trace-time clock domain.
- PERFETTO_DCHECK(decoder.has_timestamp());
- ClockTracker::ClockId clock_id = decoder.timestamp_clock_id();
- bool is_seq_scoped = ClockTracker::IsReservedSeqScopedClockId(clock_id);
- if (is_seq_scoped) {
- if (!seq_id) {
- return util::ErrStatus(
- "TracePacket specified a sequence-local clock id (%" PRIu32
- ") but the TraceWriter's sequence_id is zero (the service is "
- "probably too old)",
- decoder.timestamp_clock_id());
- }
- clock_id = ClockTracker::SeqScopedClockIdToGlobal(
- seq_id, decoder.timestamp_clock_id());
- }
- auto trace_ts = context_->clock_tracker->ToTraceTime(clock_id, timestamp);
- if (!trace_ts.has_value()) {
- // ToTraceTime() will increase the |clock_sync_failure| stat on failure.
- static const char seq_extra_err[] =
- " Because the clock id is sequence-scoped, the ClockSnapshot must be "
- "emitted on the same TraceWriter sequence of the packet that refers "
- "to that clock id.";
- return util::ErrStatus(
- "Failed to convert TracePacket's timestamp from clock_id=%" PRIu32
- " seq_id=%" PRIu32
- ". This is usually due to the lack of a prior ClockSnapshot proto.%s",
- decoder.timestamp_clock_id(), seq_id,
- is_seq_scoped ? seq_extra_err : "");
- }
- timestamp = trace_ts.value();
- }
- latest_timestamp_ = std::max(timestamp, latest_timestamp_);
-
- auto* state = GetIncrementalStateForPacketSequence(
- decoder.trusted_packet_sequence_id());
+ auto* state = GetIncrementalStateForPacketSequence(seq_id);
uint32_t sequence_flags = decoder.sequence_flags();
@@ -254,6 +199,25 @@
HandlePreviousPacketDropped(decoder);
}
+ // It is important that we parse defaults before parsing other fields such as
+ // the timestamp, since the defaults could affect them.
+ if (decoder.has_trace_packet_defaults()) {
+ auto field = decoder.trace_packet_defaults();
+ const size_t offset = packet.offset_of(field.data);
+ ParseTracePacketDefaults(decoder, packet.slice(offset, field.size));
+ }
+
+ if (decoder.has_interned_data()) {
+ auto field = decoder.interned_data();
+ const size_t offset = packet.offset_of(field.data);
+ ParseInternedData(decoder, packet.slice(offset, field.size));
+ }
+
+ if (decoder.has_clock_snapshot()) {
+ return ParseClockSnapshot(decoder.clock_snapshot(),
+ decoder.trusted_packet_sequence_id());
+ }
+
if (decoder.sequence_flags() &
protos::pbzero::TracePacket::SEQ_NEEDS_INCREMENTAL_STATE) {
if (!seq_id) {
@@ -269,18 +233,70 @@
}
}
- if (decoder.has_clock_snapshot()) {
- return ParseClockSnapshot(decoder.clock_snapshot(),
- decoder.trusted_packet_sequence_id());
- }
+ protos::pbzero::TracePacketDefaults::Decoder* defaults =
+ state->GetTracePacketDefaults(state->current_generation());
- // TODO(eseckler): Parse TracePacketDefaults.
+ int64_t timestamp;
+ if (decoder.has_timestamp()) {
+ timestamp = static_cast<int64_t>(decoder.timestamp());
- if (decoder.has_interned_data()) {
- auto field = decoder.interned_data();
- const size_t offset = packet.offset_of(field.data);
- ParseInternedData(decoder, packet.slice(offset, field.size));
+ uint32_t timestamp_clock_id =
+ decoder.has_timestamp_clock_id()
+ ? decoder.timestamp_clock_id()
+ : (defaults ? defaults->timestamp_clock_id() : 0);
+
+ if ((decoder.has_chrome_events() || decoder.has_chrome_metadata()) &&
+ (!timestamp_clock_id ||
+ timestamp_clock_id ==
+ protos::pbzero::ClockSnapshot::Clock::MONOTONIC)) {
+ // Chrome event timestamps are in MONOTONIC domain, but may occur in
+ // traces where (a) no clock snapshots exist or (b) no clock_id is
+ // specified for their timestamps. Adjust to trace time if we have a clock
+ // snapshot.
+ // TODO(eseckler): Set timestamp_clock_id and emit ClockSnapshots in
+ // chrome and then remove this.
+ auto trace_ts = context_->clock_tracker->ToTraceTime(
+ protos::pbzero::ClockSnapshot::Clock::MONOTONIC, timestamp);
+ if (trace_ts.has_value())
+ timestamp = trace_ts.value();
+ } else if (timestamp_clock_id) {
+ // If the TracePacket specifies a non-zero clock-id, translate the
+ // timestamp into the trace-time clock domain.
+ ClockTracker::ClockId converted_clock_id = timestamp_clock_id;
+ bool is_seq_scoped =
+ ClockTracker::IsReservedSeqScopedClockId(converted_clock_id);
+ if (is_seq_scoped) {
+ if (!seq_id) {
+ return util::ErrStatus(
+ "TracePacket specified a sequence-local clock id (%" PRIu32
+ ") but the TraceWriter's sequence_id is zero (the service is "
+ "probably too old)",
+ timestamp_clock_id);
+ }
+ converted_clock_id =
+ ClockTracker::SeqScopedClockIdToGlobal(seq_id, timestamp_clock_id);
+ }
+ auto trace_ts =
+ context_->clock_tracker->ToTraceTime(converted_clock_id, timestamp);
+ if (!trace_ts.has_value()) {
+ // ToTraceTime() will increase the |clock_sync_failure| stat on failure.
+ static const char seq_extra_err[] =
+ " Because the clock id is sequence-scoped, the ClockSnapshot must "
+ "be emitted on the same TraceWriter sequence of the packet that "
+ "refers to that clock id.";
+ return util::ErrStatus(
+ "Failed to convert TracePacket's timestamp from clock_id=%" PRIu32
+ " seq_id=%" PRIu32
+ ". This is usually due to the lack of a prior ClockSnapshot "
+ "proto.%s",
+ timestamp_clock_id, seq_id, is_seq_scoped ? seq_extra_err : "");
+ }
+ timestamp = trace_ts.value();
+ }
+ } else {
+ timestamp = std::max(latest_timestamp_, context_->sorter->max_timestamp());
}
+ latest_timestamp_ = std::max(timestamp, latest_timestamp_);
auto& modules = context_->modules_by_field;
for (uint32_t field_id = 1; field_id < modules.size(); ++field_id) {
@@ -380,6 +396,21 @@
->OnPacketLoss();
}
+void ProtoTraceTokenizer::ParseTracePacketDefaults(
+ const protos::pbzero::TracePacket_Decoder& packet_decoder,
+ TraceBlobView trace_packet_defaults) {
+ if (PERFETTO_UNLIKELY(!packet_decoder.has_trusted_packet_sequence_id())) {
+ PERFETTO_ELOG(
+ "TracePacketDefaults packet without trusted_packet_sequence_id");
+ context_->storage->IncrementStats(stats::interned_data_tokenizer_errors);
+ return;
+ }
+
+ auto* state = GetIncrementalStateForPacketSequence(
+ packet_decoder.trusted_packet_sequence_id());
+ state->UpdateTracePacketDefaults(std::move(trace_packet_defaults));
+}
+
void ProtoTraceTokenizer::ParseInternedData(
const protos::pbzero::TracePacket::Decoder& packet_decoder,
TraceBlobView interned_data) {
diff --git a/src/trace_processor/importers/proto/proto_trace_tokenizer.h b/src/trace_processor/importers/proto/proto_trace_tokenizer.h
index bdefa2e..0612068 100644
--- a/src/trace_processor/importers/proto/proto_trace_tokenizer.h
+++ b/src/trace_processor/importers/proto/proto_trace_tokenizer.h
@@ -67,6 +67,8 @@
void HandleIncrementalStateCleared(
const protos::pbzero::TracePacket_Decoder&);
void HandlePreviousPacketDropped(const protos::pbzero::TracePacket_Decoder&);
+ void ParseTracePacketDefaults(const protos::pbzero::TracePacket_Decoder&,
+ TraceBlobView trace_packet_defaults);
void ParseInternedData(const protos::pbzero::TracePacket_Decoder&,
TraceBlobView interned_data);
PacketSequenceState* GetIncrementalStateForPacketSequence(
diff --git a/src/trace_processor/importers/proto/track_event_parser.cc b/src/trace_processor/importers/proto/track_event_parser.cc
index 85507b3..3ba6b59 100644
--- a/src/trace_processor/importers/proto/track_event_parser.cc
+++ b/src/trace_processor/importers/proto/track_event_parser.cc
@@ -193,6 +193,21 @@
ConstBytes blob) {
using LegacyEvent = protos::pbzero::TrackEvent::LegacyEvent;
+ protos::pbzero::TrackEventDefaults::Decoder* defaults = nullptr;
+ auto* packet_defaults_view =
+ sequence_state->GetTracePacketDefaultsView(sequence_state_generation);
+ if (packet_defaults_view) {
+ auto* track_event_defaults_view =
+ packet_defaults_view
+ ->GetOrCreateSubmessageView<protos::pbzero::TracePacketDefaults,
+ protos::pbzero::TracePacketDefaults::
+ kTrackEventDefaultsFieldNumber>();
+ if (track_event_defaults_view) {
+ defaults = track_event_defaults_view
+ ->GetOrCreateDecoder<protos::pbzero::TrackEventDefaults>();
+ }
+ }
+
protos::pbzero::TrackEvent::Decoder event(blob.data, blob.size);
const auto legacy_event_blob = event.legacy_event();
@@ -275,9 +290,14 @@
name_id = storage->InternString(event.name());
}
- // TODO(eseckler): Also consider track_uuid from TrackEventDefaults.
- // Fall back to the default descriptor track (uuid 0).
- uint64_t track_uuid = event.has_track_uuid() ? event.track_uuid() : 0u;
+ // Consider track_uuid from the packet and TrackEventDefaults, fall back to
+ // the default descriptor track (uuid 0).
+ uint64_t track_uuid =
+ event.has_track_uuid()
+ ? event.track_uuid()
+ : (defaults && defaults->has_track_uuid() ? defaults->track_uuid()
+ : 0u);
+
TrackId track_id;
base::Optional<UniqueTid> utid;
base::Optional<UniqueTid> upid;
diff --git a/src/trace_processor/storage_minimal_smoke_test.cc b/src/trace_processor/storage_minimal_smoke_test.cc
new file mode 100644
index 0000000..1aa037d
--- /dev/null
+++ b/src/trace_processor/storage_minimal_smoke_test.cc
@@ -0,0 +1,87 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <cstdio>
+#include <string>
+
+#include <json/reader.h>
+#include <json/value.h>
+
+#include "perfetto/ext/trace_processor/export_json.h"
+#include "perfetto/trace_processor/basic_types.h"
+#include "perfetto/trace_processor/trace_processor_storage.h"
+#include "src/base/test/utils.h"
+#include "test/gtest_and_gmock.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace {
+
+class JsonStringOutputWriter : public json::OutputWriter {
+ public:
+ util::Status AppendString(const std::string& string) override {
+ buffer += string;
+ return util::OkStatus();
+ }
+ std::string buffer;
+};
+
+class StorageMinimalSmokeTest : public ::testing::Test {
+ public:
+ StorageMinimalSmokeTest()
+ : storage_(TraceProcessorStorage::CreateInstance(Config())) {}
+
+ protected:
+ std::unique_ptr<TraceProcessorStorage> storage_;
+};
+
+TEST_F(StorageMinimalSmokeTest, GraphicEventsIgnored) {
+ const size_t MAX_SIZE = 1 << 20;
+ auto f = fopen(base::GetTestDataPath("test/data/gpu_trace.pb").c_str(), "rb");
+ std::unique_ptr<uint8_t[]> buf(new uint8_t[MAX_SIZE]);
+ auto rsize = fread(reinterpret_cast<char*>(buf.get()), 1, MAX_SIZE, f);
+ storage_->Parse(std::move(buf), rsize);
+ storage_->NotifyEndOfFile();
+
+ JsonStringOutputWriter output_writer;
+ auto status = json::ExportJson(storage_.get(), &output_writer);
+ Json::Reader reader;
+ Json::Value result;
+ reader.parse(output_writer.buffer, result);
+
+ ASSERT_EQ(result["traceEvents"].size(), 0u);
+}
+
+TEST_F(StorageMinimalSmokeTest, TrackEventsImported) {
+ const size_t MAX_SIZE = 1 << 20;
+ auto f = fopen("test/trace_processor/track_event_typed_args.pb", "rb");
+ std::unique_ptr<uint8_t[]> buf(new uint8_t[MAX_SIZE]);
+ auto rsize = fread(reinterpret_cast<char*>(buf.get()), 1, MAX_SIZE, f);
+ storage_->Parse(std::move(buf), rsize);
+ storage_->NotifyEndOfFile();
+
+ JsonStringOutputWriter output_writer;
+ auto status = json::ExportJson(storage_.get(), &output_writer);
+ Json::Reader reader;
+ Json::Value result;
+ reader.parse(output_writer.buffer, result);
+
+ ASSERT_EQ(result["traceEvents"].size(), 4u);
+}
+
+} // namespace
+} // namespace trace_processor
+} // namespace perfetto
diff --git a/src/trace_processor/tables/macros_benchmark.cc b/src/trace_processor/tables/macros_benchmark.cc
index 008bcab..12296fd 100644
--- a/src/trace_processor/tables/macros_benchmark.cc
+++ b/src/trace_processor/tables/macros_benchmark.cc
@@ -108,7 +108,7 @@
}
BENCHMARK(BM_TableIteratorChild)->Apply(TableFilterArgs);
-static void BM_TableFilterIdColumn(benchmark::State& state) {
+static void BM_TableFilterRootId(benchmark::State& state) {
StringPool pool;
RootTestTable root(&pool, nullptr);
@@ -120,7 +120,66 @@
benchmark::DoNotOptimize(root.Filter({root.id().eq(30)}));
}
}
-BENCHMARK(BM_TableFilterIdColumn)->Apply(TableFilterArgs);
+BENCHMARK(BM_TableFilterRootId)->Apply(TableFilterArgs);
+
+static void BM_TableFilterRootIdAndOther(benchmark::State& state) {
+ StringPool pool;
+ RootTestTable root(&pool, nullptr);
+
+ uint32_t size = static_cast<uint32_t>(state.range(0));
+
+ for (uint32_t i = 0; i < size; ++i) {
+ RootTestTable::Row root_row;
+ root_row.root_non_null = i * 4;
+ root.Insert(root_row);
+ }
+
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(root.Filter(
+ {root.id().eq(root.size() - 1), root.root_non_null().gt(100)}));
+ }
+}
+BENCHMARK(BM_TableFilterRootIdAndOther)->Apply(TableFilterArgs);
+
+static void BM_TableFilterChildId(benchmark::State& state) {
+ StringPool pool;
+ RootTestTable root(&pool, nullptr);
+ ChildTestTable child(&pool, &root);
+
+ uint32_t size = static_cast<uint32_t>(state.range(0));
+ for (uint32_t i = 0; i < size; ++i) {
+ root.Insert({});
+ child.Insert({});
+ }
+
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(child.Filter({child.id().eq(30)}));
+ }
+}
+BENCHMARK(BM_TableFilterChildId)->Apply(TableFilterArgs);
+
+static void BM_TableFilterChildIdAndSortedInRoot(benchmark::State& state) {
+ StringPool pool;
+ RootTestTable root(&pool, nullptr);
+ ChildTestTable child(&pool, &root);
+
+ uint32_t size = static_cast<uint32_t>(state.range(0));
+ for (uint32_t i = 0; i < size; ++i) {
+ RootTestTable::Row root_row;
+ root_row.root_sorted = i * 2;
+ root.Insert(root_row);
+
+ ChildTestTable::Row child_row;
+ child_row.root_sorted = i * 2 + 1;
+ child.Insert(child_row);
+ }
+
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(
+ child.Filter({child.id().eq(30), child.root_sorted().gt(1024)}));
+ }
+}
+BENCHMARK(BM_TableFilterChildIdAndSortedInRoot)->Apply(TableFilterArgs);
static void BM_TableFilterRootNonNullEqMatchMany(benchmark::State& state) {
StringPool pool;
@@ -320,25 +379,6 @@
}
BENCHMARK(BM_TableFilterChildSortedEqInParent)->Apply(TableFilterArgs);
-static void BM_TableFilterIdAndOtherParent(benchmark::State& state) {
- StringPool pool;
- RootTestTable root(&pool, nullptr);
-
- uint32_t size = static_cast<uint32_t>(state.range(0));
-
- for (uint32_t i = 0; i < size; ++i) {
- RootTestTable::Row root_row;
- root_row.root_non_null = i * 4;
- root.Insert(root_row);
- }
-
- for (auto _ : state) {
- benchmark::DoNotOptimize(root.Filter(
- {root.id().eq(root.size() - 1), root.root_non_null().gt(100)}));
- }
-}
-BENCHMARK(BM_TableFilterIdAndOtherParent)->Apply(TableFilterArgs);
-
static void BM_TableSortRootNonNull(benchmark::State& state) {
StringPool pool;
RootTestTable root(&pool, nullptr);
diff --git a/src/trace_processor/trace_blob_view.h b/src/trace_processor/trace_blob_view.h
index 46cc424..7a7889b 100644
--- a/src/trace_processor/trace_blob_view.h
+++ b/src/trace_processor/trace_blob_view.h
@@ -51,7 +51,7 @@
TraceBlobView(const TraceBlobView&) = delete;
TraceBlobView& operator=(const TraceBlobView&) = delete;
- TraceBlobView slice(size_t offset, size_t length) {
+ TraceBlobView slice(size_t offset, size_t length) const {
PERFETTO_DCHECK(offset + length <= offset_ + length_);
return TraceBlobView(shbuf_, offset, length);
}
diff --git a/test/ci/linux_tests.sh b/test/ci/linux_tests.sh
index 11f60a0..62bf1c7 100755
--- a/test/ci/linux_tests.sh
+++ b/test/ci/linux_tests.sh
@@ -23,6 +23,7 @@
${OUT_PATH}/perfetto_unittests
${OUT_PATH}/perfetto_integrationtests
+${OUT_PATH}/trace_processor_minimal_smoke_tests
# If this is a split host+target build, use the trace_processoer_shell binary
# from the host directory. In some cases (e.g. lsan x86 builds) the host binary
diff --git a/test/trace_processor/clock_sync.out b/test/trace_processor/clock_sync.out
index 77ee53f..aca328a 100644
--- a/test/trace_processor/clock_sync.out
+++ b/test/trace_processor/clock_sync.out
@@ -4,4 +4,7 @@
1003,7
1005,9
2006,11
-3007,13
+2010,12
+2013,13
+3007,14
+3010,15
diff --git a/test/trace_processor/clock_sync.py b/test/trace_processor/clock_sync.py
index 9dded25..e097024 100644
--- a/test/trace_processor/clock_sync.py
+++ b/test/trace_processor/clock_sync.py
@@ -68,10 +68,25 @@
# This counter should be translated @ BOOTTIME : 3000 + 7
trace.add_gpu_counter(
- ts=7, clock_id=SEQ_CLOCK1, counter_id=42, value=13, seq_id=3)
+ ts=7, clock_id=SEQ_CLOCK1, counter_id=42, value=14, seq_id=3)
# This counter should be translated @ BOOTTIME : 2000 + 6
trace.add_gpu_counter(
ts=6, clock_id=SEQ_CLOCK1, seq_id=2, counter_id=42, value=11)
+# Set default clock for sequence 2.
+defaults_packet = trace.add_packet()
+defaults_packet.trusted_packet_sequence_id = 2
+defaults_packet.trace_packet_defaults.timestamp_clock_id = SEQ_CLOCK1
+
+# This counter should be translated @ BOOTTIME : 2000 + 10
+trace.add_gpu_counter(ts=10, seq_id=2, counter_id=42, value=12)
+
+# Manually specified clock_id overrides the default clock.
+trace.add_gpu_counter(
+ ts=2013, clock_id=CLOCK_BOOTTIME, seq_id=2, counter_id=42, value=13)
+
+# Other sequence's default clock isn't changed, so this should be in BOOTTIME.
+trace.add_gpu_counter(ts=3010, counter_id=42, value=15, seq_id=3)
+
print(trace.trace.SerializeToString())
diff --git a/test/trace_processor/index b/test/trace_processor/index
index 6793acd..1d6dee0 100644
--- a/test/trace_processor/index
+++ b/test/trace_processor/index
@@ -151,6 +151,7 @@
track_event_same_tids.textproto track_event_slices.sql track_event_same_tids_slices.out
track_event_typed_args.textproto track_event_slices.sql track_event_typed_args_slices.out
track_event_typed_args.textproto track_event_args.sql track_event_typed_args_args.out
+track_event_tracks.textproto track_event_slices.sql track_event_tracks_slices.out
# Parsing of an html file with systrace data inside
../data/systrace.html systrace_html.sql systrace_html.out
diff --git a/test/trace_processor/track_event_same_tids_slices.out b/test/trace_processor/track_event_same_tids_slices.out
index 350acf9..48fa77b 100644
--- a/test/trace_processor/track_event_same_tids_slices.out
+++ b/test/trace_processor/track_event_same_tids_slices.out
@@ -1,3 +1,3 @@
-"ts","dur","category","name","arg_set_id"
-1000,0,"cat","name1",0
-2000,0,"cat","name2",0
+"thread","ts","dur","category","name","arg_set_id"
+"t1",1000,0,"cat","name1",0
+"t2",2000,0,"cat","name2",0
diff --git a/test/trace_processor/track_event_slices.sql b/test/trace_processor/track_event_slices.sql
index 68772b4..42f7b69 100644
--- a/test/trace_processor/track_event_slices.sql
+++ b/test/trace_processor/track_event_slices.sql
@@ -13,4 +13,14 @@
-- See the License for the specific language governing permissions and
-- limitations under the License.
--
-select ts, dur, category, name, arg_set_id from slice order by ts asc;
\ No newline at end of file
+select
+ thread.name as thread,
+ slice.ts,
+ slice.dur,
+ slice.category,
+ slice.name,
+ slice.arg_set_id
+from slice
+left join thread_track on slice.track_id = thread_track.id
+left join thread on thread_track.utid = thread.utid
+order by ts asc;
diff --git a/test/trace_processor/track_event_tracks.textproto b/test/trace_processor/track_event_tracks.textproto
new file mode 100644
index 0000000..fd8cdc8
--- /dev/null
+++ b/test/trace_processor/track_event_tracks.textproto
@@ -0,0 +1,69 @@
+# Sequence 1 defaults to track for "t1".
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 0
+ incremental_state_cleared: true
+ track_descriptor {
+ uuid: 1
+ thread {
+ pid: 5
+ tid: 1
+ thread_name: "t1"
+ }
+ }
+ trace_packet_defaults {
+ track_event_defaults {
+ track_uuid: 1
+ }
+ }
+}
+# Sequence 2 defaults to track for "t2".
+packet {
+ trusted_packet_sequence_id: 2
+ timestamp: 0
+ incremental_state_cleared: true
+ track_descriptor {
+ uuid: 2
+ thread {
+ pid: 5
+ tid: 2
+ thread_name: "t2"
+ }
+ }
+ trace_packet_defaults {
+ track_event_defaults {
+ track_uuid: 2
+ }
+ }
+}
+# Should appear on default track "t1".
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 1000
+ track_event {
+ categories: "cat"
+ name: "name1"
+ type: 3
+ }
+}
+# Should appear on default track "t2".
+packet {
+ trusted_packet_sequence_id: 2
+ timestamp: 2000
+ track_event {
+ categories: "cat"
+ name: "name2"
+ type: 3
+ }
+}
+# Should appear on overridden track "t2".
+packet {
+ trusted_packet_sequence_id: 1
+ timestamp: 3000
+ track_event {
+ track_uuid: 2
+ categories: "cat"
+ name: "name3"
+ type: 3
+ }
+}
diff --git a/test/trace_processor/track_event_tracks_slices.out b/test/trace_processor/track_event_tracks_slices.out
new file mode 100644
index 0000000..93c7186
--- /dev/null
+++ b/test/trace_processor/track_event_tracks_slices.out
@@ -0,0 +1,4 @@
+"thread","ts","dur","category","name","arg_set_id"
+"t1",1000,0,"cat","name1",0
+"t2",2000,0,"cat","name2",0
+"t2",3000,0,"cat","name3",0
diff --git a/test/trace_processor/track_event_typed_args.pb b/test/trace_processor/track_event_typed_args.pb
new file mode 100644
index 0000000..c478cb0
--- /dev/null
+++ b/test/trace_processor/track_event_typed_args.pb
Binary files differ
diff --git a/test/trace_processor/track_event_typed_args_slices.out b/test/trace_processor/track_event_typed_args_slices.out
index d280266..6a9a969 100644
--- a/test/trace_processor/track_event_typed_args_slices.out
+++ b/test/trace_processor/track_event_typed_args_slices.out
@@ -1,4 +1,4 @@
-"ts","dur","category","name","arg_set_id"
-1000,0,"cat","name1",2
-2000,0,"cat","name2",3
-3000,0,"cat","name3",4
+"thread","ts","dur","category","name","arg_set_id"
+"t1",1000,0,"cat","name1",2
+"t1",2000,0,"cat","name2",3
+"t1",3000,0,"cat","name3",4