diff options
author | Treehugger Robot <treehugger-gerrit@google.com> | 2021-05-14 18:59:05 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2021-05-14 18:59:05 +0000 |
commit | 80e68f00e9b6cfc55d3d1d63a6d1cba2c2dea1c3 (patch) | |
tree | 4c4d72189918777a296230d5c71c166c19b9cebc | |
parent | 22dde0839e59a63e95749d960a5412c3dcb4069b (diff) | |
parent | a8271f6373a7cf83018ff17dc6cbd95b5cd41da2 (diff) | |
download | perfetto-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.cc | 11 | ||||
-rw-r--r-- | src/trace_processor/importers/common/clock_tracker.h | 3 | ||||
-rw-r--r-- | src/trace_processor/importers/proto/proto_trace_reader.cc | 53 | ||||
-rw-r--r-- | src/trace_processor/importers/proto/proto_trace_reader.h | 2 | ||||
-rw-r--r-- | src/trace_processor/storage/trace_storage.h | 10 | ||||
-rw-r--r-- | src/trace_processor/tables/metadata_tables.h | 22 | ||||
-rw-r--r-- | src/trace_processor/tables/table_destructors.cc | 1 | ||||
-rw-r--r-- | src/trace_processor/trace_processor_impl.cc | 1 |
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()); |