Merge "Use bigint time (almost) everywhere - Pt.2"
diff --git a/Android.bp b/Android.bp
index f4f9a2d..af0f50d 100644
--- a/Android.bp
+++ b/Android.bp
@@ -2035,6 +2035,7 @@
":perfetto_src_shared_lib_test_utils",
":perfetto_src_trace_processor_containers_containers",
":perfetto_src_trace_processor_db_db",
+ ":perfetto_src_trace_processor_db_overlays_overlays",
":perfetto_src_trace_processor_export_json",
":perfetto_src_trace_processor_importers_android_bugreport_android_bugreport",
":perfetto_src_trace_processor_importers_common_common",
@@ -9408,6 +9409,11 @@
],
}
+// GN: //src/trace_processor/db/overlays:overlays
+filegroup {
+ name: "perfetto_src_trace_processor_db_overlays_overlays",
+}
+
// GN: //src/trace_processor/db:unittests
filegroup {
name: "perfetto_src_trace_processor_db_unittests",
@@ -12033,6 +12039,7 @@
":perfetto_src_trace_processor_containers_containers",
":perfetto_src_trace_processor_containers_unittests",
":perfetto_src_trace_processor_db_db",
+ ":perfetto_src_trace_processor_db_overlays_overlays",
":perfetto_src_trace_processor_db_unittests",
":perfetto_src_trace_processor_export_json",
":perfetto_src_trace_processor_importers_android_bugreport_android_bugreport",
@@ -12730,6 +12737,7 @@
":perfetto_src_protozero_protozero",
":perfetto_src_trace_processor_containers_containers",
":perfetto_src_trace_processor_db_db",
+ ":perfetto_src_trace_processor_db_overlays_overlays",
":perfetto_src_trace_processor_export_json",
":perfetto_src_trace_processor_importers_android_bugreport_android_bugreport",
":perfetto_src_trace_processor_importers_common_common",
@@ -12955,6 +12963,7 @@
":perfetto_src_protozero_protozero",
":perfetto_src_trace_processor_containers_containers",
":perfetto_src_trace_processor_db_db",
+ ":perfetto_src_trace_processor_db_overlays_overlays",
":perfetto_src_trace_processor_export_json",
":perfetto_src_trace_processor_importers_android_bugreport_android_bugreport",
":perfetto_src_trace_processor_importers_common_common",
@@ -13095,15 +13104,22 @@
"src/traced/service/main.cc",
],
shared_libs: [
- "liblog",
"libperfetto",
],
+ host_supported: true,
init_rc: [
"perfetto.rc",
],
defaults: [
"perfetto_defaults",
],
+ target: {
+ android: {
+ shared_libs: [
+ "liblog",
+ ],
+ },
+ },
}
// GN: //src/profiling/perf:traced_perf
diff --git a/BUILD b/BUILD
index 195292f..e350b2c 100644
--- a/BUILD
+++ b/BUILD
@@ -73,6 +73,7 @@
":src_kernel_utils_syscall_table",
":src_protozero_proto_ring_buffer",
":src_trace_processor_db_db",
+ ":src_trace_processor_db_overlays_overlays",
":src_trace_processor_export_json",
":src_trace_processor_importers_android_bugreport_android_bugreport",
":src_trace_processor_importers_common_common",
@@ -1271,6 +1272,14 @@
linkstatic = True,
)
+# GN target: //src/trace_processor/db/overlays:overlays
+perfetto_filegroup(
+ name = "src_trace_processor_db_overlays_overlays",
+ srcs = [
+ "src/trace_processor/db/overlays/column_overlay.h",
+ ],
+)
+
# GN target: //src/trace_processor/db:db
perfetto_filegroup(
name = "src_trace_processor_db_db",
@@ -4991,6 +5000,7 @@
srcs = [
":src_kernel_utils_syscall_table",
":src_trace_processor_db_db",
+ ":src_trace_processor_db_overlays_overlays",
":src_trace_processor_export_json",
":src_trace_processor_importers_android_bugreport_android_bugreport",
":src_trace_processor_importers_common_common",
@@ -5147,6 +5157,7 @@
":src_profiling_symbolizer_symbolizer",
":src_protozero_proto_ring_buffer",
":src_trace_processor_db_db",
+ ":src_trace_processor_db_overlays_overlays",
":src_trace_processor_export_json",
":src_trace_processor_importers_android_bugreport_android_bugreport",
":src_trace_processor_importers_common_common",
@@ -5362,6 +5373,7 @@
":src_profiling_symbolizer_symbolizer",
":src_protozero_proto_ring_buffer",
":src_trace_processor_db_db",
+ ":src_trace_processor_db_overlays_overlays",
":src_trace_processor_export_json",
":src_trace_processor_importers_android_bugreport_android_bugreport",
":src_trace_processor_importers_common_common",
diff --git a/src/base/utils.cc b/src/base/utils.cc
index 198daa9..82386fa 100644
--- a/src/base/utils.cc
+++ b/src/base/utils.cc
@@ -55,9 +55,16 @@
#define PERFETTO_M_PURGE -101
#endif // M_PURGE
+#ifdef M_PURGE_ALL
+#define PERFETTO_M_PURGE_ALL M_PURGE_ALL
+#else
+// Only available in in-tree builds and on newer SDKs.
+#define PERFETTO_M_PURGE_ALL -104
+#endif // M_PURGE
+
namespace {
extern "C" {
-using MalloptType = void (*)(int, int);
+using MalloptType = int (*)(int, int);
}
} // namespace
#endif // OS_ANDROID
@@ -140,7 +147,9 @@
reinterpret_cast<MalloptType>(dlsym(RTLD_DEFAULT, "mallopt"));
if (!mallopt_fn)
return;
- mallopt_fn(PERFETTO_M_PURGE, 0);
+ if (mallopt_fn(PERFETTO_M_PURGE_ALL, 0) == 0) {
+ mallopt_fn(PERFETTO_M_PURGE, 0);
+ }
#endif
}
diff --git a/src/trace_processor/db/BUILD.gn b/src/trace_processor/db/BUILD.gn
index 043b2af..848db44 100644
--- a/src/trace_processor/db/BUILD.gn
+++ b/src/trace_processor/db/BUILD.gn
@@ -50,6 +50,7 @@
"../../../include/perfetto/trace_processor",
"../containers",
"../util:glob",
+ "overlays",
]
}
diff --git a/src/trace_processor/db/column_overlay.cc b/src/trace_processor/db/column_overlay.cc
index 599a3b2..690256f 100644
--- a/src/trace_processor/db/column_overlay.cc
+++ b/src/trace_processor/db/column_overlay.cc
@@ -20,7 +20,7 @@
namespace trace_processor {
namespace column {
-ColumnOverlay::~ColumnOverlay() = default;
+ColumnOverlayOld::~ColumnOverlayOld() = default;
} // namespace column
} // namespace trace_processor
diff --git a/src/trace_processor/db/column_overlay.h b/src/trace_processor/db/column_overlay.h
index e3bad53..14c6123 100644
--- a/src/trace_processor/db/column_overlay.h
+++ b/src/trace_processor/db/column_overlay.h
@@ -31,9 +31,9 @@
// done on the storage. This is a composable design - one ColumnOverlay
// subclass might hold another subclass, and each of them implements all of the
// functions in it's own specific way.
-class ColumnOverlay {
+class ColumnOverlayOld {
public:
- virtual ~ColumnOverlay();
+ virtual ~ColumnOverlayOld();
// Clears the rows of RowMap, on which data don't match the FilterOp operation
// with SqlValue. Efficient.
diff --git a/src/trace_processor/db/null_overlay.h b/src/trace_processor/db/null_overlay.h
index 43d2fed..cd573a4 100644
--- a/src/trace_processor/db/null_overlay.h
+++ b/src/trace_processor/db/null_overlay.h
@@ -28,9 +28,9 @@
namespace column {
// Overlay responsible for operations related to column nullability.
-class NullOverlay : public ColumnOverlay {
+class NullOverlay : public ColumnOverlayOld {
public:
- explicit NullOverlay(std::unique_ptr<ColumnOverlay> inner,
+ explicit NullOverlay(std::unique_ptr<ColumnOverlayOld> inner,
const BitVector* null_bv)
: inner_(std::move(inner)), null_bv_(null_bv) {}
@@ -38,7 +38,7 @@
void StableSort(uint32_t* rows, uint32_t rows_size) const override;
private:
- std::unique_ptr<ColumnOverlay> inner_;
+ std::unique_ptr<ColumnOverlayOld> inner_;
// Vector of data nullability.
const BitVector* null_bv_;
diff --git a/src/trace_processor/db/numeric_storage.cc b/src/trace_processor/db/numeric_storage.cc
index 3b66e22..1957dc1 100644
--- a/src/trace_processor/db/numeric_storage.cc
+++ b/src/trace_processor/db/numeric_storage.cc
@@ -93,12 +93,14 @@
val);
}
+void NumericStorage::Sort(uint32_t*, uint32_t) const {}
+
// Responsible for invoking templated version of FastPathComparison.
-void NumericStorage::CompareFast(FilterOp op,
- SqlValue sql_val,
- uint32_t offset,
- uint32_t num_elements,
- BitVector::Builder& builder) const {
+void NumericStorage::LinearSearchAligned(FilterOp op,
+ SqlValue sql_val,
+ uint32_t offset,
+ uint32_t num_elements,
+ BitVector::Builder& builder) const {
PERFETTO_DCHECK(num_elements % BitVector::kBitsInWord == 0);
std::optional<NumericValue> val = GetNumericTypeVariant(type_, sql_val);
@@ -119,11 +121,11 @@
}
// Responsible for invoking templated version of SlowPathComparison.
-void NumericStorage::CompareSlow(FilterOp op,
- SqlValue sql_val,
- uint32_t offset,
- uint32_t num_elements,
- BitVector::Builder& builder) const {
+void NumericStorage::LinearSearchUnaligned(FilterOp op,
+ SqlValue sql_val,
+ uint32_t offset,
+ uint32_t num_elements,
+ BitVector::Builder& builder) const {
std::optional<NumericValue> val = GetNumericTypeVariant(type_, sql_val);
// If the value is invalid we should just ignore those elements.
@@ -142,13 +144,14 @@
*val);
}
-uint32_t NumericStorage::UpperBoundIndex(NumericValue val) const {
+uint32_t NumericStorage::UpperBoundIndex(NumericValue val,
+ Range search_range) const {
return std::visit(
- [this](auto val_data) {
+ [this, search_range](auto val_data) {
using T = decltype(val_data);
const T* typed_start = static_cast<const T*>(data_);
- auto upper =
- std::upper_bound(typed_start, typed_start + size_, val_data);
+ auto upper = std::upper_bound(typed_start + search_range.start,
+ typed_start + search_range.end, val_data);
return static_cast<uint32_t>(std::distance(typed_start, upper));
},
val);
@@ -156,76 +159,59 @@
// As we don't template those functions, we need to use std::visitor to type
// `start`, hence this wrapping.
-uint32_t NumericStorage::LowerBoundIndex(NumericValue val) const {
+uint32_t NumericStorage::LowerBoundIndex(NumericValue val,
+ Range search_range) const {
return std::visit(
- [this](auto val_data) {
+ [this, search_range](auto val_data) {
using T = decltype(val_data);
const T* typed_start = static_cast<const T*>(data_);
- auto lower =
- std::lower_bound(typed_start, typed_start + size_, val_data);
+ auto lower = std::lower_bound(typed_start + search_range.start,
+ typed_start + search_range.end, val_data);
return static_cast<uint32_t>(std::distance(typed_start, lower));
},
val);
}
-void NumericStorage::CompareSorted(FilterOp op,
- SqlValue sql_val,
- RowMap& rm) const {
+std::optional<Range> NumericStorage::BinarySearch(FilterOp op,
+ SqlValue sql_val,
+ Range search_range) const {
std::optional<NumericValue> val = GetNumericTypeVariant(type_, sql_val);
- if (!val.has_value() || op == FilterOp::kIsNotNull ||
- op == FilterOp::kIsNull || op == FilterOp::kGlob) {
- rm.Clear();
- return;
- }
+ if (op == FilterOp::kIsNotNull)
+ return Range(0, size());
+
+ if (!val)
+ return std::nullopt;
switch (op) {
- case FilterOp::kEq: {
- uint32_t beg = LowerBoundIndex(*val);
- uint32_t end = UpperBoundIndex(*val);
- RowMap sec(beg, end);
- rm.Intersect(sec);
- return;
- }
- case FilterOp::kLe: {
- uint32_t end = UpperBoundIndex(*val);
- RowMap sec(0, end);
- rm.Intersect(sec);
- return;
- }
- case FilterOp::kLt: {
- uint32_t end = LowerBoundIndex(*val);
- RowMap sec(0, end);
- rm.Intersect(sec);
- return;
- }
- case FilterOp::kGe: {
- uint32_t beg = LowerBoundIndex(*val);
- RowMap sec(beg, size_);
- rm.Intersect(sec);
- return;
- }
- case FilterOp::kGt: {
- uint32_t beg = UpperBoundIndex(*val);
- RowMap sec(beg, size_);
- rm.Intersect(sec);
- return;
- }
+ case FilterOp::kEq:
+ return Range(LowerBoundIndex(*val, search_range),
+ UpperBoundIndex(*val, search_range));
+ case FilterOp::kLe:
+ return Range(0, UpperBoundIndex(*val, search_range));
+ case FilterOp::kLt:
+ return Range(0, LowerBoundIndex(*val, search_range));
+ case FilterOp::kGe:
+ return Range(LowerBoundIndex(*val, search_range), size_);
+ case FilterOp::kGt:
+ return Range(UpperBoundIndex(*val, search_range), size_);
case FilterOp::kNe:
case FilterOp::kIsNull:
case FilterOp::kIsNotNull:
case FilterOp::kGlob:
- rm.Clear();
+ return std::nullopt;
}
- return;
+ return std::nullopt;
}
uint32_t NumericStorage::UpperBoundIndex(NumericValue val,
- uint32_t* order) const {
+ uint32_t* order,
+ Range search_range) const {
return std::visit(
- [this, order](auto val_data) {
+ [this, order, search_range](auto val_data) {
using T = decltype(val_data);
const T* typed_start = static_cast<const T*>(data_);
- auto upper = std::upper_bound(order, order + size_, val_data,
+ auto upper = std::upper_bound(order + search_range.start,
+ order + search_range.end, val_data,
[typed_start](T val, uint32_t index) {
return val < *(typed_start + index);
});
@@ -237,12 +223,14 @@
// As we don't template those functions, we need to use std::visitor to type
// `start`, hence this wrapping.
uint32_t NumericStorage::LowerBoundIndex(NumericValue val,
- uint32_t* order) const {
+ uint32_t* order,
+ Range search_range) const {
return std::visit(
- [this, order](auto val_data) {
+ [this, order, search_range](auto val_data) {
using T = decltype(val_data);
const T* typed_start = static_cast<const T*>(data_);
- auto lower = std::lower_bound(order, order + size_, val_data,
+ auto lower = std::lower_bound(order + search_range.start,
+ order + search_range.end, val_data,
[typed_start](uint32_t index, T val) {
return *(typed_start + index) < val;
});
@@ -251,56 +239,38 @@
val);
}
-void NumericStorage::CompareSortedIndexes(FilterOp op,
- SqlValue sql_val,
- uint32_t* order,
- RowMap& rm) const {
+std::optional<Range> NumericStorage::BinarySearchWithIndex(
+ FilterOp op,
+ SqlValue sql_val,
+ uint32_t* order,
+ Range search_range) const {
std::optional<NumericValue> val = GetNumericTypeVariant(type_, sql_val);
- if (!val.has_value() || op == FilterOp::kIsNotNull ||
- op == FilterOp::kIsNull || op == FilterOp::kGlob) {
- rm.Clear();
- return;
- }
+
+ if (op == FilterOp::kIsNotNull)
+ return Range(0, size());
+
+ if (!val.has_value())
+ return std::nullopt;
switch (op) {
- case FilterOp::kEq: {
- uint32_t beg = LowerBoundIndex(*val, order);
- uint32_t end = UpperBoundIndex(*val, order);
- std::vector<uint32_t> index(order + beg, order + end);
- rm.Intersect(RowMap(std::move(index)));
- return;
- }
- case FilterOp::kLe: {
- uint32_t end = UpperBoundIndex(*val, order);
- std::vector<uint32_t> index(order, order + end);
- rm.Intersect(RowMap(std::move(index)));
- return;
- }
- case FilterOp::kLt: {
- uint32_t end = LowerBoundIndex(*val, order);
- std::vector<uint32_t> index(order, order + end);
- rm.Intersect(RowMap(std::move(index)));
- return;
- }
- case FilterOp::kGe: {
- uint32_t beg = LowerBoundIndex(*val, order);
- std::vector<uint32_t> index(order + beg, order + size_);
- rm.Intersect(RowMap(std::move(index)));
- return;
- }
- case FilterOp::kGt: {
- uint32_t beg = UpperBoundIndex(*val, order);
- std::vector<uint32_t> index(order + beg, order + size_);
- rm.Intersect(RowMap(std::move(index)));
- return;
- }
+ case FilterOp::kEq:
+ return Range(LowerBoundIndex(*val, order, search_range),
+ UpperBoundIndex(*val, order, search_range));
+ case FilterOp::kLe:
+ return Range(0, UpperBoundIndex(*val, order, search_range));
+ case FilterOp::kLt:
+ return Range(0, LowerBoundIndex(*val, order, search_range));
+ case FilterOp::kGe:
+ return Range(LowerBoundIndex(*val, order, search_range), size_);
+ case FilterOp::kGt:
+ return Range(UpperBoundIndex(*val, order, search_range), size_);
case FilterOp::kNe:
case FilterOp::kIsNull:
case FilterOp::kIsNotNull:
case FilterOp::kGlob:
- rm.Clear();
+ return std::nullopt;
}
- return;
+ return std::nullopt;
}
} // namespace column
diff --git a/src/trace_processor/db/numeric_storage.h b/src/trace_processor/db/numeric_storage.h
index a85044b..0ed8852 100644
--- a/src/trace_processor/db/numeric_storage.h
+++ b/src/trace_processor/db/numeric_storage.h
@@ -33,43 +33,51 @@
void StableSort(uint32_t* rows, uint32_t rows_size) const override;
- void CompareFast(FilterOp op,
- SqlValue val,
- uint32_t offset,
- uint32_t num_elements,
- BitVector::Builder& builder) const override;
+ void Sort(uint32_t* rows, uint32_t rows_size) const override;
- void CompareSlow(FilterOp op,
- SqlValue val,
- uint32_t offset,
- uint32_t num_elements,
- BitVector::Builder& builder) const override;
+ void LinearSearchAligned(FilterOp op,
+ SqlValue val,
+ uint32_t offset,
+ uint32_t num_elements,
+ BitVector::Builder& builder) const override;
- void CompareSorted(FilterOp op, SqlValue val, RowMap&) const override;
+ void LinearSearchUnaligned(FilterOp op,
+ SqlValue val,
+ uint32_t offset,
+ uint32_t num_elements,
+ BitVector::Builder& builder) const override;
- void CompareSortedIndexes(FilterOp op,
- SqlValue val,
- uint32_t* order,
- RowMap&) const override;
+ std::optional<Range> BinarySearch(FilterOp op,
+ SqlValue val,
+ Range search_range) const override;
+
+ std::optional<Range> BinarySearchWithIndex(FilterOp op,
+ SqlValue val,
+ uint32_t* order,
+ Range search_range) const override;
uint32_t size() const override { return size_; }
private:
// As we don't template those functions, we need to use std::visitor to type
// `start`, hence this wrapping.
- uint32_t UpperBoundIndex(NumericValue val) const;
+ uint32_t UpperBoundIndex(NumericValue val, Range search_range) const;
// As we don't template those functions, we need to use std::visitor to type
// `start`, hence this wrapping.
- uint32_t LowerBoundIndex(NumericValue val) const;
+ uint32_t LowerBoundIndex(NumericValue val, Range search_range) const;
// As we don't template those functions, we need to use std::visitor to type
// `start`, hence this wrapping.
- uint32_t UpperBoundIndex(NumericValue val, uint32_t* order) const;
+ uint32_t UpperBoundIndex(NumericValue val,
+ uint32_t* order,
+ Range search_range) const;
// As we don't template those functions, we need to use std::visitor to type
// `start`, hence this wrapping.
- uint32_t LowerBoundIndex(NumericValue val, uint32_t* order) const;
+ uint32_t LowerBoundIndex(NumericValue val,
+ uint32_t* order,
+ Range search_range) const;
const ColumnType type_;
const void* data_;
diff --git a/src/trace_processor/db/overlays/BUILD.gn b/src/trace_processor/db/overlays/BUILD.gn
new file mode 100644
index 0000000..abc47d7
--- /dev/null
+++ b/src/trace_processor/db/overlays/BUILD.gn
@@ -0,0 +1,18 @@
+# Copyright (C) 2023 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.
+
+source_set("overlays") {
+ sources = [ "column_overlay.h" ]
+ deps = [ "../../containers" ]
+}
diff --git a/src/trace_processor/db/overlays/column_overlay.h b/src/trace_processor/db/overlays/column_overlay.h
new file mode 100644
index 0000000..661debe
--- /dev/null
+++ b/src/trace_processor/db/overlays/column_overlay.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 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.
+ */
+
+#ifndef SRC_TRACE_PROCESSOR_DB_OVERLAYS_COLUMN_OVERLAY_H_
+#define SRC_TRACE_PROCESSOR_DB_OVERLAYS_COLUMN_OVERLAY_H_
+
+#include <variant>
+#include "perfetto/ext/base/status_or.h"
+#include "src/trace_processor/db/column.h"
+#include "src/trace_processor/db/storage.h"
+
+namespace perfetto {
+namespace trace_processor {
+namespace column {
+
+enum class SearchAlgorithm {
+ kLinearSearch,
+ kBinarySearch,
+};
+
+// Column overlay introduce separation between column storage (vector of data)
+// and state (nullability, sorting) and actions (filtering, expanding, joining)
+// done on the storage. This is a composable design - one Overlay is
+// DecidingSearchAlgorithm based on the result of the same function from
+// previous Overlay.
+class ColumnOverlay {
+ public:
+ virtual ~ColumnOverlay();
+
+ // Returns the RowMap without information added by overlay. The result would
+ // be used by the overlay one step closer to Storage. For example, for
+ // NullOverlay it would be returning RowMap that would be only of the length
+ // of set bits in a bit vector.
+ virtual RowMap TranslateDown(RowMap) const = 0;
+
+ // Returns the RowMap with information added by overlay. The result would be
+ // used by the overlay one step closer to the Table. For example, for
+ // NullOverlay it would be returning RowMap that would be the length of bit
+ // vector, nulls included.
+ virtual RowMap TranslateUp(RowMap) const = 0;
+
+ // Decides what search algorithm should be called based on the type of overlay
+ // and passed SearchAlgorithm.
+ virtual SearchAlgorithm DecideSearchAlgorithm(SearchAlgorithm) const = 0;
+};
+} // namespace column
+} // namespace trace_processor
+} // namespace perfetto
+
+#endif // SRC_TRACE_PROCESSOR_DB_OVERLAYS_COLUMN_OVERLAY_H_
diff --git a/src/trace_processor/db/row_order_overlay.cc b/src/trace_processor/db/row_order_overlay.cc
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/src/trace_processor/db/row_order_overlay.cc
diff --git a/src/trace_processor/db/storage.h b/src/trace_processor/db/storage.h
index 41e616f..8157a13 100644
--- a/src/trace_processor/db/storage.h
+++ b/src/trace_processor/db/storage.h
@@ -24,43 +24,55 @@
namespace trace_processor {
namespace column {
-// Most base column interpreting layer - responsible for implementing operations
-// that require looking at the data, such as comparison or sorting.
+using Range = RowMap::Range;
+
+// Most base column interpreting layer - responsible for implementing searches
+// and sorting.
class Storage {
public:
virtual ~Storage();
- // Changes the vector of indices to represent the sorted state of the column.
+ // Changes the vector of indices to represent the sorted (stable sort) state
+ // of the column.
virtual void StableSort(uint32_t* rows, uint32_t rows_size) const = 0;
+ // Changes the vector of indices to represent the sorted (not stable) state of
+ // the column.
+ virtual void Sort(uint32_t* rows, uint32_t rows_size) const = 0;
+
// Efficiently compares series of |num_elements| of data from |data_start| to
// comparator value and appends results to BitVector::Builder. Should be used
- // on as much data as possible.
- virtual void CompareFast(FilterOp op,
- SqlValue value,
- uint32_t offset,
- uint32_t compare_elements_count,
- BitVector::Builder&) const = 0;
+ // where possible
+ virtual void LinearSearchAligned(FilterOp op,
+ SqlValue value,
+ uint32_t offset,
+ uint32_t compare_elements_count,
+ BitVector::Builder&) const = 0;
// Inefficiently compares series of |num_elements| of data from |data_start|
// to comparator value and appends results to BitVector::Builder. Should be
- // avoided if possible, with `FastSeriesComparison` used instead.
- virtual void CompareSlow(FilterOp op,
- SqlValue value,
- uint32_t offset,
- uint32_t compare_elements_count,
- BitVector::Builder&) const = 0;
+ // avoided if possible, with `LinearSearchAligned` used instead.
+ virtual void LinearSearchUnaligned(FilterOp op,
+ SqlValue value,
+ uint32_t offset,
+ uint32_t compare_elements_count,
+ BitVector::Builder&) const = 0;
- // Compares sorted (asc) series data with comparator value. Should be used
- // where possible.
- virtual void CompareSorted(FilterOp op, SqlValue value, RowMap&) const = 0;
+ // Compares sorted (asc) series data in |range| with comparator value. Should
+ // be used where possible. Returns the Range of indices which match the
+ // constraint.
+ virtual std::optional<Range> BinarySearch(FilterOp op,
+ SqlValue value,
+ Range search_range) const = 0;
- // Compares sorted (asc) with `order` vector series with comparator value.
- // Should be used where possible.
- virtual void CompareSortedIndexes(FilterOp op,
- SqlValue value,
- uint32_t* order,
- RowMap&) const = 0;
+ // Compares sorted (asc) with |order| vector series in |range| with comparator
+ // value. Should be used where possible. Returns the Range of indices
+ // inside |order| vector which match the constraint.
+ virtual std::optional<Range> BinarySearchWithIndex(
+ FilterOp op,
+ SqlValue value,
+ uint32_t* order,
+ Range search_range) const = 0;
// Number of elements in stored data.
virtual uint32_t size() const = 0;
diff --git a/src/trace_processor/db/storage_overlay.cc b/src/trace_processor/db/storage_overlay.cc
index 2ab4fde..daefc34 100644
--- a/src/trace_processor/db/storage_overlay.cc
+++ b/src/trace_processor/db/storage_overlay.cc
@@ -35,18 +35,19 @@
// Slow path: we compare <64 elements and append to get us to a word
// boundary.
uint32_t front_elements = builder.BitsUntilWordBoundaryOrFull();
- storage_->CompareSlow(op, value, 0, front_elements, builder);
+ storage_->LinearSearchUnaligned(op, value, 0, front_elements, builder);
uint32_t cur_index = front_elements;
// Fast path: we compare as many groups of 64 elements as we can.
// This should be very easy for the compiler to auto-vectorize.
uint32_t fast_path_elements = builder.BitsInCompleteWordsUntilFull();
- storage_->CompareFast(op, value, cur_index, fast_path_elements, builder);
+ storage_->LinearSearchAligned(op, value, cur_index, fast_path_elements,
+ builder);
cur_index += fast_path_elements;
// Slow path: we compare <64 elements and append to fill the Builder.
uint32_t back_elements = builder.BitsUntilFull();
- storage_->CompareSlow(op, value, cur_index, back_elements, builder);
+ storage_->LinearSearchUnaligned(op, value, cur_index, back_elements, builder);
BitVector bv = std::move(builder).Build();
rm.Intersect(RowMap(std::move(bv)));
diff --git a/src/trace_processor/db/storage_overlay.h b/src/trace_processor/db/storage_overlay.h
index 9b0b5ec..1c3a7de 100644
--- a/src/trace_processor/db/storage_overlay.h
+++ b/src/trace_processor/db/storage_overlay.h
@@ -28,7 +28,7 @@
namespace column {
// Overlay responsible for doing operations on storage.
-class StorageOverlay : public ColumnOverlay {
+class StorageOverlay : public ColumnOverlayOld {
public:
explicit StorageOverlay(const Storage* storage) : storage_(storage) {}
void Filter(FilterOp, SqlValue, RowMap&) const override;
diff --git a/src/trace_processor/db/storage_unittest.cc b/src/trace_processor/db/storage_unittest.cc
index 8988c00..05e5e4e 100644
--- a/src/trace_processor/db/storage_unittest.cc
+++ b/src/trace_processor/db/storage_unittest.cc
@@ -57,7 +57,8 @@
std::iota(data_vec.begin(), data_vec.end(), 0);
NumericStorage storage(data_vec.data(), size, ColumnType::kUint32);
BitVector::Builder builder(size);
- storage.CompareSlow(FilterOp::kGe, SqlValue::Long(5), 0, size, builder);
+ storage.LinearSearchUnaligned(FilterOp::kGe, SqlValue::Long(5), 0, size,
+ builder);
BitVector bv = std::move(builder).Build();
ASSERT_EQ(bv.CountSetBits(), 5u);
@@ -70,7 +71,8 @@
std::iota(data_vec.begin(), data_vec.end(), 0);
NumericStorage storage(data_vec.data(), size, ColumnType::kUint32);
BitVector::Builder builder(size);
- storage.CompareSlow(FilterOp::kGe, SqlValue::Long(5), 0, size, builder);
+ storage.LinearSearchUnaligned(FilterOp::kGe, SqlValue::Long(5), 0, size,
+ builder);
BitVector bv = std::move(builder).Build();
ASSERT_EQ(bv.CountSetBits(), 1020u);
@@ -82,7 +84,8 @@
std::iota(data_vec.begin(), data_vec.end(), 0);
NumericStorage storage(data_vec.data(), 128, ColumnType::kUint32);
BitVector::Builder builder(128);
- storage.CompareFast(FilterOp::kGe, SqlValue::Long(100), 0, 128, builder);
+ storage.LinearSearchAligned(FilterOp::kGe, SqlValue::Long(100), 0, 128,
+ builder);
BitVector bv = std::move(builder).Build();
ASSERT_EQ(bv.CountSetBits(), 28u);
@@ -93,11 +96,12 @@
std::vector<uint32_t> data_vec(128);
std::iota(data_vec.begin(), data_vec.end(), 0);
NumericStorage storage(data_vec.data(), 128, ColumnType::kUint32);
- RowMap rm(0, 128);
- storage.CompareSorted(FilterOp::kGe, SqlValue::Long(100), rm);
+ std::optional<Range> range =
+ storage.BinarySearch(FilterOp::kGe, SqlValue::Long(100), Range(0, 128));
- ASSERT_EQ(rm.size(), 28u);
- ASSERT_EQ(rm.Get(0), 100u);
+ ASSERT_EQ(range->size(), 28u);
+ ASSERT_EQ(range->start, 100u);
+ ASSERT_EQ(range->end, 128u);
}
TEST(NumericStorageUnittest, CompareSortedIndexesGreaterEqual) {
@@ -105,16 +109,13 @@
std::vector<uint32_t> sorted_order{7, 8, 9, 0, 1, 2, 3, 6, 5, 4};
NumericStorage storage(data_vec.data(), 10, ColumnType::kUint32);
- RowMap rm(0, 10);
- storage.CompareSortedIndexes(FilterOp::kGe, SqlValue::Long(60),
- sorted_order.data(), rm);
+ std::optional<Range> range = storage.BinarySearchWithIndex(
+ FilterOp::kGe, SqlValue::Long(60), sorted_order.data(), Range(0, 10));
- ASSERT_EQ(rm.size(), 4u);
- ASSERT_EQ(rm.Get(0), 3u);
- ASSERT_EQ(rm.Get(1), 6u);
- ASSERT_EQ(rm.Get(2), 5u);
- ASSERT_EQ(rm.Get(3), 4u);
+ ASSERT_EQ(range->size(), 4u);
+ ASSERT_EQ(range->start, 6u);
+ ASSERT_EQ(range->end, 10u);
}
TEST(NumericStorageUnittest, CompareSortedIndexesLess) {
@@ -122,13 +123,13 @@
std::vector<uint32_t> sorted_order{7, 8, 9, 0, 1, 2, 3, 6, 5, 4};
NumericStorage storage(data_vec.data(), 10, ColumnType::kUint32);
- RowMap rm(0, 10);
- storage.CompareSortedIndexes(FilterOp::kLt, SqlValue::Long(60),
- sorted_order.data(), rm);
+ std::optional<Range> range = storage.BinarySearchWithIndex(
+ FilterOp::kLt, SqlValue::Long(60), sorted_order.data(), Range(0, 10));
- ASSERT_EQ(rm.size(), 6u);
- ASSERT_EQ(rm.Get(0), 7u);
+ ASSERT_EQ(range->size(), 6u);
+ ASSERT_EQ(range->start, 0u);
+ ASSERT_EQ(range->end, 6u);
}
TEST(NumericStorageUnittest, CompareSortedIndexesEqual) {
@@ -136,13 +137,13 @@
std::vector<uint32_t> sorted_order{7, 8, 9, 0, 1, 2, 3, 6, 5, 4};
NumericStorage storage(data_vec.data(), 10, ColumnType::kUint32);
- RowMap rm(0, 10);
- storage.CompareSortedIndexes(FilterOp::kEq, SqlValue::Long(60),
- sorted_order.data(), rm);
+ std::optional<Range> range = storage.BinarySearchWithIndex(
+ FilterOp::kEq, SqlValue::Long(60), sorted_order.data(), Range(0, 10));
- ASSERT_EQ(rm.size(), 1u);
- ASSERT_EQ(rm.Get(0), 3u);
+ ASSERT_EQ(range->size(), 1u);
+ ASSERT_EQ(range->start, 6u);
+ ASSERT_EQ(range->end, 7u);
}
TEST(StorageOverlayUnittests, FilterIsNull) {
@@ -201,7 +202,8 @@
BitVector bv = BitVector::Range(0, 20, [](uint32_t t) { return t % 2 == 0; });
NumericStorage storage(data_vec.data(), 10, ColumnType::kUint32);
- std::unique_ptr<ColumnOverlay> storage_overlay(new StorageOverlay(&storage));
+ std::unique_ptr<ColumnOverlayOld> storage_overlay(
+ new StorageOverlay(&storage));
NullOverlay overlay(std::move(storage_overlay), &bv);
RowMap rm(0, 10);
@@ -215,7 +217,8 @@
std::iota(data_vec.begin(), data_vec.end(), 0);
NumericStorage storage(data_vec.data(), 10, ColumnType::kUint32);
BitVector bv = BitVector::Range(0, 20, [](uint32_t t) { return t % 2 == 0; });
- std::unique_ptr<ColumnOverlay> storage_overlay(new StorageOverlay(&storage));
+ std::unique_ptr<ColumnOverlayOld> storage_overlay(
+ new StorageOverlay(&storage));
NullOverlay overlay(std::move(storage_overlay), &bv);
RowMap rm(0, 10);
@@ -237,7 +240,8 @@
// Prepare NullOverlay
BitVector bv =
BitVector::Range(0, bv_size, [](uint32_t t) { return t % 2 == 0; });
- std::unique_ptr<ColumnOverlay> storage_overlay(new StorageOverlay(&storage));
+ std::unique_ptr<ColumnOverlayOld> storage_overlay(
+ new StorageOverlay(&storage));
NullOverlay overlay(std::move(storage_overlay), &bv);
RowMap rm(0, bv_size);
@@ -259,7 +263,8 @@
// Prepare NullOverlay
BitVector bv =
BitVector::Range(800, bv_size, [](uint32_t t) { return t % 2 == 0; });
- std::unique_ptr<ColumnOverlay> storage_overlay(new StorageOverlay(&storage));
+ std::unique_ptr<ColumnOverlayOld> storage_overlay(
+ new StorageOverlay(&storage));
NullOverlay overlay(std::move(storage_overlay), &bv);
RowMap rm(0, bv_size);
@@ -278,7 +283,8 @@
// Prepare NullOverlay
BitVector bv = BitVector::Range(0, 18, [](uint32_t t) { return t % 2 == 0; });
- std::unique_ptr<ColumnOverlay> storage_overlay(new StorageOverlay(&storage));
+ std::unique_ptr<ColumnOverlayOld> storage_overlay(
+ new StorageOverlay(&storage));
NullOverlay overlay(std::move(storage_overlay), &bv);
overlay.StableSort(out.data(), 18);
diff --git a/src/trace_processor/metrics/sql/android/android_batt.sql b/src/trace_processor/metrics/sql/android/android_batt.sql
index b88d7ed..a5cfd5a 100644
--- a/src/trace_processor/metrics/sql/android/android_batt.sql
+++ b/src/trace_processor/metrics/sql/android/android_batt.sql
@@ -14,6 +14,7 @@
-- limitations under the License.
--
SELECT IMPORT('android.battery');
+SELECT IMPORT('android.battery_stats');
DROP VIEW IF EXISTS battery_view;
CREATE VIEW battery_view AS
@@ -182,7 +183,26 @@
END AS slice_name,
'Plug type' AS track_name,
'slice' AS track_type
-FROM plug_type_span;
+FROM plug_type_span
+UNION ALL
+SELECT *
+FROM (
+ SELECT ts,
+ dur,
+ value_name AS slice_name,
+ CASE track_name
+ WHEN 'battery_stats.mobile_radio' THEN 'Cellular radio'
+ WHEN 'battery_stats.data_conn' THEN 'Cellular connection'
+ WHEN 'battery_stats.phone_signal_strength' THEN 'Cellular strength'
+ WHEN 'battery_stats.wifi_radio' THEN 'WiFi radio'
+ WHEN 'battery_stats.wifi_suppl' THEN 'Wifi supplicant state'
+ WHEN 'battery_stats.wifi_signal_strength' THEN 'WiFi strength'
+ ELSE NULL
+ END AS track_name,
+ 'slice' AS track_type
+ FROM android_battery_stats_state
+)
+WHERE track_name IS NOT NULL;
DROP VIEW IF EXISTS android_batt_output;
CREATE VIEW android_batt_output AS
diff --git a/src/trace_processor/metrics/sql/android/network_activity_template.sql b/src/trace_processor/metrics/sql/android/network_activity_template.sql
index 2dcfa31..aa163c2 100644
--- a/src/trace_processor/metrics/sql/android/network_activity_template.sql
+++ b/src/trace_processor/metrics/sql/android/network_activity_template.sql
@@ -34,6 +34,7 @@
-- @column dur The duration of the current segment.
-- @column packet_count The total number of packets in this segment.
-- @column packet_length The total number of bytes for packets in this segment.
+DROP VIEW IF EXISTS {{view_name}};
CREATE VIEW {{view_name}} AS
WITH quantized AS (
SELECT
diff --git a/src/trace_processor/stdlib/android/battery_stats.sql b/src/trace_processor/stdlib/android/battery_stats.sql
index 2507cb1..30cea54 100644
--- a/src/trace_processor/stdlib/android/battery_stats.sql
+++ b/src/trace_processor/stdlib/android/battery_stats.sql
@@ -18,10 +18,10 @@
-- Converts a battery_stats counter value to human readable string.
--
-- @arg track STRING The counter track name (e.g. 'battery_stats.audio').
--- @arg value LONG The counter value.
+-- @arg value FLOAT The counter value.
-- @ret STRING The human-readable name for the counter value.
SELECT CREATE_FUNCTION(
- 'BATTERY_STATS_COUNTER_TO_STRING(track STRING, value FLOAT)',
+ 'ANDROID_BATTERY_STATS_COUNTER_TO_STRING(track STRING, value FLOAT)',
'STRING',
'
SELECT
@@ -71,7 +71,7 @@
THEN
CASE $value
WHEN 0 THEN "invalid"
- WHEN 1 THEN "disconn"
+ WHEN 1 THEN "disconnected"
WHEN 2 THEN "disabled"
WHEN 3 THEN "inactive"
WHEN 4 THEN "scanning"
@@ -82,35 +82,35 @@
WHEN 9 THEN "group-handshake"
WHEN 10 THEN "completed"
WHEN 11 THEN "dormant"
- WHEN 12 THEN "uninit"
+ WHEN 12 THEN "uninitialized"
ELSE "unknown"
END
WHEN $track = "battery_stats.data_conn"
THEN
CASE $value
- WHEN 0 THEN "oos"
- WHEN 1 THEN "gprs"
- WHEN 2 THEN "edge"
- WHEN 3 THEN "umts"
- WHEN 4 THEN "cdma"
- WHEN 5 THEN "evdo_0"
- WHEN 6 THEN "evdo_A"
- WHEN 7 THEN "1xrtt"
- WHEN 8 THEN "hsdpa"
- WHEN 9 THEN "hsupa"
- WHEN 10 THEN "hspa"
- WHEN 11 THEN "iden"
- WHEN 12 THEN "evdo_b"
- WHEN 13 THEN "lte"
- WHEN 14 THEN "ehrpd"
- WHEN 15 THEN "hspap"
- WHEN 16 THEN "gsm"
- WHEN 17 THEN "td_scdma"
- WHEN 18 THEN "iwlan"
- WHEN 19 THEN "lte_ca"
- WHEN 20 THEN "nr"
- WHEN 21 THEN "emngcy"
- WHEN 22 THEN "other"
+ WHEN 0 THEN "Out of service"
+ WHEN 1 THEN "2.5G (GPRS)"
+ WHEN 2 THEN "2.7G (EDGE)"
+ WHEN 3 THEN "3G (UMTS)"
+ WHEN 4 THEN "3G (CDMA)"
+ WHEN 5 THEN "3G (EVDO Rel 0)"
+ WHEN 6 THEN "3G (EVDO Rev A)"
+ WHEN 7 THEN "3G (LXRTT)"
+ WHEN 8 THEN "3.5G (HSDPA)"
+ WHEN 9 THEN "3.5G (HSUPA)"
+ WHEN 10 THEN "3.5G (HSPA)"
+ WHEN 11 THEN "2G (IDEN)"
+ WHEN 12 THEN "3G (EVDO Rev B)"
+ WHEN 13 THEN "4G (LTE)"
+ WHEN 14 THEN "3.5G (eHRPD)"
+ WHEN 15 THEN "3.7G (HSPA+)"
+ WHEN 16 THEN "2G (GSM)"
+ WHEN 17 THEN "3G (TD SCDMA)"
+ WHEN 18 THEN "Wifi calling (IWLAN)"
+ WHEN 19 THEN "4.5G (LTE CA)"
+ WHEN 20 THEN "5G (NR)"
+ WHEN 21 THEN "Emergency calls only"
+ WHEN 22 THEN "Other"
ELSE "unknown"
END
ELSE CAST($value AS text)
@@ -133,8 +133,8 @@
ts,
name AS track_name,
CAST(value AS INT64) AS value,
- BATTERY_STATS_COUNTER_TO_STRING(name, value) AS value_name,
- IFNULL(LEAD(ts) OVER (PARTITION BY track_id ORDER BY ts) - ts, -1) AS dur
+ ANDROID_BATTERY_STATS_COUNTER_TO_STRING(name, value) AS value_name,
+ IFNULL(LEAD(ts) OVER (PARTITION BY name ORDER BY ts) - ts, -1) AS dur
FROM counter
JOIN counter_track
ON counter.track_id = counter_track.id
diff --git a/src/trace_processor/stdlib/android/monitor_contention.sql b/src/trace_processor/stdlib/android/monitor_contention.sql
index 595c1fe..9fae0c7 100644
--- a/src/trace_processor/stdlib/android/monitor_contention.sql
+++ b/src/trace_processor/stdlib/android/monitor_contention.sql
@@ -145,7 +145,7 @@
AS
SELECT ancestor.parent_id AS id FROM slice
JOIN slice ancestor ON ancestor.id = slice.parent_id
- WHERE ancestor.name LIKE 'Lock contention on a monitor lock%'
+ WHERE ancestor.name GLOB 'Lock contention on a monitor lock*'
GROUP BY ancestor.id;
-- Contains parsed monitor contention slices.
@@ -211,7 +211,7 @@
LEFT JOIN thread_track binder_reply_thread_track ON binder_reply.track_id = binder_reply_thread_track.id
LEFT JOIN thread binder_reply_thread ON binder_reply_thread_track.utid = binder_reply_thread.utid
JOIN thread blocking_thread ON blocking_thread.tid = blocking_tid AND blocking_thread.upid = thread.upid
-WHERE slice.name LIKE 'monitor contention%'
+WHERE slice.name GLOB 'monitor contention*'
AND slice.dur != -1
AND internal_broken_android_monitor_contention.id IS NULL
AND short_blocking_method IS NOT NULL
@@ -247,13 +247,34 @@
LEFT JOIN android_monitor_contention parent ON child.blocked_utid = parent.blocking_utid
AND parent.ts BETWEEN child.ts AND child.ts + child.dur;
+-- First blocked node on a lock, i.e nodes with |waiter_count| = 0. The |dur| here is adjusted
+-- to only account for the time between the first thread waiting and the first thread to acquire
+-- the lock. That way, the thread state span joins below only compute the thread states where
+-- the blocking thread is actually holding the lock. This avoids counting the time when another
+-- waiter acquired the lock before the first waiter.
+CREATE VIEW internal_first_blocked_contention
+ AS
+SELECT start.id, start.blocking_utid, start.ts, MIN(end.ts + end.dur) - start.ts AS dur
+FROM android_monitor_contention_chain start
+JOIN android_monitor_contention_chain END
+ ON
+ start.blocking_utid = end.blocking_utid
+ AND start.blocking_method = end.blocking_method
+ AND end.ts BETWEEN start.ts AND start.ts + start.dur
+WHERE start.waiter_count = 0
+GROUP BY start.id;
+
CREATE VIEW internal_blocking_thread_state
AS
SELECT utid AS blocking_utid, ts, dur, state, blocked_function
FROM thread_state;
--- Contains the span join of the |android_monitor_contention_chain| with their
--- blocking thread thread state.
+-- Contains the span join of the first waiters in the |android_monitor_contention_chain| with their
+-- blocking_thread thread state.
+
+-- Note that we only span join the duration where the lock was actually held and contended.
+-- This can be less than the duration the lock was 'waited on' when a different waiter acquired the
+-- lock earlier than the first waiter.
--
-- @column parent_id Id of slice blocking the blocking_thread.
-- @column blocking_method Name of the method holding the lock.
@@ -282,14 +303,16 @@
-- @column blocked_function Blocked kernel function of the blocking thread.
CREATE VIRTUAL TABLE android_monitor_contention_chain_thread_state
USING
- SPAN_JOIN(android_monitor_contention_chain PARTITIONED blocking_utid,
+ SPAN_JOIN(internal_first_blocked_contention PARTITIONED blocking_utid,
internal_blocking_thread_state PARTITIONED blocking_utid);
--- Aggregated blocked_functions on the 'blocking thread', the thread holding the lock.
+-- Aggregated thread_states on the 'blocking thread', the thread holding the lock.
-- This builds on the data from |android_monitor_contention_chain| and
-- for each contention slice, it returns the aggregated sum of all the thread states on the
-- blocking thread.
--
+-- Note that this data is only available for the first waiter on a lock.
+--
-- @column id Slice id of the monitor contention.
-- @column thread_state A |thread_state| that occurred in the blocking thread during the contention.
-- @column thread_state_dur Total time the blocking thread spent in the |thread_state| during
@@ -311,6 +334,8 @@
-- for each contention, it returns the aggregated sum of all the kernel
-- blocked function durations on the blocking thread.
--
+-- Note that this data is only available for the first waiter on a lock.
+--
-- @column id Slice id of the monitor contention.
-- @column blocked_function Blocked kernel function in a thread state in the blocking thread during
-- the contention.
diff --git a/src/trace_processor/trace_processor_shell.cc b/src/trace_processor/trace_processor_shell.cc
index da08183..44df9a9 100644
--- a/src/trace_processor/trace_processor_shell.cc
+++ b/src/trace_processor/trace_processor_shell.cc
@@ -763,7 +763,7 @@
builds. The features behind this flag can
break at any time without any warning.
-Standard library:
+Standard library:
--add-sql-module MODULE_PATH Files from the directory will be treated
as a new SQL module and can be used for
IMPORT. The name of the directory is the
@@ -1016,10 +1016,11 @@
return command_line_options;
}
-void ExtendPoolWithBinaryDescriptor(google::protobuf::DescriptorPool& pool,
- const void* data,
- int size,
- std::vector<std::string>& skip_prefixes) {
+void ExtendPoolWithBinaryDescriptor(
+ google::protobuf::DescriptorPool& pool,
+ const void* data,
+ int size,
+ const std::vector<std::string>& skip_prefixes) {
google::protobuf::FileDescriptorSet desc_set;
PERFETTO_CHECK(desc_set.ParseFromArray(data, size));
for (const auto& file_desc : desc_set.file()) {
@@ -1237,7 +1238,8 @@
}
base::Status LoadMetricExtensionProtos(const std::string& proto_root,
- const std::string& mount_path) {
+ const std::string& mount_path,
+ google::protobuf::DescriptorPool& pool) {
if (!base::FileExists(proto_root)) {
return base::ErrStatus(
"Directory %s does not exist. Metric extension directory must contain "
@@ -1262,6 +1264,11 @@
serialized_filedescset.data(),
static_cast<int>(serialized_filedescset.size()));
+ // Extend the pool for any subsequent reflection-based operations
+ // (e.g. output json)
+ ExtendPoolWithBinaryDescriptor(
+ pool, serialized_filedescset.data(),
+ static_cast<int>(serialized_filedescset.size()), {});
RETURN_IF_ERROR(g_tp->ExtendMetricsProto(serialized_filedescset.data(),
serialized_filedescset.size()));
@@ -1293,7 +1300,8 @@
return base::OkStatus();
}
-base::Status LoadMetricExtension(const MetricExtension& extension) {
+base::Status LoadMetricExtension(const MetricExtension& extension,
+ google::protobuf::DescriptorPool& pool) {
const std::string& disk_path = extension.disk_path();
const std::string& virtual_path = extension.virtual_path();
@@ -1305,8 +1313,8 @@
// Note: Proto files must be loaded first, because we determine whether an SQL
// file is a metric or not by checking if the name matches a field of the root
// TraceMetrics proto.
- RETURN_IF_ERROR(LoadMetricExtensionProtos(disk_path + "protos/",
- kMetricProtoRoot + virtual_path));
+ RETURN_IF_ERROR(LoadMetricExtensionProtos(
+ disk_path + "protos/", kMetricProtoRoot + virtual_path, pool));
RETURN_IF_ERROR(LoadMetricExtensionSql(disk_path + "sql/", virtual_path));
return base::OkStatus();
@@ -1585,11 +1593,21 @@
tp->EnableMetatrace(metatrace_config);
}
+ // Descriptor pool used for printing output as textproto. Building on top of
+ // generated pool so default protos in google.protobuf.descriptor.proto are
+ // available.
+ // For some insane reason, the descriptor pool is not movable so we need to
+ // create it here so we can create references and pass it everywhere.
+ google::protobuf::DescriptorPool pool(
+ google::protobuf::DescriptorPool::generated_pool());
+ RETURN_IF_ERROR(PopulateDescriptorPool(pool, metric_extensions));
+
// We load all the metric extensions even when --run-metrics arg is not there,
// because we want the metrics to be available in interactive mode or when
// used in UI using httpd.
+ // Metric extensions are also used to populate the descriptor pool.
for (const auto& extension : metric_extensions) {
- RETURN_IF_ERROR(LoadMetricExtension(extension));
+ RETURN_IF_ERROR(LoadMetricExtension(extension, pool));
}
base::TimeNanos t_load{};
@@ -1616,14 +1634,6 @@
RETURN_IF_ERROR(RunQueries(options.pre_metrics_path, false));
}
- // Descriptor pool used for printing output as textproto. Building on top of
- // generated pool so default protos in google.protobuf.descriptor.proto are
- // available.
- // For some insane reason, the descriptor pool is not movable so we need to
- // create it here so we can create references and pass it everywhere.
- google::protobuf::DescriptorPool pool(
- google::protobuf::DescriptorPool::generated_pool());
- RETURN_IF_ERROR(PopulateDescriptorPool(pool, metric_extensions));
std::vector<MetricNameAndPath> metrics;
if (!options.metric_names.empty()) {
diff --git a/src/trace_processor/util/interned_message_view.h b/src/trace_processor/util/interned_message_view.h
index 3422b8b..f6a9a13 100644
--- a/src/trace_processor/util/interned_message_view.h
+++ b/src/trace_processor/util/interned_message_view.h
@@ -71,7 +71,9 @@
if (PERFETTO_TYPE_IDENTIFIER &&
strcmp(decoder_type_,
// GCC complains if this arg can be null.
- PERFETTO_TYPE_IDENTIFIER ? PERFETTO_TYPE_IDENTIFIER : "") != 0) {
+ static_cast<bool>(PERFETTO_TYPE_IDENTIFIER)
+ ? PERFETTO_TYPE_IDENTIFIER
+ : "") != 0) {
PERFETTO_FATAL(
"Interning entry accessed under different types! previous type: "
"%s. new type: %s.",
diff --git a/test/trace_processor/diff_tests/android/android_battery_stats_state.out b/test/trace_processor/diff_tests/android/android_battery_stats_state.out
index 04ea953..eb16850 100644
--- a/test/trace_processor/diff_tests/android/android_battery_stats_state.out
+++ b/test/trace_processor/diff_tests/android/android_battery_stats_state.out
@@ -1,4 +1,4 @@
"ts","track_name","value","value_name","dur"
1000,"battery_stats.audio",1,"active",-1
-1000,"battery_stats.data_conn",13,"lte",3000
-4000,"battery_stats.data_conn",20,"nr",-1
+1000,"battery_stats.data_conn",13,"4G (LTE)",3000
+4000,"battery_stats.data_conn",20,"5G (NR)",-1
diff --git a/test/trace_processor/diff_tests/android/android_monitor_contention.out b/test/trace_processor/diff_tests/android/android_monitor_contention.out
index 163815d..8940be9 100644
--- a/test/trace_processor/diff_tests/android/android_monitor_contention.out
+++ b/test/trace_processor/diff_tests/android/android_monitor_contention.out
@@ -1215,11 +1215,6 @@
pid: 642
is_blocked_thread_main: false
is_blocking_thread_main: false
- thread_states {
- thread_state: "R"
- thread_state_dur: 122815
- thread_state_count: 1
- }
}
node {
node_id: 914
@@ -1373,8 +1368,8 @@
is_blocking_thread_main: false
thread_states {
thread_state: "R+"
- thread_state_dur: 7143444
- thread_state_count: 4
+ thread_state_dur: 7127675
+ thread_state_count: 3
}
thread_states {
thread_state: "Running"
@@ -1404,8 +1399,8 @@
is_blocking_thread_main: false
thread_states {
thread_state: "R+"
- thread_state_dur: 7143444
- thread_state_count: 4
+ thread_state_dur: 7127675
+ thread_state_count: 3
}
thread_states {
thread_state: "Running"
@@ -1432,21 +1427,6 @@
pid: 642
is_blocked_thread_main: true
is_blocking_thread_main: false
- thread_states {
- thread_state: "R+"
- thread_state_dur: 7100855
- thread_state_count: 1
- }
- thread_states {
- thread_state: "Running"
- thread_state_dur: 40711
- thread_state_count: 1
- }
- thread_states {
- thread_state: "S"
- thread_state_dur: 2814860
- thread_state_count: 1
- }
}
node {
node_id: 983
@@ -1467,11 +1447,6 @@
pid: 642
is_blocked_thread_main: false
is_blocking_thread_main: false
- thread_states {
- thread_state: "S"
- thread_state_dur: 3054413
- thread_state_count: 1
- }
}
node {
node_id: 994
@@ -4504,11 +4479,6 @@
pid: 642
is_blocked_thread_main: false
is_blocking_thread_main: false
- thread_states {
- thread_state: "S"
- thread_state_dur: 3567249
- thread_state_count: 1
- }
}
node {
node_id: 1778
@@ -4529,11 +4499,6 @@
pid: 642
is_blocked_thread_main: false
is_blocking_thread_main: false
- thread_states {
- thread_state: "S"
- thread_state_dur: 8523903
- thread_state_count: 1
- }
}
node {
node_id: 1786
@@ -4554,11 +4519,6 @@
pid: 642
is_blocked_thread_main: false
is_blocking_thread_main: false
- thread_states {
- thread_state: "S"
- thread_state_dur: 9607080
- thread_state_count: 1
- }
}
node {
node_id: 1819
@@ -4614,11 +4574,6 @@
pid: 642
is_blocked_thread_main: false
is_blocking_thread_main: false
- thread_states {
- thread_state: "S"
- thread_state_dur: 10733654
- thread_state_count: 1
- }
}
node {
node_id: 1825
@@ -5221,26 +5176,6 @@
pid: 642
is_blocked_thread_main: false
is_blocking_thread_main: false
- thread_states {
- thread_state: "R"
- thread_state_dur: 59191
- thread_state_count: 1
- }
- thread_states {
- thread_state: "R+"
- thread_state_dur: 223496
- thread_state_count: 1
- }
- thread_states {
- thread_state: "Running"
- thread_state_dur: 36279
- thread_state_count: 2
- }
- thread_states {
- thread_state: "S"
- thread_state_dur: 583889
- thread_state_count: 1
- }
}
node {
node_id: 2289
@@ -5261,11 +5196,6 @@
pid: 642
is_blocked_thread_main: false
is_blocking_thread_main: false
- thread_states {
- thread_state: "S"
- thread_state_dur: 1514707
- thread_state_count: 1
- }
}
node {
node_id: 2352
@@ -6873,26 +6803,6 @@
is_blocking_thread_main: false
binder_reply_ts: 1739927686578
binder_reply_tid: 657
- thread_states {
- thread_state: "R"
- thread_state_dur: 819671
- thread_state_count: 3
- }
- thread_states {
- thread_state: "R+"
- thread_state_dur: 600233
- thread_state_count: 2
- }
- thread_states {
- thread_state: "Running"
- thread_state_dur: 890957
- thread_state_count: 5
- }
- thread_states {
- thread_state: "S"
- thread_state_dur: 623113
- thread_state_count: 2
- }
}
node {
node_id: 13948
@@ -6935,16 +6845,6 @@
pid: 642
is_blocked_thread_main: false
is_blocking_thread_main: false
- thread_states {
- thread_state: "Running"
- thread_state_dur: 480064
- thread_state_count: 1
- }
- thread_states {
- thread_state: "S"
- thread_state_dur: 1685676
- thread_state_count: 1
- }
}
node {
node_id: 13979
@@ -7222,16 +7122,6 @@
is_blocking_thread_main: false
binder_reply_ts: 1739956996641
binder_reply_tid: 2721
- thread_states {
- thread_state: "R"
- thread_state_dur: 70662
- thread_state_count: 1
- }
- thread_states {
- thread_state: "Running"
- thread_state_dur: 92726
- thread_state_count: 1
- }
}
node {
node_id: 14154
@@ -7629,26 +7519,6 @@
pid: 642
is_blocked_thread_main: false
is_blocking_thread_main: true
- thread_states {
- thread_state: "R"
- thread_state_dur: 105075
- thread_state_count: 1
- }
- thread_states {
- thread_state: "R+"
- thread_state_dur: 69326
- thread_state_count: 1
- }
- thread_states {
- thread_state: "Running"
- thread_state_dur: 722485
- thread_state_count: 3
- }
- thread_states {
- thread_state: "S"
- thread_state_dur: 267110
- thread_state_count: 2
- }
}
node {
node_id: 14623
@@ -7669,11 +7539,6 @@
pid: 642
is_blocked_thread_main: false
is_blocking_thread_main: true
- thread_states {
- thread_state: "S"
- thread_state_dur: 1129545
- thread_state_count: 1
- }
}
node {
node_id: 14626
@@ -7716,11 +7581,6 @@
pid: 642
is_blocked_thread_main: true
is_blocking_thread_main: false
- thread_states {
- thread_state: "Running"
- thread_state_dur: 388360
- thread_state_count: 1
- }
}
node {
node_id: 14730
@@ -8045,11 +7905,6 @@
pid: 642
is_blocked_thread_main: false
is_blocking_thread_main: false
- thread_states {
- thread_state: "R+"
- thread_state_dur: 473837
- thread_state_count: 1
- }
}
node {
node_id: 15361
diff --git a/test/trace_processor/diff_tests/android/tests.py b/test/trace_processor/diff_tests/android/tests.py
index 84bafc1..2dc6615 100644
--- a/test/trace_processor/diff_tests/android/tests.py
+++ b/test/trace_processor/diff_tests/android/tests.py
@@ -436,41 +436,19 @@
13934,"D",11950576,1
"""))
- def test_monitor_contention_chain_extraction(self):
+ def test_monitor_contention_chain_extraction_parent(self):
return DiffTestBlueprint(
trace=DataPath('android_monitor_contention_trace.atr'),
query="""
SELECT IMPORT('android.monitor_contention');
- SELECT
- IIF(parent_id IS NULL, "", parent_id) AS parent_id,
- blocking_method,
- blocked_method,
- short_blocking_method,
- short_blocked_method,
- blocking_src,
- blocked_src,
- waiter_count,
- blocked_utid,
- blocked_thread_name,
- blocking_utid,
- blocking_thread_name,
- upid,
- process_name,
- id,
- ts,
- dur,
- is_blocked_thread_main,
- is_blocking_thread_main,
- IIF(binder_reply_id IS NULL, "", binder_reply_id) AS binder_reply_id,
- IIF(binder_reply_ts IS NULL, "", binder_reply_ts) AS binder_reply_ts,
- IIF(binder_reply_tid IS NULL, "", binder_reply_tid) AS binder_reply_tid
- FROM android_monitor_contention_chain
+ SELECT * FROM android_monitor_contention_chain
+ WHERE parent_id IS NOT NULL
ORDER BY dur DESC
LIMIT 1;
""",
out=Csv("""
- "parent_id","blocking_method","blocked_method","short_blocking_method","short_blocked_method","blocking_src","blocked_src","waiter_count","blocked_utid","blocked_thread_name","blocking_utid","blocking_thread_name","upid","process_name","id","ts","dur","is_blocked_thread_main","is_blocking_thread_main","binder_reply_id","binder_reply_ts","binder_reply_tid"
- "","void com.android.server.am.ActivityManagerService.forceStopPackage(java.lang.String, int)","boolean com.android.server.am.ActivityManagerService.unbindService(android.app.IServiceConnection)","com.android.server.am.ActivityManagerService.forceStopPackage","com.android.server.am.ActivityManagerService.unbindService","ActivityManagerService.java:3992","ActivityManagerService.java:12719",0,640,"StorageUserConn",495,"binder:642_1",250,"system_server",327,1737063410007,46114664,0,0,"","",""
+ "parent_id","blocking_method","blocked_method","short_blocking_method","short_blocked_method","blocking_src","blocked_src","waiter_count","blocked_utid","blocked_thread_name","blocking_utid","blocking_thread_name","blocking_tid","upid","process_name","id","ts","dur","track_id","is_blocked_thread_main","blocked_thread_tid","is_blocking_thread_main","blocking_thread_tid","binder_reply_id","binder_reply_ts","binder_reply_tid","pid"
+ 956,"void com.android.server.am.AppProfiler.collectPssInBackground()","void com.android.server.am.ProcessRecord.setPid(int)","com.android.server.am.AppProfiler.collectPssInBackground","com.android.server.am.ProcessRecord.setPid","AppProfiler.java:514","ProcessRecord.java:596",0,656,"binder:642_12",506,"android.bg",670,250,"system_server",949,1737122781871,7301144,1236,0,2720,0,670,"[NULL]","[NULL]","[NULL]",642
"""))
def test_monitor_contention_metric(self):
diff --git a/test/trace_processor/diff_tests/atrace/tests_general.py b/test/trace_processor/diff_tests/atrace/tests_general.py
deleted file mode 100644
index 59417c0..0000000
--- a/test/trace_processor/diff_tests/atrace/tests_general.py
+++ /dev/null
@@ -1,91 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2023 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 a
-#
-# 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.
-
-from python.generators.diff_tests.testing import Path, DataPath, Metric
-from python.generators.diff_tests.testing import Csv, Json, TextProto
-from python.generators.diff_tests.testing import DiffTestBlueprint
-from python.generators.diff_tests.testing import DiffTestModule
-
-
-class AtraceGeneral(DiffTestModule):
-
- def test_android_b2b_async_begin_list_slices(self):
- return DiffTestBlueprint(
- trace=Path('android_b2b_async_begin.textproto'),
- query="""
-SELECT ts, dur, name
-FROM slice;
-""",
- out=Csv("""
-"ts","dur","name"
-1000,30,"multistart"
-1015,45,"multistart"
-1030,20,"multistart"
-"""))
-
- def test_process_track_slices_android_async_slice(self):
- return DiffTestBlueprint(
- trace=Path('android_async_slice.textproto'),
- query="""
-SELECT
- ts,
- dur,
- pid,
- slice.name AS slice_name,
- process_track.name AS track_name
-FROM slice
-JOIN process_track ON slice.track_id = process_track.id
-JOIN process USING (upid);
-""",
- out=Path('process_track_slices_android_async_slice.out'))
-
- def test_async_track_atrace_process_track_slices(self):
- return DiffTestBlueprint(
- trace=Path('async_track_atrace.py'),
- query="""
-SELECT
- ts,
- dur,
- pid,
- slice.name AS slice_name,
- process_track.name AS track_name
-FROM slice
-JOIN process_track ON slice.track_id = process_track.id
-JOIN process USING (upid);
-""",
- out=Csv("""
-"ts","dur","pid","slice_name","track_name"
-50,25,1,"ev","track"
-55,15,1,"ev","track"
-60,5,2,"ev","track"
-"""))
-
- def test_sys_write_and_atrace(self):
- return DiffTestBlueprint(
- trace=Path('sys_write_and_atrace.py'),
- query="""
-SELECT slice.ts, slice.dur, slice.name, slice.depth
-FROM slice
-JOIN thread_track ON (slice.track_id = thread_track.id)
-JOIN thread USING (utid)
-WHERE tid = 42;
-""",
- out=Csv("""
-"ts","dur","name","depth"
-100,100,"sys_write",0
-300,50,"sys_write",0
-350,300,"test",0
-600,50,"sys_write",1
-"""))
diff --git a/test/trace_processor/diff_tests/camera/tests_general.py b/test/trace_processor/diff_tests/camera/tests_general.py
deleted file mode 100644
index 7277796..0000000
--- a/test/trace_processor/diff_tests/camera/tests_general.py
+++ /dev/null
@@ -1,42 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2023 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 a
-#
-# 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.
-
-from python.generators.diff_tests.testing import Path, DataPath, Metric
-from python.generators.diff_tests.testing import Csv, Json, TextProto
-from python.generators.diff_tests.testing import DiffTestBlueprint
-from python.generators.diff_tests.testing import DiffTestModule
-
-
-class CameraGeneral(DiffTestModule):
-
- def test_camera_ion_mem_trace_android_camera(self):
- return DiffTestBlueprint(
- trace=DataPath('camera-ion-mem-trace'),
- query=Metric('android_camera'),
- out=TextProto(r"""
-android_camera {
- gc_rss_and_dma {
- min: 47779840.0
- max: 2529583104.0
- avg: 1459479416.3297353
- }
-}
-"""))
-
- def test_camera_ion_mem_trace_android_camera_unagg(self):
- return DiffTestBlueprint(
- trace=DataPath('camera-ion-mem-trace'),
- query=Metric('android_camera_unagg'),
- out=Path('camera-ion-mem-trace_android_camera_unagg.out'))
diff --git a/test/trace_processor/diff_tests/chrome/index.py b/test/trace_processor/diff_tests/chrome/index.py
deleted file mode 100644
index 67e8ca4..0000000
--- a/test/trace_processor/diff_tests/chrome/index.py
+++ /dev/null
@@ -1,1427 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2023 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 a
-#
-# 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.
-
-from python.generators.diff_tests.testing import Path, Metric
-from python.generators.diff_tests.testing import Csv, Json, TextProto
-from python.generators.diff_tests.testing import DiffTestBlueprint
-from python.generators.diff_tests.testing import DiffTestModule
-
-
-class DiffTestModule_Chrome(DiffTestModule):
-
- def test_scroll_jank_general_validation(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query=Path('scroll_jank_general_validation_test.sql'),
- out=Path('scroll_jank_general_validation.out'))
-
- def test_scroll_jank(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/scroll_jank.sql');
-
-SELECT
- gesture_scroll_id,
- trace_id,
- jank,
- ts,
- dur,
- jank_budget
-FROM scroll_jank;
-""",
- out=Path('scroll_jank.out'))
-
- def test_event_latency_to_breakdowns(self):
- return DiffTestBlueprint(
- trace=Path('../../data/event_latency_with_args.perfetto-trace'),
- query="""
-SELECT RUN_METRIC('chrome/event_latency_to_breakdowns.sql');
-
-SELECT
- event_latency_ts,
- event_latency_dur,
- event_type,
- GenerationToRendererCompositorNs,
- GenerationToBrowserMainNs,
- BrowserMainToRendererCompositorNs,
- RendererCompositorQueueingDelayNs,
- unknown_stages_seen
-FROM event_latency_to_breakdowns
-ORDER BY event_latency_id
-LIMIT 30;
-""",
- out=Path('event_latency_to_breakdowns.out'))
-
- def test_event_latency_scroll_jank(self):
- return DiffTestBlueprint(
- trace=Path('../../data/event_latency_with_args.perfetto-trace'),
- query="""
-SELECT RUN_METRIC('chrome/event_latency_scroll_jank.sql');
-
-SELECT
- jank,
- next_jank,
- prev_jank,
- gesture_begin_ts,
- gesture_end_ts,
- ts,
- dur,
- event_type,
- next_ts,
- next_dur,
- prev_ts,
- prev_dur
-FROM scroll_event_latency_jank
-ORDER BY jank DESC
-LIMIT 10;
-""",
- out=Path('event_latency_scroll_jank.out'))
-
- def test_event_latency_scroll_jank_cause(self):
- return DiffTestBlueprint(
- trace=Path('../../data/event_latency_with_args.perfetto-trace'),
- query="""
-SELECT RUN_METRIC('chrome/event_latency_scroll_jank_cause.sql');
-
-SELECT
- dur,
- ts,
- event_type,
- next_jank,
- prev_jank,
- next_delta_dur_ns,
- prev_delta_dur_ns,
- cause_of_jank,
- max_delta_dur_ns,
- sub_cause_of_jank
-FROM event_latency_scroll_jank_cause
-ORDER by ts;
-""",
- out=Path('event_latency_scroll_jank_cause.out'))
-
- def test_scroll_flow_event(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/scroll_flow_event.sql');
-
-SELECT
- trace_id,
- ts,
- dur,
- jank,
- step,
- ancestor_end,
- maybe_next_ancestor_ts,
- next_ts,
- next_trace_id,
- next_step
-FROM scroll_flow_event
-ORDER BY gesture_scroll_id, trace_id, ts;
-""",
- out=Path('scroll_flow_event.out'))
-
- def test_scroll_flow_event_general_validation(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/scroll_flow_event.sql');
-
-SELECT
- -- Each trace_id (in our example trace not true in general) has 8 steps. There
- -- are 139 scrolls. So we expect 1112 rows in total 72 of which are janky.
- (
- SELECT
- COUNT(*)
- FROM (
- SELECT
- trace_id,
- COUNT(*)
- FROM scroll_flow_event
- GROUP BY trace_id
- )
- ) AS total_scroll_updates,
- (
- SELECT COUNT(*) FROM scroll_flow_event
- ) AS total_flow_event_steps,
- (
- SELECT COUNT(*) FROM scroll_flow_event WHERE jank
- ) AS total_janky_flow_event_steps,
- (
- SELECT COUNT(*) FROM (SELECT step FROM scroll_flow_event GROUP BY step)
- ) AS number_of_unique_steps;
-""",
- out=Path('scroll_flow_event_general_validation.out'))
-
- def test_scroll_jank_cause(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/scroll_jank_cause.sql');
-
-SELECT
- COUNT(*) AS total,
- SUM(jank) AS total_jank,
- SUM(explained_jank + unexplained_jank) AS sum_explained_and_unexplained,
- SUM(
- CASE WHEN explained_jank THEN
- unexplained_jank
- ELSE
- CASE WHEN jank AND NOT unexplained_jank THEN
- 1
- ELSE
- 0
- END
- END
- ) AS error_rows
-FROM scroll_jank_cause;
-""",
- out=Csv("""
-"total","total_jank","sum_explained_and_unexplained","error_rows"
-139,7,7,0
-"""))
-
- def test_scroll_flow_event_queuing_delay(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/scroll_flow_event_queuing_delay.sql');
-
-SELECT
- trace_id,
- jank,
- step,
- next_step,
- ancestor_end,
- maybe_next_ancestor_ts,
- queuing_time_ns
-FROM scroll_flow_event_queuing_delay
-WHERE trace_id = 2954 OR trace_id = 2956 OR trace_id = 2960
-ORDER BY trace_id, ts;
-""",
- out=Path('scroll_flow_event_queuing_delay.out'))
-
- def test_scroll_flow_event_general_validation_2(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query=Path(
- 'scroll_flow_event_queuing_delay_general_validation_test.sql'),
- out=Path('scroll_flow_event_general_validation.out'))
-
- def test_scroll_jank_cause_queuing_delay(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
-
-SELECT
- process_name,
- thread_name,
- trace_id,
- jank,
- dur_overlapping_ns,
- metric_name
-FROM scroll_jank_cause_queuing_delay
-WHERE trace_id = 2918 OR trace_id = 2926
-ORDER BY trace_id ASC, ts ASC;
-""",
- out=Path('scroll_jank_cause_queuing_delay.out'))
-
- def test_scroll_jank_cause_queuing_delay_restricted(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
-
-SELECT
- process_name,
- thread_name,
- trace_id,
- jank,
- dur_overlapping_ns,
- restricted_metric_name
-FROM scroll_jank_cause_queuing_delay
-WHERE trace_id = 2918 OR trace_id = 2926
-ORDER BY trace_id ASC, ts ASC;
-""",
- out=Path('scroll_jank_cause_queuing_delay_restricted.out'))
-
- def test_scroll_jank_cause_queuing_delay_general_validation(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
-
-SELECT
- COUNT(*) AS total,
- (
- SELECT DISTINCT
- (avg_no_jank_dur_overlapping_ns)
- FROM scroll_jank_cause_queuing_delay
- WHERE
- location = "LatencyInfo.Flow"
- AND jank
- ) AS janky_latency_info_non_jank_avg_dur,
- (
- SELECT DISTINCT
- (avg_no_jank_dur_overlapping_ns)
- FROM scroll_jank_cause_queuing_delay
- WHERE
- location = "LatencyInfo.Flow"
- AND NOT jank
- ) AS non_janky_latency_info_non_jank_avg_dur
-FROM (
- SELECT
- trace_id
- FROM scroll_jank_cause_queuing_delay
- GROUP BY trace_id
-);
-""",
- out=Path('scroll_jank_cause_queuing_delay_general_validation.out'))
-
- def test_chrome_thread_slice(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_thread_slice.sql');
-
-SELECT
- EXTRACT_ARG(arg_set_id, 'chrome_latency_info.trace_id') AS trace_id,
- dur,
- thread_dur
-FROM chrome_thread_slice
-WHERE
- name = 'LatencyInfo.Flow'
- AND EXTRACT_ARG(arg_set_id, 'chrome_latency_info.trace_id') = 2734;
-""",
- out=Csv("""
-"trace_id","dur","thread_dur"
-2734,25000,25000
-2734,1000,2000
-2734,2000,2000
-2734,258000,171000
-2734,1000,1000
-"""))
-
- def test_chrome_input_to_browser_intervals(self):
- return DiffTestBlueprint(
- trace=Path(
- '../../data/scrolling_with_blocked_nonblocked_frames.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_input_to_browser_intervals.sql');
-
-SELECT
- *
-FROM chrome_input_to_browser_intervals
-WHERE window_start_ts >= 60934320005158
- AND window_start_ts <= 60934338798158;
-""",
- out=Path('chrome_input_to_browser_intervals.out'))
-
- def test_chrome_scroll_jank_caused_by_scheduling_test(self):
- return DiffTestBlueprint(
- trace=Path('../../data/fling_with_input_delay.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_scroll_jank_caused_by_scheduling.sql',
- 'dur_causes_jank_ms',
-/* dur_causes_jank_ms = */ '5');
-
-SELECT
- full_name,
- total_duration_ms,
- total_thread_duration_ms,
- count,
- window_start_ts,
- window_end_ts,
- scroll_type
-FROM chrome_scroll_jank_caused_by_scheduling;
-""",
- out=Path('chrome_scroll_jank_caused_by_scheduling_test.out'))
-
- def test_chrome_tasks_delaying_input_processing_test(self):
- return DiffTestBlueprint(
- trace=Path('../../data/fling_with_input_delay.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_tasks_delaying_input_processing.sql',
- 'duration_causing_jank_ms',
- /* duration_causing_jank_ms = */ '8');
-
-SELECT
- full_name,
- duration_ms,
- thread_dur_ms
-FROM chrome_tasks_delaying_input_processing;
-""",
- out=Path('chrome_tasks_delaying_input_processing_test.out'))
-
- def test_long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_test(
- self):
- return DiffTestBlueprint(
- trace=Path('../../data/long_task_tracking_trace'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_long_tasks_delaying_input_processing.sql');
-
-SELECT
- full_name,
- duration_ms,
- slice_id
-FROM chrome_tasks_delaying_input_processing
-ORDER BY slice_id;
-""",
- out=Path(
- 'long_task_tracking_trace_chrome_long_tasks_delaying_input_processing_test.out'
- ))
-
- def test_experimental_reliable_chrome_tasks_delaying_input_processing_test(
- self):
- return DiffTestBlueprint(
- trace=Path('../../data/fling_with_input_delay.pftrace'),
- query="""
-SELECT RUN_METRIC(
- 'chrome/experimental_reliable_chrome_tasks_delaying_input_processing.sql',
- 'duration_causing_jank_ms', '8');
-
-SELECT
- full_name,
- duration_ms,
- thread_dur_ms
-FROM chrome_tasks_delaying_input_processing;
-""",
- out=Path(
- 'experimental_reliable_chrome_tasks_delaying_input_processing_test.out'
- ))
-
- def test_chrome_scroll_inputs_per_frame_test(self):
- return DiffTestBlueprint(
- trace=Path(
- '../../data/scrolling_with_blocked_nonblocked_frames.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_scroll_inputs_per_frame.sql');
-
-SELECT
- count_for_frame,
- ts
-FROM chrome_scroll_inputs_per_frame
-WHERE ts = 60934316798158;
-""",
- out=Csv("""
-"count_for_frame","ts"
-4,60934316798158
-"""))
-
- def test_chrome_thread_slice_repeated(self):
- return DiffTestBlueprint(
- trace=Path('../track_event/track_event_counters.textproto'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_thread_slice.sql');
-
-SELECT
- name,
- ts,
- dur,
- thread_dur
-FROM chrome_thread_slice;
-""",
- out=Csv("""
-"name","ts","dur","thread_dur"
-"event1_on_t1",1000,100,10000
-"event2_on_t1",2000,200,30000
-"event3_on_t1",2000,200,10000
-"event4_on_t1",4000,0,0
-"float_counter_on_t1",4300,0,"[NULL]"
-"float_counter_on_t1",4500,0,"[NULL]"
-"event1_on_t3",4000,100,5000
-"""))
-
- def test_frame_times_metric(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_rendering_desktop.pftrace'),
- query=Metric('frame_times'),
- out=Path('frame_times_metric.out'))
-
- def test_chrome_dropped_frames_metric(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_rendering_desktop.pftrace'),
- query=Metric('chrome_dropped_frames'),
- out=TextProto(r"""
-[perfetto.protos.chrome_dropped_frames]: {
- dropped_frame: {
- ts: 166479338462000
- process_name: "Renderer"
- pid: 12743
- }
- dropped_frame: {
- ts: 166479355302000
- process_name: "Renderer"
- pid: 12743
- }
-}"""))
-
- def test_chrome_long_latency_metric(self):
- return DiffTestBlueprint(
- trace=Path('../chrome/long_event_latency.textproto'),
- query="""
-SELECT RUN_METRIC('experimental/chrome_long_latency.sql');
-
-SELECT * FROM long_latency_with_process_info;
-""",
- out=Csv("""
-"ts","event_type","process_name","process_id"
-200111000,"FirstGestureScrollUpdate,GestureScrollUpdate","Renderer",1001
-200111000,"GestureScrollUpdate","Renderer",1002
-280111001,"GestureScrollUpdate","Renderer",1001
-"""))
-
- def test_scroll_jank_mojo_simple_watcher(self):
- return DiffTestBlueprint(
- trace=Path('scroll_jank_mojo_simple_watcher.py'),
- query="""
-SELECT RUN_METRIC('chrome/scroll_jank_cause_queuing_delay.sql');
-
-SELECT
- trace_id,
- jank,
- dur_overlapping_ns,
- metric_name
-FROM scroll_jank_cause_queuing_delay
-ORDER BY trace_id ASC, ts ASC;
-""",
- out=Path('scroll_jank_mojo_simple_watcher.out'))
-
- def test_scroll_jank_gpu_check(self):
- return DiffTestBlueprint(
- trace=Path('scroll_jank_gpu_check.py'),
- query="""
-SELECT RUN_METRIC('chrome/scroll_jank.sql');
-
-SELECT ts, jank
-FROM scroll_jank
-ORDER BY ts ASC;
-""",
- out=Csv("""
-"ts","jank"
-15000000,0
-30000000,1
-115000000,0
-"""))
-
- def test_touch_jank(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_touch_gesture_scroll.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/touch_jank.sql');
-
-SELECT
- touch_id,
- trace_id,
- jank,
- ts,
- dur,
- jank_budget
-FROM touch_jank;
-""",
- out=Path('touch_jank.out'))
-
- def test_touch_flow_event(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_touch_gesture_scroll.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/touch_flow_event.sql');
-
-SELECT
- trace_id,
- ts,
- dur,
- jank,
- step,
- ancestor_end,
- maybe_next_ancestor_ts,
- next_ts,
- next_trace_id,
- next_step
-FROM touch_flow_event
-ORDER BY touch_id, trace_id, ts;
-""",
- out=Path('touch_flow_event.out'))
-
- def test_touch_flow_event_queuing_delay(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_touch_gesture_scroll.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/touch_flow_event_queuing_delay.sql');
-
-SELECT
- trace_id,
- jank,
- step,
- next_step,
- ancestor_end,
- maybe_next_ancestor_ts,
- queuing_time_ns
-FROM touch_flow_event_queuing_delay
-WHERE trace_id = 6915 OR trace_id = 6911 OR trace_id = 6940
-ORDER BY trace_id, ts;
-""",
- out=Path('touch_flow_event_queuing_delay.out'))
-
- def test_touch_jank_synth(self):
- return DiffTestBlueprint(
- trace=Path('touch_jank.py'),
- query="""
-SELECT RUN_METRIC('chrome/touch_jank.sql');
-
-SELECT
- touch_id,
- trace_id,
- jank,
- ts,
- dur,
- jank_budget
-FROM touch_jank;
-""",
- out=Csv("""
-"touch_id","trace_id","jank","ts","dur","jank_budget"
-87654,34577,0,0,10000000,-31333333.350000
-87654,34578,1,16000000,33000000,14666666.650000
-87654,34579,0,55000000,33000000,-8333333.350000
-"""))
-
- def test_touch_flow_event_synth(self):
- return DiffTestBlueprint(
- trace=Path('touch_jank.py'),
- query="""
-SELECT RUN_METRIC('chrome/touch_flow_event.sql');
-
-SELECT
- trace_id,
- ts,
- dur,
- jank,
- step,
- ancestor_end,
- maybe_next_ancestor_ts,
- next_ts,
- next_trace_id,
- next_step
-FROM touch_flow_event
-ORDER BY touch_id, trace_id, ts;
-""",
- out=Path('touch_flow_event_synth.out'))
-
- def test_touch_flow_event_queuing_delay_synth(self):
- return DiffTestBlueprint(
- trace=Path('touch_jank.py'),
- query="""
-SELECT RUN_METRIC('chrome/touch_flow_event_queuing_delay.sql');
-
-SELECT
- trace_id,
- jank,
- step,
- next_step,
- ancestor_end,
- maybe_next_ancestor_ts,
- queuing_time_ns
-FROM touch_flow_event_queuing_delay
-ORDER BY trace_id, ts;
-""",
- out=Path('touch_flow_event_queuing_delay_synth.out'))
-
- def test_memory_snapshot_general_validation(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_memory_snapshot.pftrace'),
- query="""
-SELECT
- (
- SELECT COUNT(*) FROM memory_snapshot
- ) AS total_snapshots,
- (
- SELECT COUNT(*) FROM process
- ) AS total_processes,
- (
- SELECT COUNT(*) FROM process_memory_snapshot
- ) AS total_process_snapshots,
- (
- SELECT COUNT(*) FROM memory_snapshot_node
- ) AS total_nodes,
- (
- SELECT COUNT(*) FROM memory_snapshot_edge
- ) AS total_edges,
- (
- SELECT COUNT(DISTINCT args.id)
- FROM args
- JOIN memory_snapshot_node
- ON args.arg_set_id = memory_snapshot_node.arg_set_id
- ) AS total_node_args,
- (
- SELECT COUNT(*) FROM profiler_smaps
- JOIN memory_snapshot ON timestamp = ts
- ) AS total_smaps;
-""",
- out=Path('memory_snapshot_general_validation.out'))
-
- def test_memory_snapshot_os_dump_events(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_memory_snapshot.pftrace'),
- query="""
-SELECT
- p.upid,
- pid,
- p.name,
- timestamp,
- detail_level,
- pf.value AS private_footprint_kb,
- prs.value AS peak_resident_set_kb,
- EXTRACT_ARG(p.arg_set_id, 'is_peak_rss_resettable') AS is_peak_rss_resettable
-FROM process p
-LEFT JOIN memory_snapshot
-LEFT JOIN (
- SELECT id, upid
- FROM process_counter_track
- WHERE name = 'chrome.private_footprint_kb'
- ) AS pct_pf
- ON p.upid = pct_pf.upid
-LEFT JOIN counter pf ON timestamp = pf.ts AND pct_pf.id = pf.track_id
-LEFT JOIN (
- SELECT id, upid
- FROM process_counter_track
- WHERE name = 'chrome.peak_resident_set_kb'
- ) AS pct_prs
- ON p.upid = pct_prs.upid
-LEFT JOIN counter prs ON timestamp = prs.ts AND pct_prs.id = prs.track_id
-ORDER BY timestamp;
-""",
- out=Path('memory_snapshot_os_dump_events.out'))
-
- def test_memory_snapshot_chrome_dump_events(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_memory_snapshot.pftrace'),
- query="""
-SELECT
- pms.id AS process_snapshot_id,
- upid,
- snapshot_id,
- timestamp,
- detail_level
-FROM memory_snapshot ms
-LEFT JOIN process_memory_snapshot pms
- ON ms.id = pms.snapshot_id;
-""",
- out=Path('memory_snapshot_chrome_dump_events.out'))
-
- def test_memory_snapshot_nodes(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_memory_snapshot.pftrace'),
- query="""
-SELECT
- id,
- process_snapshot_id,
- parent_node_id,
- path,
- size,
- effective_size
-FROM memory_snapshot_node
-LIMIT 20;
-""",
- out=Path('memory_snapshot_nodes.out'))
-
- def test_memory_snapshot_edges(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_memory_snapshot.pftrace'),
- query="""
-SELECT
- id,
- source_node_id,
- target_node_id,
- importance
-FROM memory_snapshot_edge
-LIMIT 20;
-""",
- out=Path('memory_snapshot_edges.out'))
-
- def test_memory_snapshot_node_args(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_memory_snapshot.pftrace'),
- query="""
-SELECT
- node.id AS node_id,
- key,
- value_type,
- int_value,
- string_value
-FROM memory_snapshot_node node
-JOIN args ON node.arg_set_id = args.arg_set_id
-LIMIT 20;
-""",
- out=Path('memory_snapshot_node_args.out'))
-
- def test_memory_snapshot_smaps(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_memory_snapshot.pftrace'),
- query="""
-SELECT
- process.upid,
- process.name,
- smap.ts,
- path,
- size_kb,
- private_dirty_kb,
- swap_kb,
- file_name,
- start_address,
- module_timestamp,
- module_debugid,
- module_debug_path,
- protection_flags,
- private_clean_resident_kb,
- shared_dirty_resident_kb,
- shared_clean_resident_kb,
- locked_kb,
- proportional_resident_kb
-FROM process
-JOIN profiler_smaps smap ON process.upid = smap.upid
-JOIN memory_snapshot ms ON ms.timestamp = smap.ts
-LIMIT 20;
-""",
- out=Path('memory_snapshot_smaps.out'))
-
- def test_combined_rail_modes(self):
- return DiffTestBlueprint(
- trace=Path('combined_rail_modes.py'),
- query="""
-SELECT RUN_METRIC('chrome/rail_modes.sql');
-SELECT * FROM combined_overall_rail_slices;
-""",
- out=Csv("""
-"id","ts","dur","rail_mode"
-1,0,10000,"response"
-2,10000,25000,"animation"
-3,35000,10000,"background"
-"""))
-
- def test_cpu_time_by_combined_rail_mode(self):
- return DiffTestBlueprint(
- trace=Path('cpu_time_by_combined_rail_mode.py'),
- query="""
-SELECT RUN_METRIC('chrome/cpu_time_by_rail_mode.sql');
-SELECT * FROM cpu_time_by_rail_mode;
-""",
- out=Csv("""
-"id","ts","dur","rail_mode","cpu_dur"
-1,0,10000,"response",26000
-2,10000,20000,"animation",20000
-3,30000,5000,"background",8000
-4,35000,10000,"animation",21000
-5,45000,10000,"background",1000
-"""))
-
- def test_actual_power_by_combined_rail_mode(self):
- return DiffTestBlueprint(
- trace=Path('actual_power_by_combined_rail_mode.py'),
- query="""
-SELECT RUN_METRIC('chrome/actual_power_by_rail_mode.sql');
-SELECT * FROM real_power_by_rail_mode;
-""",
- out=Csv("""
-"id","ts","dur","rail_mode","subsystem","joules","drain_w"
-1,0,10000000,"response","cellular",0.000000,0.000000
-1,0,10000000,"response","cpu_little",0.000140,0.014000
-2,10000000,20000000,"animation","cellular",0.000350,0.017500
-2,10000000,20000000,"animation","cpu_little",0.000140,0.007000
-3,30000000,5000000,"background","cellular",0.000018,0.003500
-3,30000000,5000000,"background","cpu_little",0.000007,0.001400
-4,35000000,10000000,"animation","cellular",0.000021,0.002100
-4,35000000,10000000,"animation","cpu_little",0.000070,0.007000
-5,45000000,10000000,"background","cellular",0.000003,0.000350
-5,45000000,10000000,"background","cpu_little",0.000070,0.007000
-"""))
-
- def test_estimated_power_by_combined_rail_mode(self):
- return DiffTestBlueprint(
- trace=Path('estimated_power_by_combined_rail_mode.py'),
- query="""
-SELECT RUN_METRIC('chrome/estimated_power_by_rail_mode.sql');
-SELECT * FROM power_by_rail_mode;
-""",
- out=Csv("""
-"id","ts","dur","rail_mode","mas","ma"
-1,0,10000000,"response",0.554275,55.427500
-2,10000000,20000000,"animation",0.284850,14.242500
-3,30000000,5000000,"background",0.076233,15.246667
-4,35000000,10000000,"animation",0.536850,53.685000
-5,45000000,10000000,"background",0.071580,7.158000
-"""))
-
- def test_modified_rail_modes(self):
- return DiffTestBlueprint(
- trace=Path('modified_rail_modes.py'),
- query="""
-SELECT RUN_METRIC('chrome/rail_modes.sql');
-SELECT * FROM modified_rail_slices;
-""",
- out=Csv("""
-"id","ts","dur","mode"
-2,0,1000000000,"response"
-3,1000000000,1950000000,"foreground_idle"
-4,2950000000,333333324,"animation"
-5,3283333324,216666676,"foreground_idle"
-6,3500000000,1000000000,"background"
-"""))
-
- def test_modified_rail_modes_no_vsyncs(self):
- return DiffTestBlueprint(
- trace=Path('modified_rail_modes_no_vsyncs.py'),
- query="""
-SELECT RUN_METRIC('chrome/rail_modes.sql');
-SELECT * FROM modified_rail_slices;
-""",
- out=Csv("""
-"id","ts","dur","mode"
-2,0,1000000000,"response"
-3,1000000000,2500000000,"foreground_idle"
-4,3500000000,1000000000,"background"
-"""))
-
- def test_modified_rail_modes_with_input(self):
- return DiffTestBlueprint(
- trace=Path('modified_rail_modes_with_input.py'),
- query="""
-SELECT RUN_METRIC('chrome/rail_modes.sql');
-SELECT * FROM modified_rail_slices;
-""",
- out=Csv("""
-"id","ts","dur","mode"
-2,0,1000000000,"response"
-3,1000000000,1950000000,"foreground_idle"
-4,2950000000,50000000,"animation"
-5,3000000000,66666674,"response"
-6,3066666674,216666650,"animation"
-7,3283333324,216666676,"foreground_idle"
-8,3500000000,1000000000,"background"
-"""))
-
- def test_modified_rail_modes_long(self):
- return DiffTestBlueprint(
- trace=Path('modified_rail_modes_long.py'),
- query="""
-SELECT RUN_METRIC('chrome/rail_modes.sql');
-SELECT * FROM modified_rail_slices;
-""",
- out=Csv("""
-"id","ts","dur","mode"
-2,0,1000000000,"response"
-3,1000000000,1,"background"
-"""))
-
- def test_modified_rail_modes_extra_long(self):
- return DiffTestBlueprint(
- trace=Path('modified_rail_modes_extra_long.py'),
- query="""
-SELECT RUN_METRIC('chrome/rail_modes.sql');
-SELECT * FROM modified_rail_slices;
-""",
- out=Csv("""
-"id","ts","dur","mode"
-"""))
-
- def test_chrome_processes(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_processes.sql');
-SELECT pid, name, process_type FROM chrome_process;
-""",
- out=Csv("""
-"pid","name","process_type"
-18250,"Renderer","Renderer"
-17547,"Browser","Browser"
-18277,"GPU Process","Gpu"
-17578,"Browser","Browser"
-"""))
-
- def test_chrome_processes_android_systrace(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_android_systrace.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_processes.sql');
-SELECT pid, name, process_type FROM chrome_process;
-""",
- out=Path('chrome_processes_android_systrace.out'))
-
- def test_chrome_threads(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_processes.sql');
-SELECT tid, name, is_main_thread, canonical_name
-FROM chrome_thread
-ORDER BY tid, name;
-""",
- out=Path('chrome_threads.out'))
-
- def test_chrome_threads_android_systrace(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_android_systrace.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_processes.sql');
-SELECT tid, name, is_main_thread, canonical_name
-FROM chrome_thread
-ORDER BY tid, name;
-""",
- out=Path('chrome_threads_android_systrace.out'))
-
- def test_chrome_processes_type(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query="""
-SELECT pid, name, string_value AS chrome_process_type
-FROM
- process
-JOIN
- (SELECT * FROM args WHERE key = "chrome.process_type") chrome_process_args
- ON
- process.arg_set_id = chrome_process_args.arg_set_id
-ORDER BY pid;
-""",
- out=Csv("""
-"pid","name","chrome_process_type"
-17547,"Browser","Browser"
-17578,"Browser","Browser"
-18250,"Renderer","Renderer"
-18277,"GPU Process","Gpu"
-"""))
-
- def test_chrome_processes_type_android_systrace(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_android_systrace.pftrace'),
- query="""
-SELECT pid, name, string_value AS chrome_process_type
-FROM
- process
-JOIN
- (SELECT * FROM args WHERE key = "chrome.process_type") chrome_process_args
- ON
- process.arg_set_id = chrome_process_args.arg_set_id
-ORDER BY pid;
-""",
- out=Path('chrome_processes_type_android_systrace.out'))
-
- def test_track_with_chrome_process(self):
- return DiffTestBlueprint(
- trace=Path('track_with_chrome_process.textproto'),
- query="""
-SELECT pid, name, string_value AS chrome_process_type
-FROM
- process
-JOIN
- (SELECT * FROM args WHERE key = "chrome.process_type") chrome_process_args
- ON
- process.arg_set_id = chrome_process_args.arg_set_id
-ORDER BY pid;
-""",
- out=Csv("""
-"pid","name","chrome_process_type"
-5,"p5","[NULL]"
-"""))
-
- def test_chrome_histogram_hashes(self):
- return DiffTestBlueprint(
- trace=Path('chrome_histogram_hashes.textproto'),
- query=Metric('chrome_histogram_hashes'),
- out=TextProto(r"""
-[perfetto.protos.chrome_histogram_hashes]: {
- hash: 10
- hash: 20
-}
-"""))
-
- def test_chrome_user_event_hashes(self):
- return DiffTestBlueprint(
- trace=Path('chrome_user_event_hashes.textproto'),
- query=Metric('chrome_user_event_hashes'),
- out=TextProto(r"""
-[perfetto.protos.chrome_user_event_hashes]: {
- action_hash: 10
- action_hash: 20
-}
-
-"""))
-
- def test_chrome_performance_mark_hashes(self):
- return DiffTestBlueprint(
- trace=Path('chrome_performance_mark_hashes.textproto'),
- query=Metric('chrome_performance_mark_hashes'),
- out=TextProto(r"""
-[perfetto.protos.chrome_performance_mark_hashes]: {
- site_hash: 10
- site_hash: 20
- mark_hash: 100
- mark_hash: 200
-}
-"""))
-
- def test_chrome_reliable_range(self):
- return DiffTestBlueprint(
- trace=Path('chrome_reliable_range.textproto'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
-"start","reason","debug_limiting_upid","debug_limiting_utid"
-12,"First slice for utid=2","[NULL]",2
-"""))
-
- def test_chrome_reliable_range_cropping(self):
- return DiffTestBlueprint(
- trace=Path('chrome_reliable_range_cropping.textproto'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
-"start","reason","debug_limiting_upid","debug_limiting_utid"
-10000,"Range of interest packet","[NULL]",2
-"""))
-
- def test_chrome_reliable_range_missing_processes(self):
- return DiffTestBlueprint(
- trace=Path('chrome_reliable_range_missing_processes.textproto'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
-"start","reason","debug_limiting_upid","debug_limiting_utid"
-1011,"Missing process data for upid=2",2,1
-"""))
-
- def test_chrome_reliable_range_missing_browser_main(self):
- return DiffTestBlueprint(
- trace=Path('chrome_reliable_range_missing_browser_main.textproto'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
-"start","reason","debug_limiting_upid","debug_limiting_utid"
-1011,"Missing main thread for upid=1",1,1
-"""))
-
- def test_chrome_reliable_range_missing_renderer_main(self):
- return DiffTestBlueprint(
- trace=Path('chrome_reliable_range_missing_renderer_main.textproto'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
-"start","reason","debug_limiting_upid","debug_limiting_utid"
-1011,"Missing main thread for upid=1",1,1
-"""))
-
- def test_chrome_reliable_range_non_chrome_process(self):
- return DiffTestBlueprint(
- # We need a trace with a large number of non-chrome slices, so that the
- # reliable range is affected by their filtering.
- trace=Path('../../data/example_android_trace_30s.pb'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
- "start","reason","debug_limiting_upid","debug_limiting_utid"
- 0,"[NULL]","[NULL]","[NULL]"
- """))
-
- def test_chrome_slice_names(self):
- return DiffTestBlueprint(
- trace=Path('chrome_slice_names.textproto'),
- query=Metric('chrome_slice_names'),
- out=TextProto(r"""
-[perfetto.protos.chrome_slice_names]: {
- chrome_version_code: 123
- slice_name: "Looper.Dispatch: class1"
- slice_name: "name2"
-}
-"""))
-
- def test_chrome_tasks(self):
- return DiffTestBlueprint(
- trace=Path(
- '../../data/chrome_page_load_all_categories_not_extended.pftrace.gz'
- ),
- query="""
-SELECT RUN_METRIC('chrome/chrome_tasks.sql');
-
-SELECT full_name, task_type, count() AS count
-FROM chrome_tasks
-GROUP BY full_name, task_type
-ORDER BY count DESC
-LIMIT 50;
-""",
- out=Path('chrome_tasks.out'))
-
- def test_top_level_java_choreographer_slices_top_level_java_chrome_tasks_test(
- self):
- return DiffTestBlueprint(
- trace=Path('../../data/top_level_java_choreographer_slices'),
- query="""
-SELECT RUN_METRIC(
- 'chrome/chrome_tasks_template.sql',
- 'slice_table_name', 'slice',
- 'function_prefix', ''
-);
-
-SELECT
- full_name,
- task_type
-FROM chrome_tasks
-WHERE category = "toplevel,Java"
-AND ts < 263904000000000
-GROUP BY full_name, task_type;
-""",
- out=Path(
- 'top_level_java_choreographer_slices_top_level_java_chrome_tasks_test.out'
- ))
-
- def test_chrome_stack_samples_for_task_test(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_stack_traces_symbolized_trace.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_stack_samples_for_task.sql',
- 'target_duration_ms', '0.000001',
- 'thread_name', '"CrBrowserMain"',
- 'task_name', '"sendTouchEvent"');
-
-SELECT
- sample.description,
- sample.ts,
- sample.depth
-FROM chrome_stack_samples_for_task sample
-JOIN (
- SELECT
- ts,
- dur
- FROM slice
- WHERE ts = 696373965001470
-) test_slice
-ON sample.ts >= test_slice.ts
- AND sample.ts <= test_slice.ts + test_slice.dur
-ORDER BY sample.ts, sample.depth;
-""",
- out=Path('chrome_stack_samples_for_task_test.out'))
-
- def test_unsymbolized_args(self):
- return DiffTestBlueprint(
- trace=Path('unsymbolized_args.textproto'),
- query=Metric('chrome_unsymbolized_args'),
- out=TextProto(r"""
-[perfetto.protos.chrome_unsymbolized_args]: {
- args {
- module: "/liblib.so"
- build_id: "6275696c642d6964"
- address: 123
- google_lookup_id: "6275696c642d6964"
- }
- args {
- module: "/libmonochrome_64.so"
- build_id: "7f0715c286f8b16c10e4ad349cda3b9b56c7a773"
- address: 234
- google_lookup_id: "c215077ff8866cb110e4ad349cda3b9b0"
- }
-}"""))
-
- def test_async_trace_1_count_slices(self):
- return DiffTestBlueprint(
- trace=Path('../../data/async-trace-1.json'),
- query="""
-SELECT COUNT(1) FROM slice;
-""",
- out=Csv("""
-"COUNT(1)"
-16
-"""))
-
- def test_async_trace_2_count_slices(self):
- return DiffTestBlueprint(
- trace=Path('../../data/async-trace-2.json'),
- query="""
-SELECT COUNT(1) FROM slice;
-""",
- out=Csv("""
-"COUNT(1)"
-35
-"""))
-
- def test_chrome_args_class_names(self):
- return DiffTestBlueprint(
- trace=Path('chrome_args_class_names.textproto'),
- query=Metric('chrome_args_class_names'),
- out=TextProto(r"""
-
-[perfetto.protos.chrome_args_class_names] {
- class_names_per_version {
- class_name: "abc"
- class_name: "def"
- class_name: "ghi"
- class_name: "jkl"
- }
-}
-"""))
-
- def test_chrome_log_message(self):
- return DiffTestBlueprint(
- trace=Path('chrome_log_message.textproto'),
- query="""
-SELECT utid, tag, msg FROM android_logs;
-""",
- out=Csv("""
-"utid","tag","msg"
-1,"foo.cc:123","log message"
-"""))
-
- def test_chrome_log_message_args(self):
- return DiffTestBlueprint(
- trace=Path('chrome_log_message.textproto'),
- query=Path('chrome_log_message_args_test.sql'),
- out=Csv("""
-"log_message","function_name","file_name","line_number"
-"log message","func","foo.cc",123
-"""))
-
- def test_chrome_missing_processes_default_trace(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query="""
-SELECT upid, pid, reliable_from
-FROM
- experimental_missing_chrome_processes
-JOIN
- process
- USING(upid)
-ORDER BY upid;
-""",
- out=Csv("""
-"upid","pid","reliable_from"
-"""))
-
- def test_chrome_missing_processes(self):
- return DiffTestBlueprint(
- trace=Path('chrome_missing_processes.textproto'),
- query="""
-SELECT upid, pid, reliable_from
-FROM
- experimental_missing_chrome_processes
-JOIN
- process
- USING(upid)
-ORDER BY upid;
-""",
- out=Csv("""
-"upid","pid","reliable_from"
-2,100,1000000000
-3,1000,"[NULL]"
-"""))
-
- def test_chrome_missing_processes_args(self):
- return DiffTestBlueprint(
- trace=Path('chrome_missing_processes.textproto'),
- query="""
-SELECT arg_set_id, key, int_value
-FROM
- slice
-JOIN
- args
- USING(arg_set_id)
-ORDER BY arg_set_id, key;
-""",
- out=Csv("""
-"arg_set_id","key","int_value"
-2,"chrome_active_processes.pid[0]",10
-2,"chrome_active_processes.pid[1]",100
-2,"chrome_active_processes.pid[2]",1000
-"""))
-
- def test_chrome_missing_processes_2(self):
- return DiffTestBlueprint(
- trace=Path('chrome_missing_processes_extension.textproto'),
- query="""
-SELECT upid, pid, reliable_from
-FROM
- experimental_missing_chrome_processes
-JOIN
- process
- USING(upid)
-ORDER BY upid;
-""",
- out=Csv("""
-"upid","pid","reliable_from"
-2,100,1000000000
-3,1000,"[NULL]"
-"""))
-
- def test_chrome_missing_processes_extension_args(self):
- return DiffTestBlueprint(
- trace=Path('chrome_missing_processes_extension.textproto'),
- query="""
-SELECT arg_set_id, key, int_value
-FROM
- slice
-JOIN
- args
- USING(arg_set_id)
-ORDER BY arg_set_id, key;
-""",
- out=Csv("""
-"arg_set_id","key","int_value"
-2,"active_processes.pid[0]",10
-2,"active_processes.pid[1]",100
-2,"active_processes.pid[2]",1000
-"""))
-
- def test_chrome_custom_navigation_tasks(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_custom_navigation_trace.gz'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_tasks.sql');
-
-SELECT full_name, task_type, count() AS count
-FROM chrome_tasks
-WHERE full_name GLOB 'FrameHost::BeginNavigation*'
- OR full_name GLOB 'FrameHost::DidCommitProvisionalLoad*'
- OR full_name GLOB 'FrameHost::DidCommitSameDocumentNavigation*'
- OR full_name GLOB 'FrameHost::DidStopLoading*'
-GROUP BY full_name, task_type
-ORDER BY count DESC
-LIMIT 50;
-""",
- out=Csv("""
-"full_name","task_type","count"
-"FrameHost::BeginNavigation (SUBFRAME)","navigation_task",5
-"FrameHost::DidStopLoading (SUBFRAME)","navigation_task",3
-"FrameHost::BeginNavigation (PRIMARY_MAIN_FRAME)","navigation_task",1
-"FrameHost::DidCommitProvisionalLoad (SUBFRAME)","navigation_task",1
-"""))
-
- def test_proto_content(self):
- return DiffTestBlueprint(
- trace=Path('../../data/chrome_scroll_without_vsync.pftrace'),
- query="""
-SELECT path, SUM(total_size) as total_size
-FROM experimental_proto_content as content
-JOIN experimental_proto_path as frame ON content.path_id = frame.id
-GROUP BY path
-ORDER BY total_size DESC, path
-LIMIT 10;
-""",
- out=Path('proto_content.out'))
-
- def test_chrome_scroll_jank_v2(self):
- return DiffTestBlueprint(
- trace=Path('../../data/event_latency_with_args.perfetto-trace'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_scroll_jank_v2.sql');
-
-SELECT
- scroll_processing_ms,
- scroll_jank_processing_ms,
- scroll_jank_percentage
-FROM chrome_scroll_jank_v2_output;
-""",
- out=Path('chrome_scroll_jank_v2.out'))
diff --git a/test/trace_processor/diff_tests/chrome/tests_general.py b/test/trace_processor/diff_tests/chrome/tests_general.py
deleted file mode 100644
index 99938b8..0000000
--- a/test/trace_processor/diff_tests/chrome/tests_general.py
+++ /dev/null
@@ -1,212 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2023 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 a
-#
-# 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.
-
-from python.generators.diff_tests.testing import Path, DataPath, Metric
-from python.generators.diff_tests.testing import Csv, Json, TextProto
-from python.generators.diff_tests.testing import DiffTestBlueprint
-from python.generators.diff_tests.testing import DiffTestModule
-
-
-class ChromeGeneral(DiffTestModule):
-
- def test_chrome_histogram_hashes(self):
- return DiffTestBlueprint(
- trace=Path('chrome_histogram_hashes.textproto'),
- query=Metric('chrome_histogram_hashes'),
- out=TextProto(r"""
-[perfetto.protos.chrome_histogram_hashes]: {
- hash: 10
- hash: 20
-}
-"""))
-
- def test_chrome_user_event_hashes(self):
- return DiffTestBlueprint(
- trace=Path('chrome_user_event_hashes.textproto'),
- query=Metric('chrome_user_event_hashes'),
- out=TextProto(r"""
-[perfetto.protos.chrome_user_event_hashes]: {
- action_hash: 10
- action_hash: 20
-}
-
-"""))
-
- def test_chrome_performance_mark_hashes(self):
- return DiffTestBlueprint(
- trace=Path('chrome_performance_mark_hashes.textproto'),
- query=Metric('chrome_performance_mark_hashes'),
- out=TextProto(r"""
-[perfetto.protos.chrome_performance_mark_hashes]: {
- site_hash: 10
- site_hash: 20
- mark_hash: 100
- mark_hash: 200
-}
-"""))
-
- def test_chrome_reliable_range(self):
- return DiffTestBlueprint(
- trace=Path('chrome_reliable_range.textproto'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
-"start","reason","debug_limiting_upid","debug_limiting_utid"
-12,"First slice for utid=2","[NULL]",2
-"""))
-
- def test_chrome_reliable_range_cropping(self):
- return DiffTestBlueprint(
- trace=Path('chrome_reliable_range_cropping.textproto'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
-"start","reason","debug_limiting_upid","debug_limiting_utid"
-10000,"Range of interest packet","[NULL]",2
-"""))
-
- def test_chrome_reliable_range_missing_processes(self):
- return DiffTestBlueprint(
- trace=Path('chrome_reliable_range_missing_processes.textproto'),
- query=Path('chrome_reliable_range_test.sql'),
- out=Csv("""
-"start","reason","debug_limiting_upid","debug_limiting_utid"
-1011,"Missing process data for upid=2",2,1
-"""))
-
- def test_chrome_slice_names(self):
- return DiffTestBlueprint(
- trace=Path('chrome_slice_names.textproto'),
- query=Metric('chrome_slice_names'),
- out=TextProto(r"""
-[perfetto.protos.chrome_slice_names]: {
- chrome_version_code: 123
- slice_name: "Looper.Dispatch: class1"
- slice_name: "name2"
-}
-"""))
-
- def test_chrome_tasks(self):
- return DiffTestBlueprint(
- trace=DataPath(
- 'chrome_page_load_all_categories_not_extended.pftrace.gz'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_tasks.sql');
-
-SELECT full_name, task_type, count() AS count
-FROM chrome_tasks
-GROUP BY full_name, task_type
-ORDER BY count DESC
-LIMIT 50;
-""",
- out=Path('chrome_tasks.out'))
-
- def test_top_level_java_choreographer_slices_top_level_java_chrome_tasks(
- self):
- return DiffTestBlueprint(
- trace=DataPath('top_level_java_choreographer_slices'),
- query="""
-SELECT RUN_METRIC(
- 'chrome/chrome_tasks_template.sql',
- 'slice_table_name', 'slice',
- 'function_prefix', ''
-);
-
-SELECT
- full_name,
- task_type
-FROM chrome_tasks
-WHERE category = "toplevel,Java"
-AND ts < 263904000000000
-GROUP BY full_name, task_type;
-""",
- out=Path(
- 'top_level_java_choreographer_slices_top_level_java_chrome_tasks_test.out'
- ))
-
- def test_chrome_stack_samples_for_task(self):
- return DiffTestBlueprint(
- trace=DataPath('chrome_stack_traces_symbolized_trace.pftrace'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_stack_samples_for_task.sql',
- 'target_duration_ms', '0.000001',
- 'thread_name', '"CrBrowserMain"',
- 'task_name', '"sendTouchEvent"');
-
-SELECT
- sample.description,
- sample.ts,
- sample.depth
-FROM chrome_stack_samples_for_task sample
-JOIN (
- SELECT
- ts,
- dur
- FROM slice
- WHERE ts = 696373965001470
-) test_slice
-ON sample.ts >= test_slice.ts
- AND sample.ts <= test_slice.ts + test_slice.dur
-ORDER BY sample.ts, sample.depth;
-""",
- out=Path('chrome_stack_samples_for_task_test.out'))
-
- def test_chrome_log_message(self):
- return DiffTestBlueprint(
- trace=Path('chrome_log_message.textproto'),
- query="""
-SELECT utid, tag, msg FROM android_logs;
-""",
- out=Csv("""
-"utid","tag","msg"
-1,"foo.cc:123","log message"
-"""))
-
- def test_chrome_log_message_args(self):
- return DiffTestBlueprint(
- trace=Path('chrome_log_message.textproto'),
- query=Path('chrome_log_message_args_test.sql'),
- out=Csv("""
-"log_message","function_name","file_name","line_number"
-"log message","func","foo.cc",123
-"""))
-
- def test_chrome_custom_navigation_tasks(self):
- return DiffTestBlueprint(
- trace=DataPath('chrome_custom_navigation_trace.gz'),
- query="""
-SELECT RUN_METRIC('chrome/chrome_tasks.sql');
-
-SELECT full_name, task_type, count() AS count
-FROM chrome_tasks
-WHERE full_name GLOB 'FrameHost::BeginNavigation*'
- OR full_name GLOB 'FrameHost::DidCommitProvisionalLoad*'
- OR full_name GLOB 'FrameHost::DidCommitSameDocumentNavigation*'
- OR full_name GLOB 'FrameHost::DidStopLoading*'
-GROUP BY full_name, task_type
-ORDER BY count DESC
-LIMIT 50;
-""",
- out=Csv("""
-"full_name","task_type","count"
-"FrameHost::BeginNavigation (SUBFRAME)","navigation_task",5
-"FrameHost::DidStopLoading (SUBFRAME)","navigation_task",3
-"FrameHost::BeginNavigation (PRIMARY_MAIN_FRAME)","navigation_task",1
-"FrameHost::DidCommitProvisionalLoad (SUBFRAME)","navigation_task",1
-"""))
-
- def test_proto_content(self):
- return DiffTestBlueprint(
- trace=DataPath('chrome_scroll_without_vsync.pftrace'),
- query=Path('proto_content_test.sql'),
- out=Path('proto_content.out'))
diff --git a/test/trace_processor/diff_tests/chrome/tests_scroll_jank.py b/test/trace_processor/diff_tests/chrome/tests_scroll_jank.py
index 62833c2..c8594d1 100644
--- a/test/trace_processor/diff_tests/chrome/tests_scroll_jank.py
+++ b/test/trace_processor/diff_tests/chrome/tests_scroll_jank.py
@@ -540,3 +540,18 @@
5679,60000000,40000000,60000000,90000000
5680,120000000,70000000,120000000,-1
"""))
+
+ # TODO(283531332): reenable this test after fixing.
+ # def test_chrome_scroll_jank_v2(self):
+ # return DiffTestBlueprint(
+ # trace=Path('../../data/event_latency_with_args.perfetto-trace'),
+ # query="""
+ # SELECT RUN_METRIC('chrome/chrome_scroll_jank_v2.sql');
+
+ # SELECT
+ # scroll_processing_ms,
+ # scroll_jank_processing_ms,
+ # scroll_jank_percentage
+ # FROM chrome_scroll_jank_v2_output;
+ # """,
+ # out=Path('chrome_scroll_jank_v2.out'))
diff --git a/test/trace_processor/diff_tests/cros/tests_general.py b/test/trace_processor/diff_tests/cros/tests_general.py
deleted file mode 100644
index 5f012db..0000000
--- a/test/trace_processor/diff_tests/cros/tests_general.py
+++ /dev/null
@@ -1,40 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2023 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 a
-#
-# 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.
-
-from python.generators.diff_tests.testing import Path, DataPath, Metric
-from python.generators.diff_tests.testing import Csv, Json, TextProto
-from python.generators.diff_tests.testing import DiffTestBlueprint
-from python.generators.diff_tests.testing import DiffTestModule
-
-
-class CrosGeneral(DiffTestModule):
-
- def test_cros_ec_sensorhub_data(self):
- return DiffTestBlueprint(
- trace=Path('cros_ec_sensorhub_data.textproto'),
- query="""
-SELECT
- t.name,
- c.ts,
- c.value,
- EXTRACT_ARG(c.arg_set_id, 'ec_num') AS ec_num,
- EXTRACT_ARG(c.arg_set_id, 'ec_delta') AS ec_delta,
- EXTRACT_ARG(c.arg_set_id, 'sample_ts') AS sample_ts
-FROM counter c
-JOIN track t
- ON c.track_id = t.id
-WHERE t.name = 'cros_ec.cros_ec_sensorhub_data.0';
-""",
- out=Path('cros_ec_sensorhub_data.out'))
diff --git a/test/trace_processor/diff_tests/span_join/tests.py b/test/trace_processor/diff_tests/span_join/tests.py
deleted file mode 100644
index e675aff..0000000
--- a/test/trace_processor/diff_tests/span_join/tests.py
+++ /dev/null
@@ -1,411 +0,0 @@
-#!/usr/bin/env python3
-# Copyright (C) 2023 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 a
-#
-# 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.
-
-from python.generators.diff_tests.testing import Path, DataPath, Metric
-from python.generators.diff_tests.testing import Csv, Json, TextProto
-from python.generators.diff_tests.testing import DiffTestBlueprint
-from python.generators.diff_tests.testing import DiffTestModule
-
-
-class DiffTestModule_SpanJoin(DiffTestModule):
-
- def test_span_outer_join(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query=Path('span_outer_join_test.sql'),
- out=Path('span_outer_join.out'))
-
- def test_span_outer_join_empty(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query="""
-CREATE TABLE t1(
- ts BIGINT,
- dur BIGINT,
- part BIGINT,
- PRIMARY KEY (part, ts)
-) WITHOUT ROWID;
-
-CREATE TABLE t2(
- ts BIGINT,
- dur BIGINT,
- part BIGINT,
- PRIMARY KEY (part, ts)
-) WITHOUT ROWID;
-
-INSERT INTO t1(ts, dur, part)
-VALUES (500, 100, 10);
-
-
-CREATE VIRTUAL TABLE sp USING span_outer_join(t1 PARTITIONED part,
- t2 PARTITIONED part);
-
-SELECT * FROM sp;
-""",
- out=Csv("""
-"ts","dur","part"
-500,100,10
-"""))
-
- def test_span_outer_join_unpartitioned_empty(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query="""
-CREATE TABLE t1(
- ts BIGINT,
- dur BIGINT,
- PRIMARY KEY (ts)
-) WITHOUT ROWID;
-
-CREATE TABLE t2(
- ts BIGINT,
- dur BIGINT,
- PRIMARY KEY (ts)
-) WITHOUT ROWID;
-
-
-CREATE VIRTUAL TABLE sp USING span_outer_join(t1, t2);
-
-SELECT * FROM sp;
-""",
- out=Csv("""
-"ts","dur"
-"""))
-
- def test_span_outer_join_unpartitioned_left_empty(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query="""
-CREATE TABLE t1(
- ts BIGINT,
- dur BIGINT,
- PRIMARY KEY (ts)
-) WITHOUT ROWID;
-
-CREATE TABLE t2(
- ts BIGINT,
- dur BIGINT,
- PRIMARY KEY (ts)
-) WITHOUT ROWID;
-
-INSERT INTO t2(ts, dur)
-VALUES
-(100, 400),
-(500, 50),
-(600, 100);
-
-CREATE VIRTUAL TABLE sp USING span_outer_join(t1, t2);
-
-SELECT * FROM sp;
-""",
- out=Csv("""
-"ts","dur"
-100,400
-500,50
-600,100
-"""))
-
- def test_span_outer_join_unpartitioned_right_empty(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query="""
-CREATE TABLE t1(
- ts BIGINT,
- dur BIGINT,
- PRIMARY KEY (ts)
-) WITHOUT ROWID;
-
-CREATE TABLE t2(
- ts BIGINT,
- dur BIGINT,
- PRIMARY KEY (ts)
-) WITHOUT ROWID;
-
-INSERT INTO t1(ts, dur)
-VALUES
-(100, 400),
-(500, 50),
-(600, 100);
-
-CREATE VIRTUAL TABLE sp USING span_outer_join(t1, t2);
-
-SELECT * FROM sp;
-""",
- out=Csv("""
-"ts","dur"
-100,400
-500,50
-600,100
-"""))
-
- def test_span_outer_join_mixed(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query=Path('span_outer_join_mixed_test.sql'),
- out=Path('span_outer_join_mixed.out'))
-
- def test_span_outer_join_mixed_empty(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query="""
-CREATE TABLE t1(
- ts BIGINT,
- dur BIGINT,
- part BIGINT,
- PRIMARY KEY (part, ts)
-) WITHOUT ROWID;
-
-CREATE TABLE t2(
- ts BIGINT,
- dur BIGINT,
- PRIMARY KEY (ts)
-) WITHOUT ROWID;
-
-
-CREATE VIRTUAL TABLE sp USING span_outer_join(t1 PARTITIONED part, t2);
-
-SELECT * FROM sp;
-""",
- out=Csv("""
-"ts","dur","part"
-"""))
-
- def test_span_outer_join_mixed_left_empty(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query="""
-CREATE TABLE t1(
- ts BIGINT,
- dur BIGINT,
- part BIGINT,
- PRIMARY KEY (part, ts)
-) WITHOUT ROWID;
-
-CREATE TABLE t2(
- ts BIGINT,
- dur BIGINT,
- PRIMARY KEY (ts)
-) WITHOUT ROWID;
-
-INSERT INTO t2(ts, dur)
-VALUES
-(100, 400),
-(500, 50),
-(600, 100);
-
-CREATE VIRTUAL TABLE sp USING span_outer_join(t1 PARTITIONED part, t2);
-
-SELECT * FROM sp;
-""",
- out=Csv("""
-"ts","dur","part"
-"""))
-
- def test_span_outer_join_mixed_left_empty_rev(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query="""
-CREATE TABLE t1(
- ts BIGINT,
- dur BIGINT,
- part BIGINT,
- PRIMARY KEY (part, ts)
-) WITHOUT ROWID;
-
-CREATE TABLE t2(
- ts BIGINT,
- dur BIGINT,
- PRIMARY KEY (ts)
-) WITHOUT ROWID;
-
-INSERT INTO t1(ts, dur, part)
-VALUES
-(100, 400, 0),
-(100, 50, 1),
-(600, 100, 1);
-
-CREATE VIRTUAL TABLE sp USING span_outer_join(t2, t1 PARTITIONED part);
-
-SELECT * FROM sp;
-""",
- out=Csv("""
-"ts","dur","part"
-100,400,0
-100,50,1
-600,100,1
-"""))
-
- def test_span_outer_join_mixed_right_empty(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query="""
-CREATE TABLE t1(
- ts BIGINT,
- dur BIGINT,
- part BIGINT,
- PRIMARY KEY (part, ts)
-) WITHOUT ROWID;
-
-CREATE TABLE t2(
- ts BIGINT,
- dur BIGINT,
- b BIGINT,
- PRIMARY KEY (ts)
-) WITHOUT ROWID;
-
-INSERT INTO t1(ts, dur, part)
-VALUES
-(100, 400, 0),
-(100, 50, 1),
-(600, 100, 1);
-
-CREATE VIRTUAL TABLE sp USING span_outer_join(t1 PARTITIONED part, t2);
-
-SELECT * FROM sp;
-""",
- out=Csv("""
-"ts","dur","part","b"
-100,400,0,"[NULL]"
-100,50,1,"[NULL]"
-600,100,1,"[NULL]"
-"""))
-
- def test_span_outer_join_mixed_right_empty_rev(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query="""
-CREATE TABLE t1(
- ts BIGINT,
- dur BIGINT,
- part BIGINT,
- PRIMARY KEY (part, ts)
-) WITHOUT ROWID;
-
-CREATE TABLE t2(
- ts BIGINT,
- dur BIGINT,
- b BIGINT,
- PRIMARY KEY (ts)
-) WITHOUT ROWID;
-
-INSERT INTO t2(ts, dur)
-VALUES
-(100, 400),
-(500, 50),
-(600, 100);
-
-CREATE VIRTUAL TABLE sp USING span_outer_join(t2, t1 PARTITIONED part);
-
-SELECT * FROM sp;
-""",
- out=Csv("""
-"ts","dur","part","b"
-"""))
-
- def test_span_outer_join_mixed_2(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query=Path('span_outer_join_mixed_test.sql'),
- out=Path('span_outer_join_mixed.out'))
-
- def test_span_left_join(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query=Path('span_left_join_test.sql'),
- out=Path('span_left_join.out'))
-
- def test_span_left_join_unpartitioned(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query=Path('span_left_join_unpartitioned_test.sql'),
- out=Path('span_left_join_unpartitioned.out'))
-
- def test_span_left_join_left_unpartitioned(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query=Path('span_left_join_left_unpartitioned_test.sql'),
- out=Path('span_left_join_left_unpartitioned.out'))
-
- def test_span_left_join_left_partitioned(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query=Path('span_left_join_left_partitioned_test.sql'),
- out=Path('span_left_join_left_partitioned.out'))
-
- def test_span_left_join_empty_right(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query="""
-CREATE TABLE t1(
- ts BIGINT,
- dur BIGINT,
- part BIGINT,
- PRIMARY KEY (part, ts)
-) WITHOUT ROWID;
-
-CREATE TABLE t2(
- ts BIGINT,
- dur BIGINT,
- part BIGINT,
- PRIMARY KEY (part, ts)
-) WITHOUT ROWID;
-
-INSERT INTO t1(ts, dur, part)
-VALUES
-(500, 500, 100);
-
-CREATE VIRTUAL TABLE sp USING span_left_join(t1 PARTITIONED part,
- t2 PARTITIONED part);
-
-SELECT * FROM sp;
-""",
- out=Csv("""
-"ts","dur","part"
-500,500,100
-"""))
-
- def test_span_left_join_unordered_android_sched_and_ps(self):
- return DiffTestBlueprint(
- trace=Path('../common/synth_1.py'),
- query="""
-CREATE TABLE t1(
- ts BIGINT,
- dur BIGINT,
- part BIGINT,
- PRIMARY KEY (part, ts)
-) WITHOUT ROWID;
-
-CREATE TABLE t2(
- ts BIGINT,
- dur BIGINT,
- part BIGINT,
- PRIMARY KEY (part, ts)
-) WITHOUT ROWID;
-
-INSERT INTO t1(ts, dur, part)
-VALUES (500, 100, 10);
-
-INSERT INTO t2(ts, dur, part)
-VALUES (500, 100, 5);
-
-CREATE VIRTUAL TABLE sp USING span_left_join(t1 PARTITIONED part,
- t2 PARTITIONED part);
-
-SELECT * FROM sp;
-""",
- out=Csv("""
-"ts","dur","part"
-500,100,10
-"""))
diff --git a/tools/gen_android_bp b/tools/gen_android_bp
index 5317914..179ac14 100755
--- a/tools/gen_android_bp
+++ b/tools/gen_android_bp
@@ -103,6 +103,7 @@
'//protos/perfetto/trace:perfetto_trace_protos',
'//src/trace_processor:demangle',
'//src/trace_processor:trace_processor_shell',
+ '//src/traced/service:traced',
]
target_vendor_available = [
diff --git a/ui/src/controller/track_decider.ts b/ui/src/controller/track_decider.ts
index 4882400..aadb889 100644
--- a/ui/src/controller/track_decider.ts
+++ b/ui/src/controller/track_decider.ts
@@ -198,14 +198,39 @@
return 'Unknown';
}
+ async guessCpuSizes(): Promise<Map<number, string>> {
+ const cpuToSize = new Map<number, string>();
+ await this.engine.query(`
+ SELECT IMPORT('common.cpus');
+ `);
+ const result = await this.engine.query(`
+ SELECT cpu, GUESS_CPU_SIZE(cpu) as size FROM cpu_counter_track;
+ `);
+
+ const it = result.iter({
+ cpu: NUM,
+ size: STR,
+ });
+
+ for (; it.valid(); it.next()) {
+ cpuToSize.set(it.cpu, it.size);
+ }
+
+ return cpuToSize;
+ }
+
async addCpuSchedulingTracks(): Promise<void> {
const cpus = await this.engine.getCpus();
+ const cpuToSize = await this.guessCpuSizes();
+
for (const cpu of cpus) {
+ const size = cpuToSize.get(cpu);
+ const name = size === undefined ? `Cpu ${cpu}` : `Cpu ${cpu} (${size})`;
this.tracksToAdd.push({
engineId: this.engineId,
kind: CPU_SLICE_TRACK_KIND,
trackSortKey: PrimaryTrackSortKey.ORDINARY_TRACK,
- name: `Cpu ${cpu}`,
+ name,
trackGroup: SCROLLING_TRACK_GROUP,
config: {
cpu,
diff --git a/ui/src/tracks/debug/add_debug_track_menu.ts b/ui/src/tracks/debug/add_debug_track_menu.ts
index d14bfd8..32bc871 100644
--- a/ui/src/tracks/debug/add_debug_track_menu.ts
+++ b/ui/src/tracks/debug/add_debug_track_menu.ts
@@ -89,7 +89,7 @@
m(FormLabel,
{for: 'track_name',
},
- 'Name'),
+ 'Track name'),
m(TextInput, {
id: 'track_name',
onkeydown: (e: KeyboardEvent) => {