xref: /aosp_15_r20/external/perfetto/src/trace_processor/importers/perf/aux_stream_manager.h (revision 6dbdd20afdafa5e3ca9b8809fa73465d530080dc)
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_AUX_STREAM_MANAGER_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_PERF_AUX_STREAM_MANAGER_H_
19 
20 #include <cstdint>
21 #include <functional>
22 #include <memory>
23 #include <optional>
24 #include <variant>
25 
26 #include "perfetto/base/logging.h"
27 #include "perfetto/base/status.h"
28 #include "perfetto/ext/base/circular_queue.h"
29 #include "perfetto/ext/base/flat_hash_map.h"
30 #include "perfetto/ext/base/status_or.h"
31 #include "perfetto/trace_processor/trace_blob_view.h"
32 #include "src/trace_processor/importers/perf/aux_data_tokenizer.h"
33 #include "src/trace_processor/importers/perf/aux_record.h"
34 #include "src/trace_processor/importers/perf/auxtrace_record.h"
35 #include "src/trace_processor/importers/perf/itrace_start_record.h"
36 #include "src/trace_processor/importers/perf/perf_session.h"
37 #include "src/trace_processor/importers/perf/time_conv_record.h"
38 #include "src/trace_processor/storage/stats.h"
39 
40 namespace perfetto {
41 namespace trace_processor {
42 class TraceProcessorContext;
43 
44 namespace perf_importer {
45 
46 struct Record;
47 class SampleId;
48 struct AuxtraceInfoRecord;
49 
50 class AuxStreamManager;
51 
52 // Takes care of reconstructing the original data stream out of AUX and AUXTRACE
53 // records. Does not parse tha actual data it just forwards it to the associated
54 // `AuxDataTokenizer` .
55 class AuxStream {
56  public:
57   enum class Type {
58     kCpuBound,
59     kThreadBound,
60   };
61 
62   ~AuxStream();
63   std::optional<uint64_t> ConvertTscToPerfTime(uint64_t cycles);
64 
type()65   Type type() const { return type_; }
66 
cpu()67   uint32_t cpu() const {
68     PERFETTO_CHECK(type_ == Type::kCpuBound);
69     return tid_or_cpu_;
70   }
71 
tid()72   uint32_t tid() const {
73     PERFETTO_CHECK(type_ == Type::kThreadBound);
74     return tid_or_cpu_;
75   }
76 
77  private:
78   class AuxtraceDataReader {
79    public:
80     AuxtraceDataReader(AuxtraceRecord auxtrace, TraceBlobView data);
81 
82     TraceBlobView ConsumeFront(uint64_t size);
83     void DropUntil(uint64_t offset);
84 
offset()85     uint64_t offset() const { return offset_; }
end()86     uint64_t end() const { return offset_ + data_.size(); }
size()87     uint64_t size() const { return data_.size(); }
88 
89    private:
90     uint64_t offset_;
91     TraceBlobView data_;
92   };
93 
94   using OutstandingRecord = std::variant<ItraceStartRecord, AuxRecord>;
95 
96   friend AuxStreamManager;
97   AuxStream(AuxStreamManager* manager, Type type, uint32_t tid_or_cpu);
98 
99   base::Status OnAuxRecord(AuxRecord aux);
100   base::Status OnAuxtraceRecord(AuxtraceRecord auxtrace, TraceBlobView data);
101   base::Status NotifyEndOfStream();
102   base::Status OnItraceStartRecord(ItraceStartRecord start);
103 
104   base::Status MaybeParse();
105 
106   AuxStreamManager& manager_;
107   Type type_;
108   uint32_t tid_or_cpu_;
109   AuxDataStream* data_stream_;
110   base::CircularQueue<OutstandingRecord> outstanding_records_;
111   uint64_t aux_end_ = 0;
112   base::CircularQueue<AuxtraceDataReader> outstanding_auxtrace_data_;
113   uint64_t auxtrace_end_ = 0;
114   uint64_t tokenizer_offset_ = 0;
115 };
116 
117 // Keeps track of all aux streams in a perf file.
118 class AuxStreamManager {
119  public:
AuxStreamManager(TraceProcessorContext * context)120   explicit AuxStreamManager(TraceProcessorContext* context)
121       : context_(context) {}
122   base::Status OnAuxtraceInfoRecord(AuxtraceInfoRecord info);
123   base::Status OnAuxRecord(AuxRecord aux);
124   base::Status OnAuxtraceRecord(AuxtraceRecord auxtrace, TraceBlobView data);
125   base::Status OnItraceStartRecord(ItraceStartRecord start);
OnTimeConvRecord(TimeConvRecord time_conv)126   base::Status OnTimeConvRecord(TimeConvRecord time_conv) {
127     time_conv_ = std::move(time_conv);
128     return base::OkStatus();
129   }
130 
131   base::Status FinalizeStreams();
132 
context()133   TraceProcessorContext* context() const { return context_; }
134 
ConvertTscToPerfTime(uint64_t cycles)135   std::optional<uint64_t> ConvertTscToPerfTime(uint64_t cycles) {
136     if (!time_conv_) {
137       context_->storage->IncrementStats(stats::perf_no_tsc_data);
138       return std::nullopt;
139     }
140     return time_conv_->ConvertTscToPerfTime(cycles);
141   }
142 
143  private:
144   base::StatusOr<std::reference_wrapper<AuxStream>>
145   GetOrCreateStreamForSampleId(const std::optional<SampleId>& sample_id);
146   base::StatusOr<std::reference_wrapper<AuxStream>> GetOrCreateStreamForCpu(
147       uint32_t cpu);
148 
149   TraceProcessorContext* const context_;
150   std::unique_ptr<AuxDataTokenizer> tokenizer_;
151   base::FlatHashMap<uint32_t, std::unique_ptr<AuxStream>>
152       auxdata_streams_by_cpu_;
153   std::optional<TimeConvRecord> time_conv_;
154 };
155 
ConvertTscToPerfTime(uint64_t cycles)156 inline std::optional<uint64_t> AuxStream::ConvertTscToPerfTime(
157     uint64_t cycles) {
158   return manager_.ConvertTscToPerfTime(cycles);
159 }
160 
161 }  // namespace perf_importer
162 }  // namespace trace_processor
163 }  // namespace perfetto
164 
165 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_PERF_AUX_STREAM_MANAGER_H_
166