aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTreehugger Robot <treehugger-gerrit@google.com>2021-05-14 18:59:05 +0000
committerAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>2021-05-14 18:59:05 +0000
commit80e68f00e9b6cfc55d3d1d63a6d1cba2c2dea1c3 (patch)
tree4c4d72189918777a296230d5c71c166c19b9cebc
parent22dde0839e59a63e95749d960a5412c3dcb4069b (diff)
parenta8271f6373a7cf83018ff17dc6cbd95b5cd41da2 (diff)
downloadperfetto-80e68f00e9b6cfc55d3d1d63a6d1cba2c2dea1c3.tar.gz
Merge "tp: add table to store all the clock snapshots in the trace" am: a8271f6373
Original change: https://android-review.googlesource.com/c/platform/external/perfetto/+/1706850 Change-Id: Ic20144981c9fcd606f18ba97651e006662669b67
-rw-r--r--src/trace_processor/importers/common/clock_tracker.cc11
-rw-r--r--src/trace_processor/importers/common/clock_tracker.h3
-rw-r--r--src/trace_processor/importers/proto/proto_trace_reader.cc53
-rw-r--r--src/trace_processor/importers/proto/proto_trace_reader.h2
-rw-r--r--src/trace_processor/storage/trace_storage.h10
-rw-r--r--src/trace_processor/tables/metadata_tables.h22
-rw-r--r--src/trace_processor/tables/table_destructors.cc1
-rw-r--r--src/trace_processor/trace_processor_impl.cc1
8 files changed, 96 insertions, 7 deletions
diff --git a/src/trace_processor/importers/common/clock_tracker.cc b/src/trace_processor/importers/common/clock_tracker.cc
index f59fbfcd4..75518a263 100644
--- a/src/trace_processor/importers/common/clock_tracker.cc
+++ b/src/trace_processor/importers/common/clock_tracker.cc
@@ -41,7 +41,7 @@ ClockTracker::ClockTracker(TraceProcessorContext* ctx)
ClockTracker::~ClockTracker() = default;
-void ClockTracker::AddSnapshot(const std::vector<ClockValue>& clocks) {
+uint32_t ClockTracker::AddSnapshot(const std::vector<ClockValue>& clocks) {
const auto snapshot_id = cur_snapshot_id_++;
// Clear the cache
@@ -65,7 +65,7 @@ void ClockTracker::AddSnapshot(const std::vector<ClockValue>& clocks) {
"supported for sequence-scoped clocks.",
clock_id);
context_->storage->IncrementStats(stats::invalid_clock_snapshots);
- return;
+ return snapshot_id;
}
domain.unit_multiplier_ns = clock.unit_multiplier_ns;
domain.is_incremental = clock.is_incremental;
@@ -79,7 +79,7 @@ void ClockTracker::AddSnapshot(const std::vector<ClockValue>& clocks) {
clock_id, clock.unit_multiplier_ns, clock.is_incremental,
domain.unit_multiplier_ns, domain.is_incremental);
context_->storage->IncrementStats(stats::invalid_clock_snapshots);
- return;
+ return snapshot_id;
}
const int64_t timestamp_ns =
clock.absolute_timestamp * domain.unit_multiplier_ns;
@@ -92,7 +92,7 @@ void ClockTracker::AddSnapshot(const std::vector<ClockValue>& clocks) {
" at snapshot %" PRIu32 ".",
clock_id, snapshot_id);
context_->storage->IncrementStats(stats::invalid_clock_snapshots);
- return;
+ return snapshot_id;
}
// Clock ids in the range [64, 128) are sequence-scoped and must be
@@ -116,7 +116,7 @@ void ClockTracker::AddSnapshot(const std::vector<ClockValue>& clocks) {
clock_id, snapshot_id, timestamp_ns,
vect.timestamps_ns.back());
context_->storage->IncrementStats(stats::invalid_clock_snapshots);
- return;
+ return snapshot_id;
}
PERFETTO_DLOG("Detected non-monotonic clock with ID %" PRIu64, clock_id);
@@ -159,6 +159,7 @@ void ClockTracker::AddSnapshot(const std::vector<ClockValue>& clocks) {
graph_.emplace(it2->clock_id, it1->clock_id, snapshot_hash);
}
}
+ return snapshot_id;
}
// Finds the shortest clock resolution path in the graph that allows to
diff --git a/src/trace_processor/importers/common/clock_tracker.h b/src/trace_processor/importers/common/clock_tracker.h
index 80b2a4e9d..16b9d79ff 100644
--- a/src/trace_processor/importers/common/clock_tracker.h
+++ b/src/trace_processor/importers/common/clock_tracker.h
@@ -154,7 +154,8 @@ class ClockTracker {
// Appends a new snapshot for the given clock domains.
// This is typically called by the code that reads the ClockSnapshot packet.
- void AddSnapshot(const std::vector<ClockValue>&);
+ // Returns the internal snapshot id of this set of clocks.
+ uint32_t AddSnapshot(const std::vector<ClockValue>&);
// Converts a timestamp between two clock domains. Tries to use the cache
// first (only for single-path resolutions), then falls back on path finding
diff --git a/src/trace_processor/importers/proto/proto_trace_reader.cc b/src/trace_processor/importers/proto/proto_trace_reader.cc
index 863d5bd4a..ee03db396 100644
--- a/src/trace_processor/importers/proto/proto_trace_reader.cc
+++ b/src/trace_processor/importers/proto/proto_trace_reader.cc
@@ -378,10 +378,61 @@ util::Status ProtoTraceReader::ParseClockSnapshot(ConstBytes blob,
clocks.emplace_back(clock_id, clk.timestamp(), unit_multiplier_ns,
clk.is_incremental());
}
- context_->clock_tracker->AddSnapshot(clocks);
+
+ uint32_t snapshot_id = context_->clock_tracker->AddSnapshot(clocks);
+
+ // Add the all the clock values to the clock snapshot table.
+ base::Optional<int64_t> trace_ts_for_check;
+ for (const auto& clock : clocks) {
+ // If the clock is incremental, we need to use 0 to map correctly to
+ // |absolute_timestamp|.
+ int64_t ts_to_convert = clock.is_incremental ? 0 : clock.absolute_timestamp;
+ base::Optional<int64_t> opt_trace_ts =
+ context_->clock_tracker->ToTraceTime(clock.clock_id, ts_to_convert);
+ if (!opt_trace_ts) {
+ // This can happen if |AddSnapshot| failed to resolve this clock. Just
+ // ignore this and move on.
+ continue;
+ }
+
+ // Double check that all the clocks in this snapshot resolve to the same
+ // trace timestamp value.
+ PERFETTO_DCHECK(!trace_ts_for_check || opt_trace_ts == trace_ts_for_check);
+ trace_ts_for_check = *opt_trace_ts;
+
+ tables::ClockSnapshotTable::Row row;
+ row.ts = *opt_trace_ts;
+ row.clock_id = static_cast<int64_t>(clock.clock_id);
+ row.clock_value = clock.absolute_timestamp;
+ row.clock_name = GetBuiltinClockNameOrNull(clock.clock_id);
+ row.snapshot_id = snapshot_id;
+
+ auto* snapshot_table = context_->storage->mutable_clock_snapshot_table();
+ snapshot_table->Insert(row);
+ }
return util::OkStatus();
}
+base::Optional<StringId> ProtoTraceReader::GetBuiltinClockNameOrNull(
+ uint64_t clock_id) {
+ switch (clock_id) {
+ case protos::pbzero::ClockSnapshot::Clock::REALTIME:
+ return context_->storage->InternString("REALTIME");
+ case protos::pbzero::ClockSnapshot::Clock::REALTIME_COARSE:
+ return context_->storage->InternString("REALTIME_COARSE");
+ case protos::pbzero::ClockSnapshot::Clock::MONOTONIC:
+ return context_->storage->InternString("MONOTONIC");
+ case protos::pbzero::ClockSnapshot::Clock::MONOTONIC_COARSE:
+ return context_->storage->InternString("MONOTONIC_COARSE");
+ case protos::pbzero::ClockSnapshot::Clock::MONOTONIC_RAW:
+ return context_->storage->InternString("MONOTONIC_RAW");
+ case protos::pbzero::ClockSnapshot::Clock::BOOTTIME:
+ return context_->storage->InternString("BOOTTIME");
+ default:
+ return base::nullopt;
+ }
+}
+
util::Status ProtoTraceReader::ParseServiceEvent(int64_t ts, ConstBytes blob) {
protos::pbzero::TracingServiceEvent::Decoder tse(blob);
if (tse.tracing_started()) {
diff --git a/src/trace_processor/importers/proto/proto_trace_reader.h b/src/trace_processor/importers/proto/proto_trace_reader.h
index b2f4069f4..1adb84151 100644
--- a/src/trace_processor/importers/proto/proto_trace_reader.h
+++ b/src/trace_processor/importers/proto/proto_trace_reader.h
@@ -75,6 +75,8 @@ class ProtoTraceReader : public ChunkedTraceReader {
TraceBlobView interned_data);
void ParseTraceConfig(ConstBytes);
+ base::Optional<StringId> GetBuiltinClockNameOrNull(uint64_t clock_id);
+
PacketSequenceState* GetIncrementalStateForPacketSequence(
uint32_t sequence_id) {
if (!incremental_state)
diff --git a/src/trace_processor/storage/trace_storage.h b/src/trace_processor/storage/trace_storage.h
index 698aa7cd1..e2af2ce75 100644
--- a/src/trace_processor/storage/trace_storage.h
+++ b/src/trace_processor/storage/trace_storage.h
@@ -442,6 +442,13 @@ class TraceStorage {
}
tables::MetadataTable* mutable_metadata_table() { return &metadata_table_; }
+ const tables::ClockSnapshotTable& clock_snapshot_table() const {
+ return clock_snapshot_table_;
+ }
+ tables::ClockSnapshotTable* mutable_clock_snapshot_table() {
+ return &clock_snapshot_table_;
+ }
+
const tables::ArgTable& arg_table() const { return arg_table_; }
tables::ArgTable* mutable_arg_table() { return &arg_table_; }
@@ -719,6 +726,9 @@ class TraceStorage {
// * descriptions of android packages
tables::MetadataTable metadata_table_{&string_pool_, nullptr};
+ // Contains data from all the clock snapshots in the trace.
+ tables::ClockSnapshotTable clock_snapshot_table_{&string_pool_, nullptr};
+
// Metadata for tracks.
tables::TrackTable track_table_{&string_pool_, nullptr};
tables::GpuTrackTable gpu_track_table_{&string_pool_, &track_table_};
diff --git a/src/trace_processor/tables/metadata_tables.h b/src/trace_processor/tables/metadata_tables.h
index fa3136b46..3f1bb9074 100644
--- a/src/trace_processor/tables/metadata_tables.h
+++ b/src/trace_processor/tables/metadata_tables.h
@@ -113,6 +113,28 @@ PERFETTO_TP_TABLE(PERFETTO_TP_CPU_TABLE_DEF);
PERFETTO_TP_TABLE(PERFETTO_TP_CPU_FREQ_TABLE_DEF);
+// Contains all the mapping between clock snapshots and trace time.
+//
+// NOTE: this table is not sorted by timestamp; this is why we omit the
+// sorted flag on the ts column.
+//
+// @param ts timestamp of the snapshot in trace time.
+// @param clock_id id of the clock (corresponds to the id in the trace).
+// @param clock_name the name of the clock for builtin clocks or null
+// otherwise.
+// @param clock_value timestamp of the snapshot in clock time.
+// @param snapshot_id the index of this snapshot (only useful for debugging)
+#define PERFETTO_TP_CLOCK_SNAPSHOT_TABLE_DEF(NAME, PARENT, C) \
+ NAME(ClockSnapshotTable, "clock_snapshot") \
+ PERFETTO_TP_ROOT_TABLE(PARENT, C) \
+ C(int64_t, ts) \
+ C(int64_t, clock_id) \
+ C(base::Optional<StringPool::Id>, clock_name) \
+ C(int64_t, clock_value) \
+ C(uint32_t, snapshot_id)
+
+PERFETTO_TP_TABLE(PERFETTO_TP_CLOCK_SNAPSHOT_TABLE_DEF);
+
} // namespace tables
} // namespace trace_processor
} // namespace perfetto
diff --git a/src/trace_processor/tables/table_destructors.cc b/src/trace_processor/tables/table_destructors.cc
index d57b71b68..34206b9b3 100644
--- a/src/trace_processor/tables/table_destructors.cc
+++ b/src/trace_processor/tables/table_destructors.cc
@@ -45,6 +45,7 @@ CpuTable::~CpuTable() = default;
CpuFreqTable::~CpuFreqTable() = default;
ThreadTable::~ThreadTable() = default;
ProcessTable::~ProcessTable() = default;
+ClockSnapshotTable::~ClockSnapshotTable() = default;
// profiler_tables.h
StackProfileMappingTable::~StackProfileMappingTable() = default;
diff --git a/src/trace_processor/trace_processor_impl.cc b/src/trace_processor/trace_processor_impl.cc
index 8893144e6..0ca05ead6 100644
--- a/src/trace_processor/trace_processor_impl.cc
+++ b/src/trace_processor/trace_processor_impl.cc
@@ -825,6 +825,7 @@ TraceProcessorImpl::TraceProcessorImpl(const Config& cfg)
RegisterDbTable(storage->metadata_table());
RegisterDbTable(storage->cpu_table());
RegisterDbTable(storage->cpu_freq_table());
+ RegisterDbTable(storage->clock_snapshot_table());
RegisterDbTable(storage->memory_snapshot_table());
RegisterDbTable(storage->process_memory_snapshot_table());