1 /* 2 * Copyright (C) 2023 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_PERF_PERF_DATA_TOKENIZER_H_ 18 #define SRC_TRACE_PROCESSOR_IMPORTERS_PERF_PERF_DATA_TOKENIZER_H_ 19 20 #include <stdint.h> 21 #include <cstdint> 22 #include <optional> 23 #include <vector> 24 25 #include "perfetto/base/flat_set.h" 26 #include "perfetto/base/status.h" 27 #include "perfetto/ext/base/status_or.h" 28 #include "perfetto/trace_processor/ref_counted.h" 29 #include "perfetto/trace_processor/trace_blob_view.h" 30 #include "src/trace_processor/importers/common/chunked_trace_reader.h" 31 #include "src/trace_processor/importers/perf/perf_file.h" 32 #include "src/trace_processor/importers/perf/perf_session.h" 33 #include "src/trace_processor/util/file_buffer.h" 34 35 namespace perfetto { 36 namespace trace_processor { 37 class TraceProcessorContext; 38 39 namespace perf_importer { 40 41 struct Record; 42 43 class PerfDataTokenizer : public ChunkedTraceReader { 44 public: 45 explicit PerfDataTokenizer(TraceProcessorContext*); 46 ~PerfDataTokenizer() override; 47 PerfDataTokenizer(const PerfDataTokenizer&) = delete; 48 PerfDataTokenizer& operator=(const PerfDataTokenizer&) = delete; 49 50 // ChunkedTraceReader implementation 51 base::Status Parse(TraceBlobView) override; 52 void NotifyEndOfFile() override; 53 54 private: 55 enum class ParsingState { 56 kParseHeader, 57 kParseAttrs, 58 kSeekRecords, 59 kParseRecords, 60 kParseFeatureSections, 61 kParseFeatures, 62 kDone, 63 }; 64 enum class ParsingResult { kMoreDataNeeded = 0, kSuccess = 1 }; 65 66 base::StatusOr<ParsingResult> ParseHeader(); 67 base::StatusOr<ParsingResult> ParseAttrs(); 68 base::StatusOr<ParsingResult> SeekRecords(); 69 base::StatusOr<ParsingResult> ParseRecords(); 70 base::StatusOr<ParsingResult> ParseFeatureSections(); 71 base::StatusOr<ParsingResult> ParseFeatures(); 72 73 base::StatusOr<PerfDataTokenizer::ParsingResult> ParseRecord(Record& record); 74 bool PushRecord(Record record); 75 base::Status ParseFeature(uint8_t feature_id, TraceBlobView payload); 76 77 base::StatusOr<int64_t> ToTraceTimestamp(std::optional<uint64_t> time); 78 79 TraceProcessorContext* context_; 80 81 ParsingState parsing_state_ = ParsingState::kParseHeader; 82 83 PerfFile::Header header_; 84 base::FlatSet<uint8_t> feature_ids_; 85 PerfFile::Section feature_headers_section_; 86 // Sections for the features present in the perf file sorted by descending 87 // section offset. This is done so that we can pop from the back as we process 88 // the sections. 89 std::vector<std::pair<uint8_t, PerfFile::Section>> feature_sections_; 90 91 RefPtr<PerfSession> perf_session_; 92 93 util::FileBuffer buffer_; 94 95 int64_t latest_timestamp_ = 0; 96 }; 97 98 } // namespace perf_importer 99 } // namespace trace_processor 100 } // namespace perfetto 101 102 #endif // SRC_TRACE_PROCESSOR_IMPORTERS_PERF_PERF_DATA_TOKENIZER_H_ 103