1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifndef SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_TRACE_READER_H_ 18 #define SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_TRACE_READER_H_ 19 20 #include <cstddef> 21 #include <cstdint> 22 #include <optional> 23 #include <utility> 24 #include <vector> 25 26 #include "perfetto/base/status.h" 27 #include "perfetto/ext/base/flat_hash_map.h" 28 #include "src/trace_processor/importers/common/chunked_trace_reader.h" 29 #include "src/trace_processor/importers/proto/multi_machine_trace_manager.h" 30 #include "src/trace_processor/importers/proto/packet_sequence_state_builder.h" 31 #include "src/trace_processor/importers/proto/proto_trace_tokenizer.h" 32 #include "src/trace_processor/storage/trace_storage.h" 33 34 namespace protozero { 35 struct ConstBytes; 36 } 37 38 namespace perfetto { 39 40 namespace protos::pbzero { 41 class TracePacket_Decoder; 42 class TraceConfig_Decoder; 43 } // namespace protos::pbzero 44 45 namespace trace_processor { 46 47 class PacketSequenceState; 48 class TraceProcessorContext; 49 class TraceSorter; 50 class TraceStorage; 51 52 // Implementation of ChunkedTraceReader for proto traces. Tokenizes a proto 53 // trace into packets, handles parsing of any packets which need to be 54 // handled in trace-order and passes the remainder to TraceSorter to sort 55 // into timestamp order. 56 class ProtoTraceReader : public ChunkedTraceReader { 57 public: 58 // |reader| is the abstract method of getting chunks of size |chunk_size_b| 59 // from a trace file with these chunks parsed into |trace|. 60 explicit ProtoTraceReader(TraceProcessorContext*); 61 ~ProtoTraceReader() override; 62 63 // ChunkedTraceReader implementation. 64 base::Status Parse(TraceBlobView) override; 65 base::Status NotifyEndOfFile() override; 66 67 using SyncClockSnapshots = base::FlatHashMap< 68 int64_t, 69 std::pair</*host ts*/ uint64_t, /*client ts*/ uint64_t>>; 70 static base::FlatHashMap<int64_t /*Clock Id*/, int64_t /*Offset*/> CalculateClockOffsetsForTesting(std::vector<SyncClockSnapshots> & sync_clock_snapshots)71 CalculateClockOffsetsForTesting( 72 std::vector<SyncClockSnapshots>& sync_clock_snapshots) { 73 return CalculateClockOffsets(sync_clock_snapshots); 74 } 75 76 std::optional<StringId> GetBuiltinClockNameOrNull(int64_t clock_id); 77 78 private: 79 struct SequenceScopedState { 80 std::optional<PacketSequenceStateBuilder> sequence_state_builder; 81 uint32_t previous_packet_dropped_count = 0; 82 uint32_t needs_incremental_state_total = 0; 83 uint32_t needs_incremental_state_skipped = 0; 84 }; 85 86 using ConstBytes = protozero::ConstBytes; 87 base::Status ParsePacket(TraceBlobView); 88 base::Status TimestampTokenizeAndPushToSorter(TraceBlobView); 89 base::Status ParseServiceEvent(int64_t ts, ConstBytes); 90 base::Status ParseClockSnapshot(ConstBytes blob, uint32_t seq_id); 91 base::Status ParseRemoteClockSync(ConstBytes blob); 92 void HandleIncrementalStateCleared( 93 const protos::pbzero::TracePacket_Decoder&); 94 void HandleFirstPacketOnSequence(uint32_t packet_sequence_id); 95 void HandlePreviousPacketDropped(const protos::pbzero::TracePacket_Decoder&); 96 void ParseTracePacketDefaults(const protos::pbzero::TracePacket_Decoder&, 97 TraceBlobView trace_packet_defaults); 98 void ParseInternedData(const protos::pbzero::TracePacket_Decoder&, 99 TraceBlobView interned_data); 100 void ParseTraceConfig(ConstBytes); 101 void ParseTraceStats(ConstBytes); 102 103 static base::FlatHashMap<int64_t /*Clock Id*/, int64_t /*Offset*/> 104 CalculateClockOffsets(std::vector<SyncClockSnapshots>&); 105 GetIncrementalStateForPacketSequence(uint32_t sequence_id)106 PacketSequenceStateBuilder* GetIncrementalStateForPacketSequence( 107 uint32_t sequence_id) { 108 auto& builder = sequence_state_.Find(sequence_id)->sequence_state_builder; 109 if (!builder) { 110 builder = PacketSequenceStateBuilder(context_); 111 } 112 return &*builder; 113 } 114 base::Status ParseExtensionDescriptor(ConstBytes descriptor); 115 116 TraceProcessorContext* context_; 117 118 ProtoTraceTokenizer tokenizer_; 119 120 // Temporary. Currently trace packets do not have a timestamp, so the 121 // timestamp given is latest_timestamp_. 122 int64_t latest_timestamp_ = 0; 123 124 base::FlatHashMap<uint32_t, SequenceScopedState> sequence_state_; 125 StringId skipped_packet_key_id_; 126 StringId invalid_incremental_state_key_id_; 127 128 std::vector<TraceBlobView> eof_deferred_packets_; 129 bool received_eof_ = false; 130 }; 131 132 } // namespace trace_processor 133 } // namespace perfetto 134 135 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_PROTO_PROTO_TRACE_READER_H_ 136