Merge "Reapply "tp: fix build in Google3" Reapply "Refactor StackProfile related classes."" into main
diff --git a/Android.bp b/Android.bp
index 0ea862b..f4559d8 100644
--- a/Android.bp
+++ b/Android.bp
@@ -11999,6 +11999,8 @@
"src/trace_processor/perfetto_sql/stdlib/common/thread_states.sql",
"src/trace_processor/perfetto_sql/stdlib/common/timestamps.sql",
"src/trace_processor/perfetto_sql/stdlib/counters/intervals.sql",
+ "src/trace_processor/perfetto_sql/stdlib/cpu/cpus.sql",
+ "src/trace_processor/perfetto_sql/stdlib/cpu/size.sql",
"src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/args.sql",
"src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/counters.sql",
"src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/cpus.sql",
@@ -12014,6 +12016,7 @@
"src/trace_processor/perfetto_sql/stdlib/pkvm/hypervisor.sql",
"src/trace_processor/perfetto_sql/stdlib/prelude/slices.sql",
"src/trace_processor/perfetto_sql/stdlib/prelude/trace_bounds.sql",
+ "src/trace_processor/perfetto_sql/stdlib/sched/states.sql",
"src/trace_processor/perfetto_sql/stdlib/sched/thread_executing_span.sql",
"src/trace_processor/perfetto_sql/stdlib/sched/thread_level_parallelism.sql",
"src/trace_processor/perfetto_sql/stdlib/sched/thread_state_flattened.sql",
@@ -12446,6 +12449,7 @@
"src/traceconv/trace_to_profile.cc",
"src/traceconv/trace_to_systrace.cc",
"src/traceconv/trace_to_text.cc",
+ "src/traceconv/trace_unpack.cc",
],
}
diff --git a/BUILD b/BUILD
index 09ab8b4..09790fd 100644
--- a/BUILD
+++ b/BUILD
@@ -2405,6 +2405,15 @@
],
)
+# GN target: //src/trace_processor/perfetto_sql/stdlib/cpu:cpu
+perfetto_filegroup(
+ name = "src_trace_processor_perfetto_sql_stdlib_cpu_cpu",
+ srcs = [
+ "src/trace_processor/perfetto_sql/stdlib/cpu/cpus.sql",
+ "src/trace_processor/perfetto_sql/stdlib/cpu/size.sql",
+ ],
+)
+
# GN target: //src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common:common
perfetto_filegroup(
name = "src_trace_processor_perfetto_sql_stdlib_deprecated_v42_common_common",
@@ -2466,6 +2475,7 @@
perfetto_filegroup(
name = "src_trace_processor_perfetto_sql_stdlib_sched_sched",
srcs = [
+ "src/trace_processor/perfetto_sql/stdlib/sched/states.sql",
"src/trace_processor/perfetto_sql/stdlib/sched/thread_executing_span.sql",
"src/trace_processor/perfetto_sql/stdlib/sched/thread_level_parallelism.sql",
"src/trace_processor/perfetto_sql/stdlib/sched/thread_state_flattened.sql",
@@ -2499,6 +2509,7 @@
":src_trace_processor_perfetto_sql_stdlib_chrome_chrome_sql",
":src_trace_processor_perfetto_sql_stdlib_common_common",
":src_trace_processor_perfetto_sql_stdlib_counters_counters",
+ ":src_trace_processor_perfetto_sql_stdlib_cpu_cpu",
":src_trace_processor_perfetto_sql_stdlib_deprecated_v42_common_common",
":src_trace_processor_perfetto_sql_stdlib_graphs_graphs",
":src_trace_processor_perfetto_sql_stdlib_intervals_intervals",
@@ -2909,6 +2920,8 @@
"src/traceconv/trace_to_systrace.h",
"src/traceconv/trace_to_text.cc",
"src/traceconv/trace_to_text.h",
+ "src/traceconv/trace_unpack.cc",
+ "src/traceconv/trace_unpack.h",
],
)
diff --git a/include/perfetto/ext/base/unix_socket.h b/include/perfetto/ext/base/unix_socket.h
index c5ee44c..f0e7961 100644
--- a/include/perfetto/ext/base/unix_socket.h
+++ b/include/perfetto/ext/base/unix_socket.h
@@ -25,6 +25,7 @@
#include <utility>
#include "perfetto/base/build_config.h"
+#include "perfetto/base/compiler.h"
#include "perfetto/base/export.h"
#include "perfetto/base/logging.h"
#include "perfetto/base/platform_handle.h"
@@ -87,6 +88,7 @@
#if !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
return sock_family == SockFamily::kUnix;
#else
+ base::ignore_result(sock_family);
// On Windows shm is negotiated by sharing an unguessable token
// over TCP sockets. In theory works on any socket type, in practice
// we need to tell the difference between a local and a remote
diff --git a/perfetto.rc b/perfetto.rc
index 8a5ee38..18432dc 100644
--- a/perfetto.rc
+++ b/perfetto.rc
@@ -57,6 +57,9 @@
# by the bug reporting UI (ls+getattr).
mkdir /data/misc/perfetto-traces/bugreport 0773 root shell
+ # Traces in this directory are only accessed by system server
+ mkdir /data/misc/perfetto-traces/profiling 0773 root shell
+
# This directory allows shell to save configs file in a place where the
# perfetto cmdline client can read then. /data/local/tmp/ isn't safe because
# too many other domains can write into that. See b/170404111.
diff --git a/protos/perfetto/config/android/protolog_config.proto b/protos/perfetto/config/android/protolog_config.proto
index c73256e..af61c2b 100644
--- a/protos/perfetto/config/android/protolog_config.proto
+++ b/protos/perfetto/config/android/protolog_config.proto
@@ -41,8 +41,8 @@
}
message ProtoLogGroup {
- // The ProtoLog tag this configuration entry applies to.
- optional string tag = 1;
+ // The ProtoLog group name this configuration entry applies to.
+ optional string group_name = 1;
// Specify the level from which to start capturing protologs.
// e.g. if ProtoLogLevel.WARN is specified only warning, errors and fatal log
// message will be traced.
diff --git a/protos/perfetto/config/perfetto_config.proto b/protos/perfetto/config/perfetto_config.proto
index d91246b..36595af 100644
--- a/protos/perfetto/config/perfetto_config.proto
+++ b/protos/perfetto/config/perfetto_config.proto
@@ -594,8 +594,8 @@
}
message ProtoLogGroup {
- // The ProtoLog tag this configuration entry applies to.
- optional string tag = 1;
+ // The ProtoLog group name this configuration entry applies to.
+ optional string group_name = 1;
// Specify the level from which to start capturing protologs.
// e.g. if ProtoLogLevel.WARN is specified only warning, errors and fatal log
// message will be traced.
diff --git a/protos/perfetto/trace/perfetto_trace.proto b/protos/perfetto/trace/perfetto_trace.proto
index f9370cd..dde9fdb 100644
--- a/protos/perfetto/trace/perfetto_trace.proto
+++ b/protos/perfetto/trace/perfetto_trace.proto
@@ -594,8 +594,8 @@
}
message ProtoLogGroup {
- // The ProtoLog tag this configuration entry applies to.
- optional string tag = 1;
+ // The ProtoLog group name this configuration entry applies to.
+ optional string group_name = 1;
// Specify the level from which to start capturing protologs.
// e.g. if ProtoLogLevel.WARN is specified only warning, errors and fatal log
// message will be traced.
diff --git a/src/base/unix_socket_unittest.cc b/src/base/unix_socket_unittest.cc
index a0d0bb3..88383d1 100644
--- a/src/base/unix_socket_unittest.cc
+++ b/src/base/unix_socket_unittest.cc
@@ -1166,6 +1166,9 @@
}
TEST_F(UnixSocketTest, ShmemSupported) {
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
+ ASSERT_EQ(SockShmemSupported(""), true);
+#else // PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
ASSERT_EQ(SockShmemSupported(""), false);
ASSERT_EQ(SockShmemSupported("/path/to/sock"), true);
ASSERT_EQ(SockShmemSupported("local_dir_sock"), true);
@@ -1178,6 +1181,7 @@
PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
ASSERT_EQ(SockShmemSupported("vsock://-1:10000"), false);
#endif
+#endif // !PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
}
} // namespace
diff --git a/src/ipc/host_impl_unittest.cc b/src/ipc/host_impl_unittest.cc
index 927a5a6..ce732cd 100644
--- a/src/ipc/host_impl_unittest.cc
+++ b/src/ipc/host_impl_unittest.cc
@@ -15,7 +15,7 @@
*/
#include "src/ipc/host_impl.h"
-#include <sys/socket.h>
+
#include <memory>
#include "perfetto/ext/base/file_utils.h"
@@ -34,6 +34,11 @@
#include "protos/perfetto/ipc/wire_protocol.gen.h"
#include "src/ipc/test/client_unittest_messages.gen.h"
+#if PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) || \
+ PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
+#include <sys/socket.h>
+#endif
+
namespace perfetto {
namespace ipc {
namespace {
@@ -644,7 +649,8 @@
EXPECT_CALL(*cli, OnInvokeMethodReply(_)).WillOnce(Return());
task_runner->RunUntilIdle();
}
-#endif // OS_WIN
+#endif // PERFETTO_BUILDFLAG(PERFETTO_OS_LINUX) ||
+ // PERFETTO_BUILDFLAG(PERFETTO_OS_ANDROID)
// TODO(primiano): add the tests below in next CLs.
// TEST(HostImplTest, ManyClients) {}
diff --git a/src/perfetto_cmd/perfetto_cmd.cc b/src/perfetto_cmd/perfetto_cmd.cc
index 9d77c4b..e356b0d 100644
--- a/src/perfetto_cmd/perfetto_cmd.cc
+++ b/src/perfetto_cmd/perfetto_cmd.cc
@@ -35,6 +35,7 @@
#include <unistd.h>
#endif
+#include <atomic>
#include <chrono>
#include <fstream>
#include <iostream>
@@ -82,7 +83,7 @@
namespace perfetto {
namespace {
-perfetto::PerfettoCmd* g_perfetto_cmd;
+std::atomic<perfetto::PerfettoCmd*> g_perfetto_cmd;
const uint32_t kOnTraceDataTimeoutMs = 3000;
const uint32_t kCloneTimeoutMs = 10000;
@@ -209,13 +210,13 @@
PerfettoCmd::PerfettoCmd() {
// Only the main thread instance on the main thread will receive ctrl-c.
- if (!g_perfetto_cmd)
- g_perfetto_cmd = this;
+ PerfettoCmd* set_if_null = nullptr;
+ g_perfetto_cmd.compare_exchange_strong(set_if_null, this);
}
PerfettoCmd::~PerfettoCmd() {
- if (g_perfetto_cmd == this) {
- g_perfetto_cmd = nullptr;
+ PerfettoCmd* self = this;
+ if (g_perfetto_cmd.compare_exchange_strong(self, nullptr)) {
if (ctrl_c_handler_installed_) {
task_runner_.RemoveFileDescriptorWatch(ctrl_c_evt_.fd());
}
@@ -1297,9 +1298,8 @@
return;
ctrl_c_handler_installed_ = true;
base::InstallCtrlCHandler([] {
- if (!g_perfetto_cmd)
- return;
- g_perfetto_cmd->SignalCtrlC();
+ if (PerfettoCmd* main_thread = g_perfetto_cmd.load())
+ main_thread->SignalCtrlC();
});
auto weak_this = weak_factory_.GetWeakPtr();
task_runner_.AddFileDescriptorWatch(ctrl_c_evt_.fd(), [weak_this] {
diff --git a/src/trace_processor/db/column/arrangement_overlay.cc b/src/trace_processor/db/column/arrangement_overlay.cc
index 281071f..b9e3000 100644
--- a/src/trace_processor/db/column/arrangement_overlay.cc
+++ b/src/trace_processor/db/column/arrangement_overlay.cc
@@ -54,13 +54,6 @@
return inner_->SingleSearch(op, sql_val, (*arrangement_)[index]);
}
-UniqueSearchResult ArrangementOverlay::ChainImpl::UniqueSearch(
- FilterOp,
- SqlValue,
- uint32_t*) const {
- return UniqueSearchResult::kNeedsFullSearch;
-}
-
SearchValidationResult ArrangementOverlay::ChainImpl::ValidateSearchConstraints(
FilterOp op,
SqlValue value) const {
diff --git a/src/trace_processor/db/column/arrangement_overlay.h b/src/trace_processor/db/column/arrangement_overlay.h
index 6138918..bca884f 100644
--- a/src/trace_processor/db/column/arrangement_overlay.h
+++ b/src/trace_processor/db/column/arrangement_overlay.h
@@ -54,10 +54,6 @@
SqlValue,
uint32_t) const override;
- UniqueSearchResult UniqueSearch(FilterOp,
- SqlValue,
- uint32_t*) const override;
-
SearchValidationResult ValidateSearchConstraints(FilterOp,
SqlValue) const override;
diff --git a/src/trace_processor/db/column/data_layer.h b/src/trace_processor/db/column/data_layer.h
index 5ec7909..8f34845 100644
--- a/src/trace_processor/db/column/data_layer.h
+++ b/src/trace_processor/db/column/data_layer.h
@@ -111,29 +111,13 @@
// Start of public API.
- // Checks whether element at the the provided index match |op| and |value|.
+ // Checks whether element at the provided index match |op| and |value|.
//
- // Returns one of the following:
- // * kMatch if the element matches.
- // * kNoMatch if the element does not match.
- // * kNeedsFullSearch if one of the "full" search algorithms need to be
- // run to determine if the element matches.
+ // Returns true if the element matches, false otherwise.
virtual SingleSearchResult SingleSearch(FilterOp op,
SqlValue value,
uint32_t row) const = 0;
- // Searches for a *unique* element in chain which matches |op| and |value|.
- //
- // The return value is one of the following:
- // * kMatch if an element matches. |row| should be set to the index of
- // the element.
- // * kNoMatch if no element matches.
- // * kNeedsFullSearch if one of the "full" search algorithms need to be
- // run for this constraint.
- virtual UniqueSearchResult UniqueSearch(FilterOp op,
- SqlValue value,
- uint32_t* row) const = 0;
-
// Searches for elements which match |op| and |value| between |range.start|
// and |range.end|.
//
diff --git a/src/trace_processor/db/column/dense_null_overlay.cc b/src/trace_processor/db/column/dense_null_overlay.cc
index e7251a3..7dff76f 100644
--- a/src/trace_processor/db/column/dense_null_overlay.cc
+++ b/src/trace_processor/db/column/dense_null_overlay.cc
@@ -61,27 +61,6 @@
PERFETTO_FATAL("For GCC");
}
-UniqueSearchResult DenseNullOverlay::ChainImpl::UniqueSearch(
- FilterOp op,
- SqlValue sql_val,
- uint32_t* index) const {
- switch (inner_->UniqueSearch(op, sql_val, index)) {
- case UniqueSearchResult::kMatch:
- if (*index >= non_null_->size()) {
- return UniqueSearchResult::kNoMatch;
- }
- // If non_null_[index] is not set, then any result returned by |inner_| is
- // meaningless as the value in |inner_| is not a "real" value.
- return non_null_->IsSet(*index) ? UniqueSearchResult::kMatch
- : UniqueSearchResult::kNeedsFullSearch;
- case UniqueSearchResult::kNoMatch:
- return UniqueSearchResult::kNoMatch;
- case UniqueSearchResult::kNeedsFullSearch:
- return UniqueSearchResult::kNeedsFullSearch;
- }
- PERFETTO_FATAL("For GCC");
-}
-
SearchValidationResult DenseNullOverlay::ChainImpl::ValidateSearchConstraints(
FilterOp op,
SqlValue sql_val) const {
diff --git a/src/trace_processor/db/column/dense_null_overlay.h b/src/trace_processor/db/column/dense_null_overlay.h
index 4acec46..0f881fb 100644
--- a/src/trace_processor/db/column/dense_null_overlay.h
+++ b/src/trace_processor/db/column/dense_null_overlay.h
@@ -49,10 +49,6 @@
SqlValue,
uint32_t) const override;
- UniqueSearchResult UniqueSearch(FilterOp,
- SqlValue,
- uint32_t*) const override;
-
SearchValidationResult ValidateSearchConstraints(FilterOp,
SqlValue) const override;
diff --git a/src/trace_processor/db/column/dense_null_overlay_unittest.cc b/src/trace_processor/db/column/dense_null_overlay_unittest.cc
index 1678857..0cf6276 100644
--- a/src/trace_processor/db/column/dense_null_overlay_unittest.cc
+++ b/src/trace_processor/db/column/dense_null_overlay_unittest.cc
@@ -17,7 +17,6 @@
#include "src/trace_processor/db/column/dense_null_overlay.h"
#include <cstdint>
-#include <limits>
#include <memory>
#include <vector>
@@ -202,40 +201,6 @@
SingleSearchResult::kMatch);
}
-TEST(DenseNullOverlay, UniqueSearchNonNull) {
- BitVector bv{0, 1, 0, 1, 1};
- DenseNullOverlay storage(&bv);
- auto fake = FakeStorageChain::SearchSubset(5, Range(1, 2));
- auto chain = storage.MakeChain(std::move(fake));
-
- uint32_t row = std::numeric_limits<uint32_t>::max();
- ASSERT_EQ(chain->UniqueSearch(FilterOp::kIsNotNull, SqlValue(), &row),
- UniqueSearchResult::kMatch);
- ASSERT_EQ(row, 1u);
-}
-
-TEST(DenseNullOverlay, UniqueSearchNull) {
- BitVector bv{0, 0, 0, 1, 1};
- DenseNullOverlay storage(&bv);
- auto fake = FakeStorageChain::SearchSubset(5, Range(1, 2));
- auto chain = storage.MakeChain(std::move(fake));
-
- uint32_t row = std::numeric_limits<uint32_t>::max();
- ASSERT_EQ(chain->UniqueSearch(FilterOp::kIsNotNull, SqlValue(), &row),
- UniqueSearchResult::kNeedsFullSearch);
-}
-
-TEST(DenseNullOverlay, UniqueSearchOutOfBounds) {
- BitVector bv{0, 0, 0, 1, 1};
- DenseNullOverlay storage(&bv);
- auto fake = FakeStorageChain::SearchSubset(6, Range(5, 6));
- auto chain = storage.MakeChain(std::move(fake));
-
- uint32_t row = std::numeric_limits<uint32_t>::max();
- ASSERT_EQ(chain->UniqueSearch(FilterOp::kIsNotNull, SqlValue(), &row),
- UniqueSearchResult::kNoMatch);
-}
-
TEST(DenseNullOverlay, StableSort) {
std::vector<uint32_t> numeric_data{0, 3, 0, 1, 0, 2, 4};
NumericStorage<uint32_t> numeric(&numeric_data, ColumnType::kUint32, false);
diff --git a/src/trace_processor/db/column/dummy_storage.cc b/src/trace_processor/db/column/dummy_storage.cc
index 0f182f8..54d7c61 100644
--- a/src/trace_processor/db/column/dummy_storage.cc
+++ b/src/trace_processor/db/column/dummy_storage.cc
@@ -31,12 +31,6 @@
PERFETTO_FATAL("Shouldn't be called");
}
-UniqueSearchResult DummyStorage::ChainImpl::UniqueSearch(FilterOp,
- SqlValue,
- uint32_t*) const {
- PERFETTO_FATAL("Shouldn't be called");
-}
-
SearchValidationResult DummyStorage::ChainImpl::ValidateSearchConstraints(
FilterOp,
SqlValue) const {
diff --git a/src/trace_processor/db/column/dummy_storage.h b/src/trace_processor/db/column/dummy_storage.h
index 286c1ea..ced41a9 100644
--- a/src/trace_processor/db/column/dummy_storage.h
+++ b/src/trace_processor/db/column/dummy_storage.h
@@ -38,10 +38,6 @@
SqlValue,
uint32_t) const override;
- UniqueSearchResult UniqueSearch(FilterOp,
- SqlValue,
- uint32_t*) const override;
-
SearchValidationResult ValidateSearchConstraints(FilterOp,
SqlValue) const override;
diff --git a/src/trace_processor/db/column/fake_storage.cc b/src/trace_processor/db/column/fake_storage.cc
index 1bab025..9fbc3ae 100644
--- a/src/trace_processor/db/column/fake_storage.cc
+++ b/src/trace_processor/db/column/fake_storage.cc
@@ -56,34 +56,6 @@
PERFETTO_FATAL("For GCC");
}
-UniqueSearchResult FakeStorageChain::UniqueSearch(FilterOp,
- SqlValue,
- uint32_t* i) const {
- switch (strategy_) {
- case kAll:
- if (size_ != 1) {
- return UniqueSearchResult::kNeedsFullSearch;
- }
- *i = 0;
- return UniqueSearchResult::kMatch;
- case kNone:
- return UniqueSearchResult::kNoMatch;
- case kBitVector:
- if (bit_vector_.CountSetBits() != 1) {
- return UniqueSearchResult::kNeedsFullSearch;
- }
- *i = bit_vector_.IndexOfNthSet(0);
- return UniqueSearchResult::kMatch;
- case kRange:
- if (range_.size() != 1) {
- return UniqueSearchResult::kNeedsFullSearch;
- }
- *i = range_.start;
- return UniqueSearchResult::kMatch;
- }
- PERFETTO_FATAL("For GCC");
-}
-
SearchValidationResult FakeStorageChain::ValidateSearchConstraints(
FilterOp,
SqlValue) const {
diff --git a/src/trace_processor/db/column/fake_storage.h b/src/trace_processor/db/column/fake_storage.h
index 8d4d6b5..aca6890 100644
--- a/src/trace_processor/db/column/fake_storage.h
+++ b/src/trace_processor/db/column/fake_storage.h
@@ -77,8 +77,6 @@
// Implementation of DataLayerChain.
SingleSearchResult SingleSearch(FilterOp, SqlValue, uint32_t) const override;
- UniqueSearchResult UniqueSearch(FilterOp, SqlValue, uint32_t*) const override;
-
SearchValidationResult ValidateSearchConstraints(FilterOp,
SqlValue) const override;
diff --git a/src/trace_processor/db/column/id_storage.cc b/src/trace_processor/db/column/id_storage.cc
index 1c32194..6fdb800 100644
--- a/src/trace_processor/db/column/id_storage.cc
+++ b/src/trace_processor/db/column/id_storage.cc
@@ -191,19 +191,6 @@
PERFETTO_FATAL("For GCC");
}
-UniqueSearchResult IdStorage::ChainImpl::UniqueSearch(FilterOp op,
- SqlValue sql_val,
- uint32_t* index) const {
- if (sql_val.type != SqlValue::kLong ||
- sql_val.long_value >= std::numeric_limits<uint32_t>::max() ||
- sql_val.long_value <= std::numeric_limits<uint32_t>::min() ||
- op != FilterOp::kEq) {
- return UniqueSearchResult::kNeedsFullSearch;
- }
- *index = static_cast<uint32_t>(sql_val.long_value);
- return UniqueSearchResult::kMatch;
-}
-
RangeOrBitVector IdStorage::ChainImpl::SearchValidated(
FilterOp op,
SqlValue sql_val,
diff --git a/src/trace_processor/db/column/id_storage.h b/src/trace_processor/db/column/id_storage.h
index bb0d7d5..e6e25ab 100644
--- a/src/trace_processor/db/column/id_storage.h
+++ b/src/trace_processor/db/column/id_storage.h
@@ -48,10 +48,6 @@
SqlValue,
uint32_t) const override;
- UniqueSearchResult UniqueSearch(FilterOp,
- SqlValue,
- uint32_t*) const override;
-
SearchValidationResult ValidateSearchConstraints(FilterOp,
SqlValue) const override;
diff --git a/src/trace_processor/db/column/id_storage_unittest.cc b/src/trace_processor/db/column/id_storage_unittest.cc
index 32b0583..48ce18e 100644
--- a/src/trace_processor/db/column/id_storage_unittest.cc
+++ b/src/trace_processor/db/column/id_storage_unittest.cc
@@ -145,25 +145,6 @@
SingleSearchResult::kNoMatch);
}
-TEST(IdStorage, UniqueSearch) {
- IdStorage storage;
- auto chain = storage.MakeChain();
-
- uint32_t row = std::numeric_limits<uint32_t>::max();
- ASSERT_EQ(chain->UniqueSearch(FilterOp::kEq, SqlValue::Long(5), &row),
- UniqueSearchResult::kMatch);
- ASSERT_EQ(row, 5u);
-
- row = std::numeric_limits<uint32_t>::max();
- ASSERT_EQ(
- chain->UniqueSearch(
- FilterOp::kEq,
- SqlValue::Long(std::numeric_limits<uint32_t>::max() + 1ll), &row),
- UniqueSearchResult::kNeedsFullSearch);
- ASSERT_EQ(chain->UniqueSearch(FilterOp::kEq, SqlValue::Double(0), &row),
- UniqueSearchResult::kNeedsFullSearch);
-}
-
TEST(IdStorage, SearchEqSimple) {
IdStorage storage;
auto chain = storage.MakeChain();
diff --git a/src/trace_processor/db/column/null_overlay.cc b/src/trace_processor/db/column/null_overlay.cc
index fe489e4..af31ac5 100644
--- a/src/trace_processor/db/column/null_overlay.cc
+++ b/src/trace_processor/db/column/null_overlay.cc
@@ -104,24 +104,6 @@
PERFETTO_FATAL("For GCC");
}
-UniqueSearchResult NullOverlay::ChainImpl::UniqueSearch(FilterOp op,
- SqlValue sql_val,
- uint32_t* index) const {
- switch (inner_->UniqueSearch(op, sql_val, index)) {
- case UniqueSearchResult::kMatch:
- if (*index >= non_null_->CountSetBits()) {
- return UniqueSearchResult::kNoMatch;
- }
- *index = non_null_->IndexOfNthSet(*index);
- return UniqueSearchResult::kMatch;
- case UniqueSearchResult::kNoMatch:
- return UniqueSearchResult::kNoMatch;
- case UniqueSearchResult::kNeedsFullSearch:
- return UniqueSearchResult::kNeedsFullSearch;
- }
- PERFETTO_FATAL("For GCC");
-}
-
NullOverlay::ChainImpl::ChainImpl(std::unique_ptr<DataLayerChain> innner,
const BitVector* non_null)
: inner_(std::move(innner)), non_null_(non_null) {
diff --git a/src/trace_processor/db/column/null_overlay.h b/src/trace_processor/db/column/null_overlay.h
index 35c5e52..99f6256 100644
--- a/src/trace_processor/db/column/null_overlay.h
+++ b/src/trace_processor/db/column/null_overlay.h
@@ -48,10 +48,6 @@
SqlValue,
uint32_t) const override;
- UniqueSearchResult UniqueSearch(FilterOp,
- SqlValue,
- uint32_t*) const override;
-
SearchValidationResult ValidateSearchConstraints(FilterOp,
SqlValue) const override;
diff --git a/src/trace_processor/db/column/null_overlay_unittest.cc b/src/trace_processor/db/column/null_overlay_unittest.cc
index 73934a6..ceb6c9f 100644
--- a/src/trace_processor/db/column/null_overlay_unittest.cc
+++ b/src/trace_processor/db/column/null_overlay_unittest.cc
@@ -17,7 +17,6 @@
#include "src/trace_processor/db/column/null_overlay.h"
#include <cstdint>
-#include <limits>
#include <memory>
#include <vector>
@@ -74,29 +73,6 @@
SingleSearchResult::kNoMatch);
}
-TEST(NullOverlay, UniqueSearch) {
- BitVector bv{0, 0, 0, 1, 1};
- NullOverlay storage(&bv);
- auto fake = FakeStorageChain::SearchSubset(5, Range(1, 2));
- auto chain = storage.MakeChain(std::move(fake));
-
- uint32_t row = std::numeric_limits<uint32_t>::max();
- ASSERT_EQ(chain->UniqueSearch(FilterOp::kIsNotNull, SqlValue(), &row),
- UniqueSearchResult::kMatch);
- ASSERT_EQ(row, 4u);
-}
-
-TEST(NullOverlay, UniqueSearchOutOfBounds) {
- BitVector bv{0, 0, 0, 1, 1};
- NullOverlay storage(&bv);
- auto fake = FakeStorageChain::SearchSubset(5, Range(4, 5));
- auto chain = storage.MakeChain(std::move(fake));
-
- uint32_t row = std::numeric_limits<uint32_t>::max();
- ASSERT_EQ(chain->UniqueSearch(FilterOp::kIsNotNull, SqlValue(), &row),
- UniqueSearchResult::kNoMatch);
-}
-
TEST(NullOverlay, SearchInputInsideBoundary) {
BitVector bv{0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0};
auto fake = FakeStorageChain::SearchAll(4u);
diff --git a/src/trace_processor/db/column/numeric_storage.cc b/src/trace_processor/db/column/numeric_storage.cc
index 27f6204..529e93d 100644
--- a/src/trace_processor/db/column/numeric_storage.cc
+++ b/src/trace_processor/db/column/numeric_storage.cc
@@ -27,7 +27,6 @@
#include <string>
#include <utility>
#include <variant>
-#include <vector>
#include "perfetto/base/logging.h"
#include "perfetto/public/compiler.h"
@@ -259,7 +258,7 @@
auto i_as_d = static_cast<double>(i);
// Case when |sql_val| can be interpreted as a SqlValue::Long.
- if (std::equal_to<>()(i, static_cast<int64_t>(i_as_d))) {
+ if (std::equal_to<int64_t>()(i, static_cast<int64_t>(i_as_d))) {
*sql_val = SqlValue::Double(i_as_d);
return SearchValidationResult::kOk;
}
@@ -299,13 +298,6 @@
bool is_sorted)
: vector_ptr_(vector_ptr), storage_type_(type), is_sorted_(is_sorted) {}
-UniqueSearchResult NumericStorageBase::ChainImpl::UniqueSearch(
- FilterOp,
- SqlValue,
- uint32_t*) const {
- return UniqueSearchResult::kNeedsFullSearch;
-}
-
SearchValidationResult NumericStorageBase::ChainImpl::ValidateSearchConstraints(
FilterOp op,
SqlValue val) const {
diff --git a/src/trace_processor/db/column/numeric_storage.h b/src/trace_processor/db/column/numeric_storage.h
index af69e28..2dfafc6 100644
--- a/src/trace_processor/db/column/numeric_storage.h
+++ b/src/trace_processor/db/column/numeric_storage.h
@@ -37,10 +37,6 @@
protected:
class ChainImpl : public DataLayerChain {
public:
- UniqueSearchResult UniqueSearch(FilterOp,
- SqlValue,
- uint32_t*) const override;
-
SearchValidationResult ValidateSearchConstraints(FilterOp,
SqlValue) const override;
diff --git a/src/trace_processor/db/column/range_overlay.cc b/src/trace_processor/db/column/range_overlay.cc
index 308bf1c..0b8275b 100644
--- a/src/trace_processor/db/column/range_overlay.cc
+++ b/src/trace_processor/db/column/range_overlay.cc
@@ -47,25 +47,6 @@
return inner_->SingleSearch(op, sql_val, i + range_->start);
}
-UniqueSearchResult RangeOverlay::ChainImpl::UniqueSearch(
- FilterOp op,
- SqlValue sql_val,
- uint32_t* index) const {
- switch (inner_->UniqueSearch(op, sql_val, index)) {
- case UniqueSearchResult::kMatch:
- if (!range_->Contains(*index)) {
- return UniqueSearchResult::kNoMatch;
- }
- *index -= range_->start;
- return UniqueSearchResult::kMatch;
- case UniqueSearchResult::kNoMatch:
- return UniqueSearchResult::kNoMatch;
- case UniqueSearchResult::kNeedsFullSearch:
- return UniqueSearchResult::kNeedsFullSearch;
- }
- PERFETTO_FATAL("For GCC");
-}
-
SearchValidationResult RangeOverlay::ChainImpl::ValidateSearchConstraints(
FilterOp op,
SqlValue sql_val) const {
diff --git a/src/trace_processor/db/column/range_overlay.h b/src/trace_processor/db/column/range_overlay.h
index 366b2d3..200d5d4 100644
--- a/src/trace_processor/db/column/range_overlay.h
+++ b/src/trace_processor/db/column/range_overlay.h
@@ -45,10 +45,6 @@
SqlValue,
uint32_t) const override;
- UniqueSearchResult UniqueSearch(FilterOp,
- SqlValue,
- uint32_t*) const override;
-
SearchValidationResult ValidateSearchConstraints(FilterOp,
SqlValue) const override;
diff --git a/src/trace_processor/db/column/range_overlay_unittest.cc b/src/trace_processor/db/column/range_overlay_unittest.cc
index bf13cbb..96c2f80 100644
--- a/src/trace_processor/db/column/range_overlay_unittest.cc
+++ b/src/trace_processor/db/column/range_overlay_unittest.cc
@@ -17,8 +17,6 @@
#include "src/trace_processor/db/column/range_overlay.h"
#include <cstdint>
-#include <limits>
-#include <utility>
#include <vector>
#include "perfetto/trace_processor/basic_types.h"
@@ -37,7 +35,7 @@
using testing::IsEmpty;
using Range = Range;
-TEST(SelectorOverlay, SingleSearch) {
+TEST(RangeOverlay, SearchSingle) {
Range range(3, 8);
RangeOverlay storage(&range);
auto fake = FakeStorageChain::SearchSubset(
@@ -50,40 +48,6 @@
SingleSearchResult::kNoMatch);
}
-TEST(SelectorOverlay, UniqueSearch) {
- Range range(1, 3);
- RangeOverlay storage(&range);
- auto fake = FakeStorageChain::SearchSubset(5, Range(2, 3));
- auto chain = storage.MakeChain(std::move(fake));
-
- uint32_t row = std::numeric_limits<uint32_t>::max();
- ASSERT_EQ(chain->UniqueSearch(FilterOp::kIsNotNull, SqlValue(), &row),
- UniqueSearchResult::kMatch);
- ASSERT_EQ(row, 1u);
-}
-
-TEST(SelectorOverlay, UniqueSearchLowOutOfBounds) {
- Range range(3, 8);
- RangeOverlay storage(&range);
- auto fake = FakeStorageChain::SearchSubset(8, Range(1, 2));
- auto chain = storage.MakeChain(std::move(fake));
-
- uint32_t row = std::numeric_limits<uint32_t>::max();
- ASSERT_EQ(chain->UniqueSearch(FilterOp::kIsNotNull, SqlValue(), &row),
- UniqueSearchResult::kNoMatch);
-}
-
-TEST(SelectorOverlay, UniqueSearchHighOutOfBounds) {
- Range range(3, 8);
- RangeOverlay storage(&range);
- auto fake = FakeStorageChain::SearchSubset(9, Range(8, 9));
- auto chain = storage.MakeChain(std::move(fake));
-
- uint32_t row = std::numeric_limits<uint32_t>::max();
- ASSERT_EQ(chain->UniqueSearch(FilterOp::kIsNotNull, SqlValue(), &row),
- UniqueSearchResult::kNoMatch);
-}
-
TEST(RangeOverlay, SearchAll) {
Range range(3, 8);
RangeOverlay storage(&range);
diff --git a/src/trace_processor/db/column/selector_overlay.cc b/src/trace_processor/db/column/selector_overlay.cc
index 935c4e2..ff1e463 100644
--- a/src/trace_processor/db/column/selector_overlay.cc
+++ b/src/trace_processor/db/column/selector_overlay.cc
@@ -44,25 +44,6 @@
return inner_->SingleSearch(op, sql_val, selector_->IndexOfNthSet(i));
}
-UniqueSearchResult SelectorOverlay::ChainImpl::UniqueSearch(
- FilterOp op,
- SqlValue sql_val,
- uint32_t* index) const {
- switch (inner_->UniqueSearch(op, sql_val, index)) {
- case UniqueSearchResult::kMatch:
- if (*index >= selector_->size() || !selector_->IsSet(*index)) {
- return UniqueSearchResult::kNoMatch;
- }
- *index = selector_->CountSetBits(*index);
- return UniqueSearchResult::kMatch;
- case UniqueSearchResult::kNoMatch:
- return UniqueSearchResult::kNoMatch;
- case UniqueSearchResult::kNeedsFullSearch:
- return UniqueSearchResult::kNeedsFullSearch;
- }
- PERFETTO_FATAL("For GCC");
-}
-
SearchValidationResult SelectorOverlay::ChainImpl::ValidateSearchConstraints(
FilterOp op,
SqlValue sql_val) const {
diff --git a/src/trace_processor/db/column/selector_overlay.h b/src/trace_processor/db/column/selector_overlay.h
index 04bc2e7..04f178a 100644
--- a/src/trace_processor/db/column/selector_overlay.h
+++ b/src/trace_processor/db/column/selector_overlay.h
@@ -49,10 +49,6 @@
SqlValue,
uint32_t) const override;
- UniqueSearchResult UniqueSearch(FilterOp,
- SqlValue,
- uint32_t*) const override;
-
SearchValidationResult ValidateSearchConstraints(FilterOp,
SqlValue) const override;
diff --git a/src/trace_processor/db/column/selector_overlay_unittest.cc b/src/trace_processor/db/column/selector_overlay_unittest.cc
index b9151b8..11d20f2 100644
--- a/src/trace_processor/db/column/selector_overlay_unittest.cc
+++ b/src/trace_processor/db/column/selector_overlay_unittest.cc
@@ -17,12 +17,11 @@
#include "src/trace_processor/db/column/selector_overlay.h"
#include <cstdint>
-#include <limits>
#include <vector>
+#include "data_layer.h"
#include "perfetto/trace_processor/basic_types.h"
#include "src/trace_processor/containers/bit_vector.h"
-#include "src/trace_processor/db/column/data_layer.h"
#include "src/trace_processor/db/column/fake_storage.h"
#include "src/trace_processor/db/column/numeric_storage.h"
#include "src/trace_processor/db/column/types.h"
@@ -47,38 +46,6 @@
SingleSearchResult::kNoMatch);
}
-TEST(SelectorOverlay, UniqueSearch) {
- BitVector selector{0, 1, 1, 0, 0, 1, 1, 0};
- auto fake = FakeStorageChain::SearchSubset(8, Range(2, 3));
- SelectorOverlay storage(&selector);
- auto chain = storage.MakeChain(std::move(fake));
-
- uint32_t row = std::numeric_limits<uint32_t>::max();
- ASSERT_EQ(chain->UniqueSearch(FilterOp::kGe, SqlValue::Long(0u), &row),
- UniqueSearchResult::kMatch);
- ASSERT_EQ(row, 1u);
-}
-
-TEST(SelectorOverlay, UniqueSearchNotSet) {
- BitVector selector{0, 1, 1, 0, 0, 1, 1, 0};
- auto fake = FakeStorageChain::SearchSubset(8, Range(4, 5));
- SelectorOverlay storage(&selector);
- auto chain = storage.MakeChain(std::move(fake));
-
- ASSERT_EQ(chain->SingleSearch(FilterOp::kGe, SqlValue::Long(0u), 1),
- SingleSearchResult::kNoMatch);
-}
-
-TEST(SelectorOverlay, UniqueSearchOutOfBounds) {
- BitVector selector{0, 1, 1, 0, 0, 1, 1, 0};
- auto fake = FakeStorageChain::SearchSubset(9, Range(8, 9));
- SelectorOverlay storage(&selector);
- auto chain = storage.MakeChain(std::move(fake));
-
- ASSERT_EQ(chain->SingleSearch(FilterOp::kGe, SqlValue::Long(0u), 1),
- SingleSearchResult::kNoMatch);
-}
-
TEST(SelectorOverlay, SearchAll) {
BitVector selector{0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 1};
auto fake = FakeStorageChain::SearchAll(10);
diff --git a/src/trace_processor/db/column/set_id_storage.cc b/src/trace_processor/db/column/set_id_storage.cc
index 3e9d497..780761c 100644
--- a/src/trace_processor/db/column/set_id_storage.cc
+++ b/src/trace_processor/db/column/set_id_storage.cc
@@ -83,12 +83,6 @@
static_cast<uint32_t>(sql_val.long_value));
}
-UniqueSearchResult SetIdStorage::ChainImpl::UniqueSearch(FilterOp,
- SqlValue,
- uint32_t*) const {
- return UniqueSearchResult::kNeedsFullSearch;
-}
-
SearchValidationResult SetIdStorage::ChainImpl::ValidateSearchConstraints(
FilterOp op,
SqlValue val) const {
diff --git a/src/trace_processor/db/column/set_id_storage.h b/src/trace_processor/db/column/set_id_storage.h
index 86d2508..64f14a3 100644
--- a/src/trace_processor/db/column/set_id_storage.h
+++ b/src/trace_processor/db/column/set_id_storage.h
@@ -47,10 +47,6 @@
SqlValue,
uint32_t) const override;
- UniqueSearchResult UniqueSearch(FilterOp,
- SqlValue,
- uint32_t*) const override;
-
SearchValidationResult ValidateSearchConstraints(FilterOp,
SqlValue) const override;
diff --git a/src/trace_processor/db/column/string_storage.cc b/src/trace_processor/db/column/string_storage.cc
index ae6a797..05f5932 100644
--- a/src/trace_processor/db/column/string_storage.cc
+++ b/src/trace_processor/db/column/string_storage.cc
@@ -280,12 +280,6 @@
PERFETTO_FATAL("For GCC");
}
-UniqueSearchResult StringStorage::ChainImpl::UniqueSearch(FilterOp,
- SqlValue,
- uint32_t*) const {
- return UniqueSearchResult::kNeedsFullSearch;
-}
-
SearchValidationResult StringStorage::ChainImpl::ValidateSearchConstraints(
FilterOp op,
SqlValue val) const {
diff --git a/src/trace_processor/db/column/string_storage.h b/src/trace_processor/db/column/string_storage.h
index 03541aa..d61aef5 100644
--- a/src/trace_processor/db/column/string_storage.h
+++ b/src/trace_processor/db/column/string_storage.h
@@ -50,10 +50,6 @@
SqlValue,
uint32_t) const override;
- UniqueSearchResult UniqueSearch(FilterOp,
- SqlValue,
- uint32_t*) const override;
-
SearchValidationResult ValidateSearchConstraints(FilterOp,
SqlValue) const override;
diff --git a/src/trace_processor/db/column/types.h b/src/trace_processor/db/column/types.h
index f27daa7..803c6ce 100644
--- a/src/trace_processor/db/column/types.h
+++ b/src/trace_processor/db/column/types.h
@@ -37,17 +37,6 @@
// the crtiteria, a call to *Search is required.
};
-// Result of calling Storage::UniqueSearch function.
-enum class UniqueSearchResult {
- kMatch, // The returned row matches the constraint.
- kNoMatch, // The returned row does not matches the constraint.
- kNeedsFullSearch, // UniqueSearch was unable to determine if a row meets
- // the crtiteria, a call to *Search is required. This
- // does not mean there >1 row necessarily, just that
- // UniqueSearch was unable to quickly identify a single
- // row.
-};
-
// Result of calling Storage::ValidateSearchResult function.
enum class SearchValidationResult {
kOk, // It makes sense to run search
diff --git a/src/trace_processor/db/query_executor.cc b/src/trace_processor/db/query_executor.cc
index 30214e4..bd15245 100644
--- a/src/trace_processor/db/query_executor.cc
+++ b/src/trace_processor/db/query_executor.cc
@@ -57,21 +57,6 @@
}
}
- // Given the chain a chance to return a single row which uniquely matches
- // this constraint. This is a relatively frequent occurence e.g. id equality
- // constraints so it is valuable to have an explicit fastpath.
- uint32_t unique_row;
- switch (chain.UniqueSearch(c.op, c.value, &unique_row)) {
- case UniqueSearchResult::kMatch:
- rm->IntersectExact(unique_row);
- return;
- case UniqueSearchResult::kNoMatch:
- rm->Clear();
- return;
- case UniqueSearchResult::kNeedsFullSearch:
- break;
- }
-
// Comparison of NULL with any operation apart from |IS_NULL| and
// |IS_NOT_NULL| should return no rows.
if (c.value.is_null() && c.op != FilterOp::kIsNull &&
diff --git a/src/trace_processor/importers/ftrace/ftrace_parser.h b/src/trace_processor/importers/ftrace/ftrace_parser.h
index 75f2130..f3234bd 100644
--- a/src/trace_processor/importers/ftrace/ftrace_parser.h
+++ b/src/trace_processor/importers/ftrace/ftrace_parser.h
@@ -233,7 +233,7 @@
void ParseWakeSourceDeactivate(int64_t timestamp, protozero::ConstBytes);
void ParseSuspendResume(int64_t timestamp, protozero::ConstBytes);
void ParseSuspendResumeMinimal(int64_t timestamp, protozero::ConstBytes);
- void ParseSchedCpuUtilCfs(int64_t timestap, protozero::ConstBytes);
+ void ParseSchedCpuUtilCfs(int64_t timestamp, protozero::ConstBytes);
void ParseFuncgraphEntry(int64_t timestamp,
uint32_t pid,
diff --git a/src/trace_processor/metrics/sql/chrome/chrome_reliable_range.sql b/src/trace_processor/metrics/sql/chrome/chrome_reliable_range.sql
index 66a1aa8..61e34c4 100644
--- a/src/trace_processor/metrics/sql/chrome/chrome_reliable_range.sql
+++ b/src/trace_processor/metrics/sql/chrome/chrome_reliable_range.sql
@@ -21,7 +21,14 @@
-- b. The event rate for the thread is at or above 75p.
-- Note: this metric considers only chrome processes and their threads, i.e. the ones coming
-- from track_event's.
-INCLUDE PERFETTO MODULE common.metadata;
+
+-- Extracts an int value with the given name from the metadata table.
+CREATE OR REPLACE PERFETTO FUNCTION _extract_int_metadata(
+ -- The name of the metadata entry.
+ name STRING)
+-- int_value for the given name. NULL if there's no such entry.
+RETURNS LONG AS
+SELECT int_value FROM metadata WHERE name = ($name);
DROP VIEW IF EXISTS chrome_event_stats_per_thread;
@@ -153,9 +160,9 @@
SELECT
-- If the trace has a cropping packet, we don't want to recompute the reliable
-- based on cropped track events - the result might be incorrect.
- IFNULL(extract_int_metadata('range_of_interest_start_us') * 1000,
+ IFNULL(_extract_int_metadata('range_of_interest_start_us') * 1000,
MAX(thread_start, data_loss_free_start)) AS start,
- IIF(extract_int_metadata('range_of_interest_start_us') IS NOT NULL,
+ IIF(_extract_int_metadata('range_of_interest_start_us') IS NOT NULL,
'Range of interest packet',
IIF(limiting_upid IN (SELECT upid FROM chrome_processes_with_missing_main),
'Missing main thread for upid=' || limiting_upid,
diff --git a/src/trace_processor/perfetto_sql/stdlib/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/BUILD.gn
index fa871e6..4ad989b 100644
--- a/src/trace_processor/perfetto_sql/stdlib/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/stdlib/BUILD.gn
@@ -23,6 +23,7 @@
"chrome:chrome_sql",
"common",
"counters",
+ "cpu",
"deprecated/v42/common",
"graphs",
"intervals",
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/oom_adjuster.sql b/src/trace_processor/perfetto_sql/stdlib/android/oom_adjuster.sql
index 314e612..3ce017e 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/oom_adjuster.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/oom_adjuster.sql
@@ -14,7 +14,7 @@
-- limitations under the License.
--
-INCLUDE PERFETTO MODULE common.slices;
+INCLUDE PERFETTO MODULE slices.with_context;
INCLUDE PERFETTO MODULE counters.intervals;
-- Converts an oom_adj score Integer to String bucket name.
diff --git a/src/trace_processor/perfetto_sql/stdlib/android/suspend.sql b/src/trace_processor/perfetto_sql/stdlib/android/suspend.sql
index 9e604b5..0d31b0d 100644
--- a/src/trace_processor/perfetto_sql/stdlib/android/suspend.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/android/suspend.sql
@@ -14,8 +14,6 @@
-- limitations under the License.
--
-INCLUDE PERFETTO MODULE common.timestamps;
-
-- Table of suspended and awake slices.
--
-- Selects either the minimal or full ftrace source depending on what's
diff --git a/src/trace_processor/perfetto_sql/stdlib/cpu/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/cpu/BUILD.gn
new file mode 100644
index 0000000..e17e6b2
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/cpu/BUILD.gn
@@ -0,0 +1,22 @@
+# Copyright (C) 2024 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import("../../../../../gn/perfetto_sql.gni")
+
+perfetto_sql_source_set("cpu") {
+ sources = [
+ "cpus.sql",
+ "size.sql",
+ ]
+}
diff --git a/src/trace_processor/perfetto_sql/stdlib/cpu/cpus.sql b/src/trace_processor/perfetto_sql/stdlib/cpu/cpus.sql
new file mode 100644
index 0000000..0d13879
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/cpu/cpus.sql
@@ -0,0 +1,28 @@
+--
+-- Copyright 2024 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
+--
+-- https://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing, software
+-- distributed under the License is distributed on an "AS IS" BASIS,
+-- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+-- See the License for the specific language governing permissions and
+-- limitations under the License.
+
+INCLUDE PERFETTO MODULE cpu.size;
+
+-- All of the CPUs with their core type as a descriptive size ('little', 'mid', 'big', etc).
+CREATE PERFETTO TABLE cpu_core_types(
+ -- Index of the CPU.
+ cpu_index INT,
+ -- A descriptive size ('little', 'mid', 'big', etc) or NULL if we have insufficient information.
+ size STRING
+) AS
+SELECT
+ cpu as cpu_index,
+ cpu_guess_core_type(cpu) AS size
+FROM _ranked_cpus;
\ No newline at end of file
diff --git a/src/trace_processor/perfetto_sql/stdlib/cpu/size.sql b/src/trace_processor/perfetto_sql/stdlib/cpu/size.sql
new file mode 100644
index 0000000..6536172
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/cpu/size.sql
@@ -0,0 +1,55 @@
+--
+-- Copyright 2024 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
+--
+-- https://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.
+
+CREATE PERFETTO TABLE _cpu_sizes AS
+SELECT 0 AS n, 'little' AS size
+UNION
+SELECT 1 AS n, 'mid' AS size
+UNION
+SELECT 2 AS n, 'big' AS size;
+
+CREATE PERFETTO TABLE _ranked_cpus AS
+SELECT
+ (DENSE_RANK() OVER win) - 1 AS n,
+ cpu
+FROM (
+ SELECT
+ track.cpu AS cpu,
+ MAX(counter.value) AS maxfreq
+ FROM counter
+ JOIN cpu_counter_track AS track
+ ON (counter.track_id = track.id)
+ WHERE track.name = "cpufreq"
+ GROUP BY track.cpu
+)
+WINDOW win AS (ORDER BY maxfreq);
+
+-- Guess size of CPU.
+-- On some multicore devices the cores are heterogeneous and divided
+-- into two or more 'sizes'. In a typical case a device might have 8
+-- cores of which 4 are 'little' (low power & low performance) and 4
+-- are 'big' (high power & high performance). This functions attempts
+-- to map a given CPU index onto the relevant descriptor. For
+-- homogeneous systems this returns NULL.
+CREATE PERFETTO FUNCTION cpu_guess_core_type(
+ -- Index of the CPU whose size we will guess.
+ cpu_index INT)
+-- A descriptive size ('little', 'mid', 'big', etc) or NULL if we have insufficient information.
+RETURNS STRING AS
+SELECT
+ IIF((SELECT COUNT(DISTINCT n) FROM _ranked_cpus) >= 2, size, null) as size
+FROM _ranked_cpus
+LEFT JOIN _cpu_sizes USING(n)
+WHERE cpu = $cpu_index;
\ No newline at end of file
diff --git a/src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/cpus.sql b/src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/cpus.sql
index d897503..0870603 100644
--- a/src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/cpus.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/cpus.sql
@@ -1,5 +1,5 @@
--
--- Copyright 2023 The Android Open Source Project
+-- Copyright 2024 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.
@@ -13,57 +13,14 @@
-- See the License for the specific language governing permissions and
-- limitations under the License.
+INCLUDE PERFETTO MODULE cpu.size;
+INCLUDE PERFETTO MODULE cpu.cpus;
-CREATE PERFETTO TABLE _cpu_sizes AS
-SELECT 0 AS n, 'little' AS size
-UNION
-SELECT 1 AS n, 'mid' AS size
-UNION
-SELECT 2 AS n, 'big' AS size;
+CREATE PERFETTO TABLE cpus(cpu_index INT, size STRING)
+AS
+SELECT * FROM cpu_core_types;
-CREATE PERFETTO TABLE _ranked_cpus AS
-SELECT
- (DENSE_RANK() OVER win) - 1 AS n,
- cpu
-FROM (
- SELECT
- track.cpu AS cpu,
- MAX(counter.value) AS maxfreq
- FROM counter
- JOIN cpu_counter_track AS track
- ON (counter.track_id = track.id)
- WHERE track.name = "cpufreq"
- GROUP BY track.cpu
-)
-WINDOW win AS (ORDER BY maxfreq);
--- Guess size of CPU.
--- On some multicore devices the cores are heterogeneous and divided
--- into two or more 'sizes'. In a typical case a device might have 8
--- cores of which 4 are 'little' (low power & low performance) and 4
--- are 'big' (high power & high performance). This functions attempts
--- to map a given CPU index onto the relevant descriptor. For
--- homogeneous systems this returns NULL.
-CREATE PERFETTO FUNCTION guess_cpu_size(
- -- Index of the CPU whose size we will guess.
- cpu_index INT)
--- A descriptive size ('little', 'mid', 'big', etc) or NULL if we have insufficient information.
+CREATE PERFETTO FUNCTION guess_cpu_size(cpu_index INT)
RETURNS STRING AS
-SELECT
- IIF((SELECT COUNT(DISTINCT n) FROM _ranked_cpus) >= 2, size, null) as size
-FROM _ranked_cpus
-LEFT JOIN _cpu_sizes USING(n)
-WHERE cpu = $cpu_index;
-
-
--- A list of CPUs with their sizes.
-CREATE PERFETTO TABLE cpus(
- -- Index of the CPU.
- cpu_index INT,
- -- A descriptive size ('little', 'mid', 'big', etc) or NULL if we have insufficient information.
- size STRING
-) AS
-SELECT
- cpu as cpu_index,
- guess_cpu_size(cpu) AS size
-FROM _ranked_cpus;
\ No newline at end of file
+SELECT cpu_guess_core_type($cpu_index);
\ No newline at end of file
diff --git a/src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/percentiles.sql b/src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/percentiles.sql
index 78e1ed1..e807a78 100644
--- a/src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/percentiles.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/percentiles.sql
@@ -24,6 +24,57 @@
WHERE num < $upper_limit)
SELECT num FROM nums;
+CREATE PERFETTO FUNCTION _earliest_timestamp_for_counter_track(
+ -- Id of a counter track with a counter.
+ counter_track_id INT)
+-- Timestamp of first counter value. Null if doesn't exist.
+RETURNS LONG AS
+SELECT MIN(ts) FROM counter WHERE counter.track_id = $counter_track_id;
+
+-- COUNTER_WITH_DUR_FOR_TRACK but in a specified time.
+-- Does calculation over the table ends - creates an artificial counter value at
+-- the start if needed and chops the duration of the last timestamps in range.
+CREATE PERFETTO FUNCTION _counter_for_time_range(
+ -- Id of track counter track.
+ counter_track_id INT,
+ -- Timestamp of the timerange start.
+ -- Can be earlier than the first counter value.
+ start_ts LONG,
+ -- Timestamp of the timerange end.
+ end_ts LONG)
+RETURNS TABLE(
+ -- Timestamp of the counter value.
+ ts LONG,
+ -- Duration of the counter value.
+ dur LONG,
+ -- Counter value.
+ value DOUBLE,
+ -- If of the counter track.
+ track_id INT,
+ -- Name of the counter track.
+ track_name STRING,
+ -- Counter track set id.
+ track_arg_set_id INT,
+ -- Counter arg set id.
+ arg_set_id INT
+) AS
+SELECT
+ IIF(ts < $start_ts, $start_ts, ts) AS ts,
+ IIF(
+ ts < $start_ts,
+ dur - ($start_ts - ts),
+ IIF(ts + dur > $end_ts, $end_ts - ts, dur)) AS dur,
+ value,
+ track_id,
+ track_name,
+ track_arg_set_id,
+ arg_set_id
+FROM counter_with_dur_for_track($counter_track_id)
+WHERE TRUE
+ AND ts + dur >= $start_ts
+ AND ts < $end_ts
+ORDER BY ts ASC;
+
--
-- Get durations for percentile
--
@@ -55,9 +106,9 @@
SELECT
value,
(CAST(SUM(dur) OVER(ORDER BY value ASC) AS DOUBLE) /
- ($end_ts - MAX($start_ts, earliest_timestamp_for_counter_track($counter_track_id)))) * 100
+ ($end_ts - MAX($start_ts, _earliest_timestamp_for_counter_track($counter_track_id)))) * 100
AS percentile_for_value
- FROM COUNTER_FOR_TIME_RANGE($counter_track_id, $start_ts, $end_ts)
+ FROM _COUNTER_FOR_TIME_RANGE($counter_track_id, $start_ts, $end_ts)
ORDER BY value ASC
),
with_gaps AS (
diff --git a/src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/thread_states.sql b/src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/thread_states.sql
index a0c63e9..952fb1d 100644
--- a/src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/thread_states.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/deprecated/v42/common/thread_states.sql
@@ -14,33 +14,13 @@
-- limitations under the License.
INCLUDE PERFETTO MODULE deprecated.v42.common.timestamps;
-INCLUDE PERFETTO MODULE deprecated.v42.common.cpus;
+INCLUDE PERFETTO MODULE sched.states;
+INCLUDE PERFETTO MODULE cpu.size;
--- TODO(altimin): this doesn't handle some corner cases which thread_state.ts
--- handles (as complex strings manipulations in SQL are pretty painful),
--- but they are pretty niche.
--- Translates the thread state name from a single-letter shorthard to
--- a human-readable name.
CREATE PERFETTO FUNCTION _translate_thread_state_name(name STRING)
RETURNS STRING AS
-SELECT CASE $name
-WHEN 'Running' THEN 'Running'
-WHEN 'R' THEN 'Runnable'
-WHEN 'R+' THEN 'Runnable (Preempted)'
-WHEN 'S' THEN 'Sleeping'
-WHEN 'D' THEN 'Uninterruptible Sleep'
-WHEN 'T' THEN 'Stopped'
-WHEN 't' THEN 'Traced'
-WHEN 'X' THEN 'Exit (Dead)'
-WHEN 'Z' THEN 'Exit (Zombie)'
-WHEN 'x' THEN 'Task Dead'
-WHEN 'I' THEN 'Idle'
-WHEN 'K' THEN 'Wakekill'
-WHEN 'W' THEN 'Waking'
-WHEN 'P' THEN 'Parked'
-WHEN 'N' THEN 'No Load'
-ELSE $name
-END;
+SELECT sched_state_to_human_readable_string($name);
+
-- Returns a human-readable name for a thread state.
CREATE PERFETTO FUNCTION human_readable_thread_state_name(
@@ -107,13 +87,14 @@
SELECT * FROM first_state_starting_before
)
SELECT
- human_readable_thread_state_name(id) as state,
+ full_name.sched_state_full_name as state,
state as raw_state,
- guess_cpu_size(cpu) as cpu_type,
+ cpu_guess_core_type(cpu) as cpu_type,
cpu,
blocked_function,
sum(spans_overlapping_dur($ts, $dur, ts, dur)) as dur
FROM thread_state
+JOIN sched_state_full_name!(thread_state, state, io_wait) full_name USING (id)
JOIN relevant_states USING (id)
GROUP BY state, raw_state, cpu_type, cpu, blocked_function
ORDER BY dur desc;
\ No newline at end of file
diff --git a/src/trace_processor/perfetto_sql/stdlib/sched/BUILD.gn b/src/trace_processor/perfetto_sql/stdlib/sched/BUILD.gn
index 8e83d6f..fa5ba77 100644
--- a/src/trace_processor/perfetto_sql/stdlib/sched/BUILD.gn
+++ b/src/trace_processor/perfetto_sql/stdlib/sched/BUILD.gn
@@ -16,6 +16,7 @@
perfetto_sql_source_set("sched") {
sources = [
+ "states.sql",
"thread_executing_span.sql",
"thread_level_parallelism.sql",
"thread_state_flattened.sql",
diff --git a/src/trace_processor/perfetto_sql/stdlib/sched/states.sql b/src/trace_processor/perfetto_sql/stdlib/sched/states.sql
new file mode 100644
index 0000000..03f3d9c
--- /dev/null
+++ b/src/trace_processor/perfetto_sql/stdlib/sched/states.sql
@@ -0,0 +1,90 @@
+--
+-- Copyright 2024 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
+--
+-- https://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.
+
+-- TODO(altimin): `sched_humanly_readable_name` doesn't handle some corner
+-- cases which thread_state.ts handles (as complex strings manipulations in
+-- SQL are pretty painful), but they are pretty niche.
+
+-- Translates the thread state name from a single-letter shorthard to
+-- a human-readable name.
+CREATE PERFETTO FUNCTION sched_state_to_human_readable_string(
+ -- An individual character string representing the scheduling state of the
+ -- kernel thread at the end of the slice.
+ short_name STRING
+)
+-- Humanly readable string representing the scheduling state of the kernel
+-- thread. The individual characters in the string mean the following: R
+-- (runnable), S (awaiting a wakeup), D (in an uninterruptible sleep), T
+-- (suspended), t (being traced), X (exiting), P (parked), W (waking), I
+-- (idle), N (not contributing to the load average), K (wakeable on fatal
+-- signals) and Z (zombie, awaiting cleanup).
+RETURNS STRING AS
+SELECT CASE $short_name
+WHEN 'Running' THEN 'Running'
+WHEN 'R' THEN 'Runnable'
+WHEN 'R+' THEN 'Runnable (Preempted)'
+WHEN 'S' THEN 'Sleeping'
+WHEN 'D' THEN 'Uninterruptible Sleep'
+WHEN 'T' THEN 'Stopped'
+WHEN 't' THEN 'Traced'
+WHEN 'X' THEN 'Exit (Dead)'
+WHEN 'Z' THEN 'Exit (Zombie)'
+WHEN 'x' THEN 'Task Dead'
+WHEN 'I' THEN 'Idle'
+WHEN 'K' THEN 'Wakekill'
+WHEN 'W' THEN 'Waking'
+WHEN 'P' THEN 'Parked'
+WHEN 'N' THEN 'No Load'
+ELSE $short_name
+END;
+
+-- Creates a table with humanly readable sched state names with IO waits.
+-- Translates the individual characters in the string to the following: R
+-- (runnable), S (awaiting a wakeup), D (in an uninterruptible sleep), T
+-- (suspended), t (being traced), X (exiting), P (parked), W (waking), I
+-- (idle), N (not contributing to the load average), K (wakeable on fatal
+-- signals) and Z (zombie, awaiting cleanup). Adds the IO wait (IO/non
+-- IO/nothing) based on the value in the `io_wait_column`.
+CREATE PERFETTO MACRO sched_state_full_name(
+ -- Table with columns required for translation and `id` column for joins.
+ states_table TableOrSubquery,
+ -- Column in `states_table` with single character version of sched state
+ -- string.
+ sched_name_column ColumnName,
+ -- Column in `states_table` with 0 for IO and 1 for non-IO states. Can be
+ -- a dummy (no real values), and no value from there would be added to the
+ -- resulting strings.
+ io_wait_column ColumnName
+)
+-- Table with the schema (id UINT32, ts UINT64, sched_state_full_name STRING).
+RETURNS TableOrSubquery AS
+(
+ WITH data AS
+ (
+ SELECT
+ id,
+ sched_state_to_human_readable_string($sched_name_column) AS sched_state_name,
+ (CASE $io_wait_column
+ WHEN 1 THEN ' (IO)'
+ WHEN 0 THEN ' (non-IO)'
+ ELSE ''
+ END) AS io_wait
+ FROM $states_table
+ )
+ SELECT
+ id,
+ printf('%s%s', sched_state_name, io_wait) AS sched_state_full_name
+ FROM data
+);
diff --git a/src/trace_processor/perfetto_sql/stdlib/sched/thread_level_parallelism.sql b/src/trace_processor/perfetto_sql/stdlib/sched/thread_level_parallelism.sql
index 0b3a470..19b0508 100644
--- a/src/trace_processor/perfetto_sql/stdlib/sched/thread_level_parallelism.sql
+++ b/src/trace_processor/perfetto_sql/stdlib/sched/thread_level_parallelism.sql
@@ -17,8 +17,8 @@
-- including how many threads were runnable at a given time and how many threads
-- where running at a given point in time.
-INCLUDE PERFETTO MODULE common.cpus;
INCLUDE PERFETTO MODULE intervals.overlap;
+INCLUDE PERFETTO MODULE cpu.cpus;
-- The count of runnable threads over time.
CREATE PERFETTO TABLE sched_runnable_thread_count(
@@ -74,7 +74,7 @@
-- Materialise the relevant cores to avoid calling a function for each row of the sched table.
cores AS MATERIALIZED (
SELECT cpu_index
- FROM cpus
+ FROM cpu_core_types
WHERE size = $core_type
),
-- Filter sched events corresponding to running tasks.
diff --git a/src/traceconv/BUILD.gn b/src/traceconv/BUILD.gn
index 97c7524..8cde4f4 100644
--- a/src/traceconv/BUILD.gn
+++ b/src/traceconv/BUILD.gn
@@ -108,6 +108,8 @@
"trace_to_text.cc",
"trace_to_text.h",
"trace_to_text.h",
+ "trace_unpack.cc",
+ "trace_unpack.h",
]
}
diff --git a/src/traceconv/main.cc b/src/traceconv/main.cc
index 1570281..d7e6ac4 100644
--- a/src/traceconv/main.cc
+++ b/src/traceconv/main.cc
@@ -31,6 +31,7 @@
#include "src/traceconv/trace_to_profile.h"
#include "src/traceconv/trace_to_systrace.h"
#include "src/traceconv/trace_to_text.h"
+#include "src/traceconv/trace_unpack.h"
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <fcntl.h>
@@ -47,7 +48,8 @@
fprintf(stderr,
"Usage: %s MODE [OPTIONS] [input file] [output file]\n"
"modes:\n"
- " systrace|json|ctrace|text|profile|hprof|symbolize|deobfuscate\n"
+ " systrace|json|ctrace|text|profile|hprof|symbolize|deobfuscate"
+ "|decompress_packets\n"
"options:\n"
" [--truncate start|end]\n"
" [--full-sort]\n"
@@ -186,13 +188,15 @@
if (truncate_keep != Keep::kAll) {
PERFETTO_ELOG(
- "--truncate is unsupported for text|profile|symbolize format.");
+ "--truncate is unsupported for "
+ "text|profile|symbolize|decompress_packets format.");
return 1;
}
if (full_sort) {
PERFETTO_ELOG(
- "--full-sort is unsupported for text|profile|symbolize format.");
+ "--full-sort is unsupported for "
+ "text|profile|symbolize|decompress_packets format.");
return 1;
}
@@ -216,6 +220,10 @@
if (format == "deobfuscate")
return DeobfuscateProfile(input_stream, output_stream);
+
+ if (format == "decompress_packets")
+ return UnpackCompressedPackets(input_stream, output_stream);
+
return Usage(argv[0]);
}
diff --git a/src/traceconv/trace_unpack.cc b/src/traceconv/trace_unpack.cc
new file mode 100644
index 0000000..060a7b2
--- /dev/null
+++ b/src/traceconv/trace_unpack.cc
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "src/traceconv/trace_unpack.h"
+
+#include <iostream>
+#include <iterator>
+#include <memory>
+#include <vector>
+
+#include "perfetto/trace_processor/read_trace.h"
+#include "src/traceconv/utils.h"
+
+namespace perfetto {
+namespace trace_to_text {
+
+// Naive: puts multiple copies of the trace in memory, but good enough for
+// manual workflows.
+bool UnpackCompressedPackets(std::istream* input, std::ostream* output) {
+ std::vector<char> packed(std::istreambuf_iterator<char>{*input},
+ std::istreambuf_iterator<char>{});
+ std::vector<uint8_t> unpacked;
+ auto status = trace_processor::DecompressTrace(
+ reinterpret_cast<uint8_t*>(packed.data()), packed.size(), &unpacked);
+ if (!status.ok())
+ return false;
+
+ TraceWriter trace_writer(output);
+ trace_writer.Write(reinterpret_cast<char*>(unpacked.data()), unpacked.size());
+ return true;
+}
+
+} // namespace trace_to_text
+} // namespace perfetto
diff --git a/src/traceconv/trace_unpack.h b/src/traceconv/trace_unpack.h
new file mode 100644
index 0000000..00e2537
--- /dev/null
+++ b/src/traceconv/trace_unpack.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2024 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_TRACECONV_TRACE_UNPACK_H_
+#define SRC_TRACECONV_TRACE_UNPACK_H_
+
+#include <iostream>
+
+namespace perfetto {
+namespace trace_to_text {
+
+// Serialised trace with compressed_packets -> serialised trace with those
+// packets in their decompressed form. Mostly for use with protoprofile.
+bool UnpackCompressedPackets(std::istream* input, std::ostream* output);
+
+} // namespace trace_to_text
+} // namespace perfetto
+
+#endif // SRC_TRACECONV_TRACE_UNPACK_H_
diff --git a/src/traced/probes/ftrace/cpu_reader.cc b/src/traced/probes/ftrace/cpu_reader.cc
index 30b58cf..2f1f121 100644
--- a/src/traced/probes/ftrace/cpu_reader.cc
+++ b/src/traced/probes/ftrace/cpu_reader.cc
@@ -596,7 +596,7 @@
}
// Data record:
default: {
- // If type_or_length <=28, the the record length is 4x that value.
+ // If type_or_length <=28, the record length is 4x that value.
// If type_or_length == 0, the length of the record is stored in the
// first uint32_t word of the payload.
uint32_t event_size = 0;
diff --git a/src/tracing/test/api_integrationtest.cc b/src/tracing/test/api_integrationtest.cc
index fefab5b..ba0d010 100644
--- a/src/tracing/test/api_integrationtest.cc
+++ b/src/tracing/test/api_integrationtest.cc
@@ -16,9 +16,6 @@
#include <fcntl.h>
-#include <sys/socket.h>
-#include <sys/types.h>
-#include <sys/un.h>
#include <chrono>
#include <condition_variable>
#include <fstream>
@@ -39,6 +36,10 @@
#if PERFETTO_BUILDFLAG(PERFETTO_OS_WIN)
#include <Windows.h> // For CreateFile().
+#else
+#include <sys/socket.h>
+#include <sys/types.h>
+#include <sys/un.h>
#endif
// Deliberately not pulling any non-public perfetto header to spot accidental
diff --git a/test/cmdline_integrationtest.cc b/test/cmdline_integrationtest.cc
index f8c7a43..74d405b 100644
--- a/test/cmdline_integrationtest.cc
+++ b/test/cmdline_integrationtest.cc
@@ -90,19 +90,6 @@
class PerfettoCmdlineTest : public ::testing::Test {
public:
- void SetUp() override {
-#if defined(ADDRESS_SANITIZER) || defined(THREAD_SANITIZER) || \
- defined(MEMORY_SANITIZER) || defined(LEAK_SANITIZER)
- // Disable cmdline tests on sanitizets because they use fork() and that
- // messes up leak / races detections, which has been fixed only recently
- // (see https://github.com/google/sanitizers/issues/836 ).
- PERFETTO_LOG("Skipping cmdline integration tests on sanitizers");
- GTEST_SKIP();
-#endif
- }
-
- void TearDown() override {}
-
void StartServiceIfRequiredNoNewExecsAfterThis() {
exec_allowed_ = false;
test_helper_.StartServiceIfRequired();
diff --git a/test/cts/test_apps/src/android/perfetto/cts/app/JavaOomActivity.java b/test/cts/test_apps/src/android/perfetto/cts/app/JavaOomActivity.java
index 35808b9..8dc7bd1 100644
--- a/test/cts/test_apps/src/android/perfetto/cts/app/JavaOomActivity.java
+++ b/test/cts/test_apps/src/android/perfetto/cts/app/JavaOomActivity.java
@@ -18,22 +18,23 @@
import android.app.Activity;
import android.os.Bundle;
+import android.util.Log;
public class JavaOomActivity extends Activity {
+ public static final String TAG = "JavaOomActivity";
+
@Override
public void onCreate(Bundle state) {
super.onCreate(state);
new Thread(() -> {
try {
+ Log.i(TAG, "Before the allocation");
+ // Try to allocate a big array: it should cause ART to run out of memory.
byte[] alloc = new byte[Integer.MAX_VALUE];
- // The return statement below is required to keep the allocation
- // above when generating DEX. Without the return statement there is
- // no way for a debugger to break where `alloc` is in scope and
- // therefore javac will not generate local variable information for it.
- // Without local variable information dexers (both D8 and R8) will
- // remove the dead allocation as without local variable information it
- // is dead even in debug mode. See b/322478366#comment3.
- return;
+ // Use the array, otherwise R8 might optimize the allocation away. (b/322478366,
+ // b/325467497).
+ alloc[5] = 42;
+ Log.i(TAG, "After the allocation " + alloc[5]);
} catch (OutOfMemoryError e) {
}
}).start();
diff --git a/test/test_helper.h b/test/test_helper.h
index b43ae0a..462861d 100644
--- a/test/test_helper.h
+++ b/test/test_helper.h
@@ -468,6 +468,7 @@
pass_env("TMPDIR", &subprocess_);
pass_env("TMP", &subprocess_);
pass_env("TEMP", &subprocess_);
+ pass_env("LD_LIBRARY_PATH", &subprocess_);
cmd.push_back(base::GetCurExecutableDir() + "/" + argv0);
cmd.insert(cmd.end(), args.begin(), args.end());
}
diff --git a/test/trace_processor/diff_tests/stdlib/common/tests.py b/test/trace_processor/diff_tests/stdlib/common/tests.py
index 8e85918..453fd08 100644
--- a/test/trace_processor/diff_tests/stdlib/common/tests.py
+++ b/test/trace_processor/diff_tests/stdlib/common/tests.py
@@ -25,7 +25,7 @@
return DiffTestBlueprint(
trace=Path('../../common/synth_1.py'),
query="""
- INCLUDE PERFETTO MODULE common.thread_states;
+ INCLUDE PERFETTO MODULE deprecated.v42.common.thread_states;
SELECT
state,
diff --git a/tools/check_sql_metrics.py b/tools/check_sql_metrics.py
index 73f0d70..3819c27 100755
--- a/tools/check_sql_metrics.py
+++ b/tools/check_sql_metrics.py
@@ -72,6 +72,24 @@
with open(path) as f:
sql = f.read()
+ # Check that each function/macro is using "CREATE OR REPLACE"
+ lines = [l.strip() for l in sql.split('\n')]
+ for line in lines:
+ if line.startswith('--'):
+ continue
+ if 'create perfetto function' in line.casefold():
+ errors.append(
+ f'Use "CREATE OR REPLACE PERFETTO FUNCTION" in Perfetto metrics, '
+ f'to prevent the file from crashing if the metric is rerun.\n'
+ f'Offending file: {path}\n')
+ if 'create perfetto macro' in line.casefold():
+ errors.append(
+ f'Use "CREATE OR REPLACE PERFETTO MACRO" in Perfetto metrics, to '
+ f'prevent the file from crashing if the metric is rerun.\n'
+ f'Offending file: {path}\n')
+
+
+
# Check that CREATE VIEW/TABLE has a matching DROP VIEW/TABLE before it.
create_table_view_dir = match_create_table_pattern_to_dict(
sql, CREATE_TABLE_VIEW_PATTERN)
diff --git a/tools/check_sql_modules.py b/tools/check_sql_modules.py
index b4ffc1f..c09261b 100755
--- a/tools/check_sql_modules.py
+++ b/tools/check_sql_modules.py
@@ -111,6 +111,10 @@
if 'RUN_METRIC' in line:
errors.append(f"RUN_METRIC is banned in standard library.\n"
f"Offending file: {path}\n")
+ if 'include perfetto module common.' in line.casefold():
+ errors.append(
+ f"Common module has been deprecated in the standard library.\n"
+ f"Offending file: {path}\n")
if 'insert into' in line.casefold():
errors.append(f"INSERT INTO table is not allowed in standard library.\n"
f"Offending file: {path}\n")
diff --git a/tools/gen_cc_proto_descriptor.py b/tools/gen_cc_proto_descriptor.py
index 45354b1..0c2dc66 100755
--- a/tools/gen_cc_proto_descriptor.py
+++ b/tools/gen_cc_proto_descriptor.py
@@ -68,7 +68,7 @@
namespace perfetto {{
-constexpr inline std::array<uint8_t, {size}> k{proto_name}Descriptor{{
+constexpr std::array<uint8_t, {size}> k{proto_name}Descriptor{{
{binary}}};
}} // namespace perfetto
diff --git a/ui/.eslintrc.js b/ui/.eslintrc.js
index c5120f4..3036628 100644
--- a/ui/.eslintrc.js
+++ b/ui/.eslintrc.js
@@ -28,7 +28,7 @@
}],
// Max line length is 80 with 2 space tabs.
- // This matches the the old clang-format definition for consistency.
+ // This matches the old clang-format definition for consistency.
'max-len': [
'error',
{
diff --git a/ui/src/common/commands.ts b/ui/src/common/commands.ts
index 2f19198..7b44775 100644
--- a/ui/src/common/commands.ts
+++ b/ui/src/common/commands.ts
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {Disposable} from '../base/disposable';
import {FuzzyFinder, FuzzySegment} from '../base/fuzzy';
import {Command} from '../public';
import {Registry} from './registry';
@@ -21,12 +22,16 @@
}
export class CommandManager {
- readonly registry = new Registry<Command>((cmd) => cmd.id);
+ private readonly registry = new Registry<Command>((cmd) => cmd.id);
get commands(): Command[] {
return Array.from(this.registry.values());
}
+ registerCommand(cmd: Command): Disposable {
+ return this.registry.register(cmd);
+ }
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
runCommand(id: string, ...args: any[]): any {
const cmd = this.registry.get(id);
diff --git a/ui/src/common/event_set.ts b/ui/src/common/event_set.ts
index 47e4e1b..e815eb7 100644
--- a/ui/src/common/event_set.ts
+++ b/ui/src/common/event_set.ts
@@ -479,7 +479,7 @@
constructor(keys: P, events: Event<P>[]) {
super();
// TODO(hjd): Add some paranoid mode where we crash here if
- // `events` and `keys` missmatch?
+ // `events` and `keys` mismatch?
this.events = events;
this.keys = keys;
}
diff --git a/ui/src/common/plugins.ts b/ui/src/common/plugins.ts
index fc996a2..bd7d5ef 100644
--- a/ui/src/common/plugins.ts
+++ b/ui/src/common/plugins.ts
@@ -75,7 +75,7 @@
// Silently ignore if context is dead.
if (!this.alive) return;
- const disposable = globals.commandManager.registry.register(cmd);
+ const disposable = globals.commandManager.registerCommand(cmd);
this.trash.add(disposable);
};
@@ -108,22 +108,24 @@
// Silently ignore if context is dead.
if (!this.alive) return;
- const disposable = globals.commandManager.registry.register(cmd);
- this.trash.add(disposable);
+ const dispose = globals.commandManager.registerCommand(cmd);
+ this.trash.add(dispose);
}
registerTrack(trackDesc: TrackDescriptor): void {
// Silently ignore if context is dead.
if (!this.alive) return;
- globals.trackManager.registerTrack(trackDesc);
- this.trash.addCallback(
- () => globals.trackManager.unregisterTrack(trackDesc.uri));
+
+ const dispose = globals.trackManager.registerTrack(trackDesc);
+ this.trash.add(dispose);
}
addDefaultTrack(track: TrackRef): void {
- globals.trackManager.addDefaultTrack(track);
- this.trash.addCallback(
- () => globals.trackManager.removeDefaultTrack(track));
+ // Silently ignore if context is dead.
+ if (!this.alive) return;
+
+ const dispose = globals.trackManager.addPotentialTrack(track);
+ this.trash.add(dispose);
}
registerStaticTrack(track: TrackDescriptor&TrackRef): void {
diff --git a/ui/src/common/timestamp_format.ts b/ui/src/common/timestamp_format.ts
index 45f38ff..83c3107 100644
--- a/ui/src/common/timestamp_format.ts
+++ b/ui/src/common/timestamp_format.ts
@@ -29,13 +29,17 @@
const DEFAULT_TIMESTAMP_FORMAT = TimestampFormat.Timecode;
export function timestampFormat(): TimestampFormat {
- const storedFormat = localStorage.getItem(TIMESTAMP_FORMAT_KEY);
- if (storedFormat && isEnumValue(TimestampFormat, storedFormat)) {
- timestampFormatCached = storedFormat;
+ if (timestampFormatCached !== undefined) {
+ return timestampFormatCached;
} else {
- timestampFormatCached = DEFAULT_TIMESTAMP_FORMAT;
+ const storedFormat = localStorage.getItem(TIMESTAMP_FORMAT_KEY);
+ if (storedFormat && isEnumValue(TimestampFormat, storedFormat)) {
+ timestampFormatCached = storedFormat;
+ } else {
+ timestampFormatCached = DEFAULT_TIMESTAMP_FORMAT;
+ }
+ return timestampFormatCached;
}
- return timestampFormatCached;
}
export function setTimestampFormat(format: TimestampFormat) {
@@ -54,13 +58,17 @@
const DEFAULT_DURATION_FORMAT = DurationPrecision.Full;
export function durationPrecision(): DurationPrecision {
- const storedFormat = localStorage.getItem(DURATION_FORMAT_KEY);
- if (storedFormat && isEnumValue(DurationPrecision, storedFormat)) {
- durationFormatCached = storedFormat;
+ if (durationFormatCached !== undefined) {
+ return durationFormatCached;
} else {
- durationFormatCached = DEFAULT_DURATION_FORMAT;
+ const storedFormat = localStorage.getItem(DURATION_FORMAT_KEY);
+ if (storedFormat && isEnumValue(DurationPrecision, storedFormat)) {
+ durationFormatCached = storedFormat;
+ } else {
+ durationFormatCached = DEFAULT_DURATION_FORMAT;
+ }
+ return durationFormatCached;
}
- return durationFormatCached;
}
export function setDurationPrecision(format: DurationPrecision) {
diff --git a/ui/src/common/track_cache.ts b/ui/src/common/track_cache.ts
index 43b1e70..90c004e 100644
--- a/ui/src/common/track_cache.ts
+++ b/ui/src/common/track_cache.ts
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+import {Disposable, DisposableCallback} from '../base/disposable';
import {PanelSize} from '../frontend/panel';
import {Store} from '../frontend/store';
import {
@@ -21,6 +22,7 @@
TrackDescriptor,
TrackRef,
} from '../public';
+import {Registry} from './registry';
import {State} from './state';
@@ -55,44 +57,39 @@
// Third cycle
// flushTracks() <-- 'foo' is destroyed.
export class TrackManager {
+ private readonly registry = new Registry<TrackDescriptor>(({uri}) => uri);
+ private readonly potentialTracks = new Set<TrackRef>();
private safeCache = new Map<string, TrackCacheEntry>();
private recycleBin = new Map<string, TrackCacheEntry>();
- private trackRegistry = new Map<string, TrackDescriptor>();
- private defaultTracks = new Set<TrackRef>();
private store: Store<State>;
constructor(store: Store<State>) {
this.store = store;
}
- registerTrack(trackDesc: TrackDescriptor): void {
- this.trackRegistry.set(trackDesc.uri, trackDesc);
+ registerTrack(trackDesc: TrackDescriptor): Disposable {
+ return this.registry.register(trackDesc);
}
- unregisterTrack(uri: string): void {
- this.trackRegistry.delete(uri);
- }
-
- addDefaultTrack(track: TrackRef): void {
- this.defaultTracks.add(track);
- }
-
- removeDefaultTrack(track: TrackRef): void {
- this.defaultTracks.delete(track);
+ addPotentialTrack(track: TrackRef): Disposable {
+ this.potentialTracks.add(track);
+ return new DisposableCallback(() => {
+ this.potentialTracks.delete(track);
+ });
}
findPotentialTracks(): TrackRef[] {
- return Array.from(this.defaultTracks);
+ return Array.from(this.potentialTracks);
}
getAllTracks(): TrackDescriptor[] {
- return Array.from(this.trackRegistry.values());
+ return Array.from(this.registry.values());
}
// Look up track into for a given track's URI.
// Returns |undefined| if no track can be found.
resolveTrackInfo(uri: string): TrackDescriptor|undefined {
- return this.trackRegistry.get(uri);
+ return this.registry.get(uri);
}
// Creates a new track using |uri| and |params| or retrieves a cached track if
diff --git a/ui/src/controller/track_decider.ts b/ui/src/controller/track_decider.ts
index c3f0cbe..2c5388d 100644
--- a/ui/src/controller/track_decider.ts
+++ b/ui/src/controller/track_decider.ts
@@ -108,10 +108,10 @@
async guessCpuSizes(): Promise<Map<number, string>> {
const cpuToSize = new Map<number, string>();
await this.engine.query(`
- INCLUDE PERFETTO MODULE common.cpus;
+ INCLUDE PERFETTO MODULE cpu.size;
`);
const result = await this.engine.query(`
- SELECT cpu, GUESS_CPU_SIZE(cpu) as size FROM cpu_counter_track;
+ SELECT cpu, cpu_guess_core_type(cpu) as size FROM cpu_counter_track;
`);
const it = result.iter({
@@ -371,7 +371,7 @@
for (const track of ionTracks) {
if (!foundSummary &&
- [MEM_DMA_COUNTER_NAME, MEM_ION].includes(track.name)) {
+ [MEM_DMA_COUNTER_NAME, MEM_ION].includes(track.name)) {
foundSummary = true;
track.key = summaryTrackKey;
track.trackGroup = undefined;
@@ -491,9 +491,9 @@
// Group all the frequency tracks together (except the CPU and GPU
// frequency ones).
if (track.name.endsWith('Frequency') && !track.name.startsWith('Cpu') &&
- !track.name.startsWith('Gpu')) {
+ !track.name.startsWith('Gpu')) {
if (track.trackGroup !== undefined &&
- track.trackGroup !== SCROLLING_TRACK_GROUP) {
+ track.trackGroup !== SCROLLING_TRACK_GROUP) {
continue;
}
if (track.uri === NULL_TRACK_URI) {
@@ -539,7 +539,7 @@
let groupUuid = undefined;
for (const track of this.tracksToAdd) {
if (track.trackGroup !== undefined &&
- track.trackGroup !== SCROLLING_TRACK_GROUP) {
+ track.trackGroup !== SCROLLING_TRACK_GROUP) {
continue;
}
if (track.uri === NULL_TRACK_URI) {
@@ -584,7 +584,7 @@
for (const track of this.tracksToAdd) {
if (regex.test(track.name)) {
if (track.trackGroup !== undefined &&
- track.trackGroup !== SCROLLING_TRACK_GROUP) {
+ track.trackGroup !== SCROLLING_TRACK_GROUP) {
continue;
}
if (track.uri === NULL_TRACK_URI) {
@@ -619,7 +619,7 @@
async addLogsTrack(engine: EngineProxy): Promise<void> {
const result =
- await engine.query(`select count(1) as cnt from android_logs`);
+ await engine.query(`select count(1) as cnt from android_logs`);
const count = result.firstRow({cnt: NUM}).cnt;
if (count > 0) {
@@ -702,7 +702,7 @@
let summaryTrackKey = undefined;
let trackGroupId =
- upid === 0 ? SCROLLING_TRACK_GROUP : this.upidToUuid.get(upid);
+ upid === 0 ? SCROLLING_TRACK_GROUP : this.upidToUuid.get(upid);
if (groupName) {
// If this is the first track encountered for a certain group,
@@ -801,7 +801,7 @@
const priority = InThreadTrackSortKey.THREAD_SCHEDULING_STATE_TRACK;
const name =
- getTrackName({utid, tid, threadName, kind: THREAD_STATE_TRACK_KIND});
+ getTrackName({utid, tid, threadName, kind: THREAD_STATE_TRACK_KIND});
this.tracksToAdd.push({
uri: `perfetto.ThreadState#${utid}`,
@@ -1014,7 +1014,7 @@
const rawName = it.name;
const uid = it.uid === null ? undefined : it.uid;
const userName =
- it.package_name === null ? `UID: ${uid}` : it.package_name;
+ it.package_name === null ? `UID: ${uid}` : it.package_name;
const groupUuid = `uid-track-group${rawName}`;
if (groupMap.get(rawName) === undefined) {
@@ -1095,7 +1095,7 @@
const kind = ACTUAL_FRAMES_SLICE_TRACK_KIND;
const name =
- getTrackName({name: trackName, upid, pid, processName, kind});
+ getTrackName({name: trackName, upid, pid, processName, kind});
this.tracksToAdd.push({
uri: `perfetto.ActualFrames#${upid}`,
@@ -1153,7 +1153,7 @@
const kind = EXPECTED_FRAMES_SLICE_TRACK_KIND;
const name =
- getTrackName({name: trackName, upid, pid, processName, kind});
+ getTrackName({name: trackName, upid, pid, processName, kind});
this.tracksToAdd.push({
uri: `perfetto.ExpectedFrames#${upid}`,
@@ -1295,16 +1295,16 @@
}
}
- getUuidUnchecked(utid: number, upid: number|null) {
+ getUuidUnchecked(utid: number, upid: number | null) {
return upid === null ? this.utidToUuid.get(utid) :
this.upidToUuid.get(upid);
}
- getUuid(utid: number, upid: number|null) {
+ getUuid(utid: number, upid: number | null) {
return assertExists(this.getUuidUnchecked(utid, upid));
}
- getOrCreateUuid(utid: number, upid: number|null) {
+ getOrCreateUuid(utid: number, upid: number | null) {
let uuid = this.getUuidUnchecked(utid, upid);
if (uuid === undefined) {
uuid = uuidv4();
@@ -1531,7 +1531,7 @@
// Group by upid if present else by utid.
let pUuid =
- upid === null ? this.utidToUuid.get(utid) : this.upidToUuid.get(upid);
+ upid === null ? this.utidToUuid.get(utid) : this.upidToUuid.get(upid);
// These should only happen once for each track group.
if (pUuid === undefined) {
pUuid = this.getOrCreateUuid(utid, upid);
@@ -1550,7 +1550,7 @@
});
const name =
- getTrackName({utid, processName, pid, threadName, tid, upid});
+ getTrackName({utid, processName, pid, threadName, tid, upid});
const addTrackGroup = Actions.addTrackGroup({
summaryTrackKey,
name,
@@ -1793,8 +1793,8 @@
}
private static getThreadSortKey(
- threadName?: string|null, tid?: number|null,
- pid?: number|null): PrimaryTrackSortKey {
+ threadName?: string | null, tid?: number | null,
+ pid?: number | null): PrimaryTrackSortKey {
if (pid !== undefined && pid !== null && pid === tid) {
return PrimaryTrackSortKey.MAIN_THREAD;
}
@@ -1804,13 +1804,13 @@
// Chrome main threads should always come first within their process.
if (threadName === 'CrBrowserMain' || threadName === 'CrRendererMain' ||
- threadName === 'CrGpuMain') {
+ threadName === 'CrGpuMain') {
return PrimaryTrackSortKey.MAIN_THREAD;
}
// Chrome IO threads should always come immediately after the main thread.
if (threadName === 'Chrome_ChildIOThread' ||
- threadName === 'Chrome_IOThread') {
+ threadName === 'Chrome_IOThread') {
return PrimaryTrackSortKey.CHROME_IO_THREAD;
}
diff --git a/ui/src/frontend/track_cache.ts b/ui/src/core/timeline_cache.ts
similarity index 98%
rename from ui/src/frontend/track_cache.ts
rename to ui/src/core/timeline_cache.ts
index 09ddf41..d8cede9 100644
--- a/ui/src/frontend/track_cache.ts
+++ b/ui/src/core/timeline_cache.ts
@@ -127,10 +127,10 @@
}
-// LRU cache for the tracks.
+// LRU cache for the timeline.
// T is all the data needed for a displaying the track in a given
// CacheKey area - generally an array of slices.
-export class TrackCache<T> {
+export class TimelineCache<T> {
private cacheSize: number;
private cache: Map<string, CacheItem<T>>;
private lastAccessId: number;
diff --git a/ui/src/frontend/track_cache_unittest.ts b/ui/src/core/timeline_cache_unittest.ts
similarity index 95%
rename from ui/src/frontend/track_cache_unittest.ts
rename to ui/src/core/timeline_cache_unittest.ts
index 2be853b..f1d24e8 100644
--- a/ui/src/frontend/track_cache_unittest.ts
+++ b/ui/src/core/timeline_cache_unittest.ts
@@ -14,7 +14,7 @@
import {Time} from '../base/time';
-import {CacheKey, TrackCache} from './track_cache';
+import {CacheKey, TimelineCache} from './timeline_cache';
test('cacheKeys', () => {
const k = CacheKey.create(Time.fromRaw(201n), Time.fromRaw(302n), 123);
@@ -45,7 +45,7 @@
.normalize();
const key7 = (CacheKey.create(Time.fromRaw(7000n), Time.fromRaw(7100n), 100))
.normalize();
- const cache = new TrackCache<string>(5);
+ const cache = new TimelineCache<string>(5);
cache.insert(key1, 'v1');
expect(cache.lookup(key1)).toEqual('v1');
diff --git a/ui/src/frontend/aggregation_tab.ts b/ui/src/frontend/aggregation_tab.ts
index 603599d..0288b91 100644
--- a/ui/src/frontend/aggregation_tab.ts
+++ b/ui/src/frontend/aggregation_tab.ts
@@ -178,7 +178,7 @@
});
this.trash.add(unregister);
- const unregisterCmd = globals.commandManager.registry.register({
+ const unregisterCmd = globals.commandManager.registerCommand({
id: uri,
name: `Show ${title} Aggregation Tab`,
callback: () => {
diff --git a/ui/src/frontend/app.ts b/ui/src/frontend/app.ts
index 0819338..d48eab6 100644
--- a/ui/src/frontend/app.ts
+++ b/ui/src/frontend/app.ts
@@ -839,7 +839,7 @@
// Register each command with the command manager
this.cmds.forEach((cmd) => {
- const dispose = globals.commandManager.registry.register(cmd);
+ const dispose = globals.commandManager.registerCommand(cmd);
this.trash.add(dispose);
});
}
diff --git a/ui/src/frontend/base_counter_track.ts b/ui/src/frontend/base_counter_track.ts
index a0025c6..dbc9456 100644
--- a/ui/src/frontend/base_counter_track.ts
+++ b/ui/src/frontend/base_counter_track.ts
@@ -32,7 +32,7 @@
import {PanelSize} from './panel';
import {constraintsToQuerySuffix} from './sql_utils';
import {NewTrackArgs} from './track';
-import {CacheKey, TrackCache} from './track_cache';
+import {CacheKey, TimelineCache} from '../core/timeline_cache';
interface CounterData {
timestamps: BigInt64Array;
@@ -85,7 +85,7 @@
minimumRate: 0,
};
- private cache: TrackCache<CounterData> = new TrackCache(5);
+ private cache: TimelineCache<CounterData> = new TimelineCache(5);
private sqlState: 'UNINITIALIZED'|'INITIALIZING'|'QUERY_PENDING'|
'QUERY_DONE' = 'UNINITIALIZED';
diff --git a/ui/src/frontend/base_slice_track.ts b/ui/src/frontend/base_slice_track.ts
index 83f678d..5974811 100644
--- a/ui/src/frontend/base_slice_track.ts
+++ b/ui/src/frontend/base_slice_track.ts
@@ -41,7 +41,7 @@
import {DEFAULT_SLICE_LAYOUT, SliceLayout} from './slice_layout';
import {constraintsToQuerySuffix} from './sql_utils';
import {NewTrackArgs} from './track';
-import {BUCKETS_PER_PIXEL, CacheKey, TrackCache} from './track_cache';
+import {BUCKETS_PER_PIXEL, CacheKey, TimelineCache} from '../core/timeline_cache';
// The common class that underpins all tracks drawing slices.
@@ -184,8 +184,8 @@
private slices = new Array<CastInternal<T['slice']>>();
// This is the slices cache:
- private cache: TrackCache<Array<CastInternal<T['slice']>>> =
- new TrackCache(5);
+ private cache: TimelineCache<Array<CastInternal<T['slice']>>> =
+ new TimelineCache(5);
// Incomplete slices (dur = -1). Rather than adding a lot of logic to
// the SQL queries to handle this case we materialise them one off
diff --git a/ui/src/frontend/panel_container.ts b/ui/src/frontend/panel_container.ts
index a86448b..9b19db0 100644
--- a/ui/src/frontend/panel_container.ts
+++ b/ui/src/frontend/panel_container.ts
@@ -254,11 +254,9 @@
this.panelByKey.set(key, node);
const mithril = node.mithril;
- return m(
- `.panel${extraClass}`,
- {key, 'data-key': key},
+ return m(`.panel${extraClass}`, {key, 'data-key': key},
perfDebug() ?
- [mithril, m('.debug-panel-border', {key: 'debug-panel-border'})] :
+ [mithril, m('.debug-panel-border')] :
mithril);
}
diff --git a/ui/src/frontend/sidebar.ts b/ui/src/frontend/sidebar.ts
index 257d2d8..627d888 100644
--- a/ui/src/frontend/sidebar.ts
+++ b/ui/src/frontend/sidebar.ts
@@ -754,8 +754,7 @@
href: `${GITILES_URL}/+/${SCM_REVISION}/ui`,
title: `Channel: ${getCurrentChannel()}`,
target: '_blank',
- },
- `${VERSION.substr(0, 11)}`),
+ }, VERSION),
),
);
},
diff --git a/ui/src/frontend/sql/thread_state.ts b/ui/src/frontend/sql/thread_state.ts
index 2274c15..24de373 100644
--- a/ui/src/frontend/sql/thread_state.ts
+++ b/ui/src/frontend/sql/thread_state.ts
@@ -72,7 +72,7 @@
// TODO(altimin): this probably should share some code with pivot tables when
// we actually get some pivot tables we like.
const query = await engine.query(`
- INCLUDE PERFETTO MODULE common.thread_states;
+ INCLUDE PERFETTO MODULE deprecated.v42.common.thread_states;
SELECT
state,
diff --git a/ui/src/frontend/track_panel.ts b/ui/src/frontend/track_panel.ts
index da06f31..697e45a 100644
--- a/ui/src/frontend/track_panel.ts
+++ b/ui/src/frontend/track_panel.ts
@@ -400,7 +400,6 @@
}
interface TrackPanelAttrs {
- key: string;
trackKey: string;
title: string;
tags?: TrackTags;
@@ -415,7 +414,7 @@
constructor(private readonly attrs: TrackPanelAttrs) {}
get key(): string {
- return this.attrs.key;
+ return this.attrs.trackKey;
}
get trackKey(): string {
@@ -435,7 +434,6 @@
});
}
return m(TrackComponent, {
- key: attrs.key,
trackKey: attrs.trackKey,
title: attrs.title,
heightPx: attrs.trackFSM.track.getHeight(),
@@ -447,7 +445,6 @@
});
} else {
return m(TrackComponent, {
- key: attrs.key,
trackKey: attrs.trackKey,
title: attrs.title,
revealOnCreate: attrs.revealOnCreate,
diff --git a/ui/src/frontend/viewer_page.ts b/ui/src/frontend/viewer_page.ts
index 693a54f..57d623c 100644
--- a/ui/src/frontend/viewer_page.ts
+++ b/ui/src/frontend/viewer_page.ts
@@ -227,7 +227,6 @@
globals.state.scrollingTracks.map((key) => {
const trackBundle = this.resolveTrack(key);
return new TrackPanel({
- key,
trackKey: key,
title: trackBundle.title,
tags: trackBundle.tags,
@@ -256,7 +255,6 @@
const key = group.tracks[i];
const trackBundle = this.resolveTrack(key);
const panel = new TrackPanel({
- key: `track-${group.id}-${key}`,
trackKey: key,
title: trackBundle.title,
tags: trackBundle.tags,
@@ -312,7 +310,6 @@
panels: globals.state.pinnedTracks.map((key) => {
const trackBundle = this.resolveTrack(key);
return new TrackPanel({
- key,
trackKey: key,
title: trackBundle.title,
tags: trackBundle.tags,
diff --git a/ui/src/plugins/dev.perfetto.AndroidPerf/index.ts b/ui/src/plugins/dev.perfetto.AndroidPerf/index.ts
index 7ef32d1..c8ffaf6 100644
--- a/ui/src/plugins/dev.perfetto.AndroidPerf/index.ts
+++ b/ui/src/plugins/dev.perfetto.AndroidPerf/index.ts
@@ -21,7 +21,7 @@
async addAppProcessStartsDebugTrack(
engine: EngineProxy, reason: string, sliceName: string): Promise<void> {
const sliceColumns =
- ['id', 'ts', 'dur', 'reason', 'process_name', 'intent', 'table_name'];
+ ['id', 'ts', 'dur', 'reason', 'process_name', 'intent', 'table_name'];
await addDebugSliceTrack(
engine,
{
@@ -91,7 +91,7 @@
if (tid === null) return;
}
ctx.tabs.openQuery(`
- INCLUDE PERFETTO MODULE common.cpus;
+ INCLUDE PERFETTO MODULE cpu.cpus;
WITH
total_runtime AS (
SELECT sum(dur) AS total_runtime
@@ -107,7 +107,7 @@
FROM sched s
LEFT JOIN thread t
USING (utid)
- LEFT JOIN cpus c
+ LEFT JOIN cpu_core_types c
ON s.cpu = c.cpu_index
WHERE t.tid = ${tid}
GROUP BY 1`, `runtime cluster distrubtion for tid ${tid}`);
diff --git a/ui/src/tracks/cpu_slices/index.ts b/ui/src/tracks/cpu_slices/index.ts
index 068142e..74e7555 100644
--- a/ui/src/tracks/cpu_slices/index.ts
+++ b/ui/src/tracks/cpu_slices/index.ts
@@ -61,7 +61,7 @@
const TRACK_HEIGHT = MARGIN_TOP * 2 + RECT_HEIGHT;
class CpuSliceTrack implements Track {
- private mousePos?: {x: number, y: number};
+ private mousePos?: { x: number, y: number };
private utidHoveredInThisTrack = -1;
private fetcher = new TimelineFetcher<Data>(this.onBoundsChange.bind(this));
@@ -140,7 +140,7 @@
}
async onBoundsChange(start: time, end: time, resolution: duration):
- Promise<Data> {
+ Promise<Data> {
assertTrue(BIMath.popcount(resolution) === 1, `${resolution} not pow of 2`);
const isCached = this.cachedBucketSize <= resolution;
@@ -148,7 +148,7 @@
`cached_tsq / ${resolution} * ${resolution}` :
`(ts + ${resolution / 2n}) / ${resolution} * ${resolution}`;
const queryTable =
- isCached ? this.tableName('sched_cached') : this.tableName('sched');
+ isCached ? this.tableName('sched_cached') : this.tableName('sched');
const constraintColumn = isCached ? 'cached_tsq' : 'ts';
const queryRes = await this.engine.query(`
@@ -411,7 +411,7 @@
// Draw diamond if the track being drawn is the cpu of the waker.
if (this.cpu === details.wakerCpu && details.wakeupTs) {
const wakeupPos =
- Math.floor(visibleTimeScale.timeToPx(details.wakeupTs));
+ Math.floor(visibleTimeScale.timeToPx(details.wakeupTs));
ctx.beginPath();
ctx.moveTo(wakeupPos, MARGIN_TOP + RECT_HEIGHT / 2 + 8);
ctx.fillStyle = 'black';
@@ -439,7 +439,7 @@
}
}
- onMouseMove(pos: {x: number, y: number}) {
+ onMouseMove(pos: { x: number, y: number }) {
const data = this.fetcher.data;
this.mousePos = pos;
if (data === undefined) return;
@@ -475,7 +475,7 @@
this.mousePos = undefined;
}
- onMouseClick({x}: {x: number}) {
+ onMouseClick({x}: { x: number }) {
const data = this.fetcher.data;
if (data === undefined) return false;
const {visibleTimeScale} = globals.timeline;
@@ -525,10 +525,11 @@
async guessCpuSizes(engine: EngineProxy): Promise<Map<number, string>> {
const cpuToSize = new Map<number, string>();
await engine.query(`
- INCLUDE PERFETTO MODULE common.cpus;
+ INCLUDE PERFETTO MODULE cpu.size;
`);
const result = await engine.query(`
- SELECT cpu, GUESS_CPU_SIZE(cpu) as size FROM cpu_counter_track;
+ SELECT cpu, cpu_guess_core_type(cpu) as size
+ FROM cpu_counter_track;
`);
const it = result.iter({