• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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_SESSION_H_
18 #define SRC_TRACE_PROCESSOR_IMPORTERS_PERF_PERF_SESSION_H_
19 
20 #include <sys/types.h>
21 #include <cstddef>
22 #include <cstdint>
23 #include <optional>
24 #include <string>
25 #include <vector>
26 
27 #include "perfetto/ext/base/flat_hash_map.h"
28 #include "perfetto/ext/base/hash.h"
29 #include "perfetto/ext/base/status_or.h"
30 #include "perfetto/trace_processor/ref_counted.h"
31 #include "perfetto/trace_processor/trace_blob_view.h"
32 #include "src/trace_processor/importers/perf/perf_event.h"
33 #include "src/trace_processor/importers/perf/perf_event_attr.h"
34 #include "src/trace_processor/tables/profiler_tables_py.h"
35 #include "src/trace_processor/util/build_id.h"
36 
37 namespace perfetto::trace_processor {
38 
39 class TraceProcessorContext;
40 
41 namespace perf_importer {
42 
43 // Helper to deal with perf_event_attr instances in a perf file.
44 class PerfSession : public RefCounted {
45  public:
46   class Builder {
47    public:
Builder(TraceProcessorContext * context)48     explicit Builder(TraceProcessorContext* context) : context_(context) {}
49     base::StatusOr<RefPtr<PerfSession>> Build();
AddAttrAndIds(perf_event_attr attr,std::vector<uint64_t> ids)50     Builder& AddAttrAndIds(perf_event_attr attr, std::vector<uint64_t> ids) {
51       attr_with_ids_.push_back({std::move(attr), std::move(ids)});
52       return *this;
53     }
54 
55    private:
56     struct PerfEventAttrWithIds {
57       perf_event_attr attr;
58       std::vector<uint64_t> ids;
59     };
60 
61     TraceProcessorContext* const context_;
62     std::vector<PerfEventAttrWithIds> attr_with_ids_;
63   };
64 
perf_session_id()65   tables::PerfSessionTable::Id perf_session_id() const {
66     return perf_session_id_;
67   }
68 
69   RefPtr<const PerfEventAttr> FindAttrForEventId(uint64_t id) const;
70 
71   base::StatusOr<RefPtr<const PerfEventAttr>> FindAttrForRecord(
72       const perf_event_header& header,
73       const TraceBlobView& payload) const;
74 
75   void SetCmdline(const std::vector<std::string>& args);
76   void SetEventName(uint64_t event_id, std::string name);
77   void SetEventName(uint32_t type, uint64_t config, const std::string& name);
78 
79   void AddBuildId(int32_t pid, std::string filename, BuildId build_id);
80   std::optional<BuildId> LookupBuildId(uint32_t pid,
81                                        const std::string& filename) const;
82 
83  private:
84   struct BuildIdMapKey {
85     int32_t pid;
86     std::string filename;
87 
88     struct Hasher {
operatorBuildIdMapKey::Hasher89       size_t operator()(const BuildIdMapKey& k) const {
90         return static_cast<size_t>(base::Hasher::Combine(k.pid, k.filename));
91       }
92     };
93 
94     bool operator==(const BuildIdMapKey& o) const {
95       return pid == o.pid && filename == o.filename;
96     }
97   };
98 
PerfSession(TraceProcessorContext * context,tables::PerfSessionTable::Id perf_session_id,base::FlatHashMap<uint64_t,RefPtr<PerfEventAttr>> attrs_by_id,bool has_single_perf_event_attr)99   PerfSession(TraceProcessorContext* context,
100               tables::PerfSessionTable::Id perf_session_id,
101               base::FlatHashMap<uint64_t, RefPtr<PerfEventAttr>> attrs_by_id,
102               bool has_single_perf_event_attr)
103       : context_(context),
104         perf_session_id_(perf_session_id),
105         attrs_by_id_(std::move(attrs_by_id)),
106         has_single_perf_event_attr_(has_single_perf_event_attr) {}
107 
108   bool ReadEventId(const perf_event_header& header,
109                    const TraceBlobView& payload,
110                    uint64_t& id) const;
111 
112   TraceProcessorContext* const context_;
113   tables::PerfSessionTable::Id perf_session_id_;
114   base::FlatHashMap<uint64_t, RefPtr<PerfEventAttr>> attrs_by_id_;
115   // Multiple ids can map to the same perf_event_attr. This member tells us
116   // whether there was only one perf_event_attr (with potentially different ids
117   // associated). This makes the attr lookup given a record trivial and not
118   // dependant no having any id field in the records.
119   bool has_single_perf_event_attr_;
120 
121   base::FlatHashMap<BuildIdMapKey, BuildId, BuildIdMapKey::Hasher> build_ids_;
122 };
123 
124 }  // namespace perf_importer
125 }  // namespace perfetto::trace_processor
126 
127 #endif  // SRC_TRACE_PROCESSOR_IMPORTERS_PERF_PERF_SESSION_H_
128