ronnie
2022-10-14 1504bb53e29d3d46222c0b3ea994fc494b48e153
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
 
#ifndef CHROMIUMOS_WIDE_PROFILING_PERF_SERIALIZER_H_
#define CHROMIUMOS_WIDE_PROFILING_PERF_SERIALIZER_H_
 
#include <stdint.h>
#include <sys/types.h>
 
#include <map>
#include <memory>
#include <vector>
 
#include "base/macros.h"
 
#include "compat/proto.h"
#include "compat/string.h"
#include "perf_data_utils.h"
 
struct perf_event_attr;
 
namespace quipper {
 
struct ParsedEvent;
struct PerfFileAttr;
struct PerfGroupDescMetadata;
struct PerfPMUMappingsMetadata;
struct PerfNodeTopologyMetadata;
struct PerfCPUTopologyMetadata;
struct PerfEventStats;
struct PerfParserOptions;
struct PerfUint32Metadata;
struct PerfUint64Metadata;
 
class SampleInfoReader;
 
class PerfSerializer {
 public:
  PerfSerializer();
  ~PerfSerializer();
 
  // The following functions convert between raw perf data structures and their
  // equivalent PerfDataProto representations.
  bool SerializePerfFileAttr(
      const PerfFileAttr& perf_file_attr,
      PerfDataProto_PerfFileAttr* perf_file_attr_proto) const;
  bool DeserializePerfFileAttr(
      const PerfDataProto_PerfFileAttr& perf_file_attr_proto,
      PerfFileAttr* perf_file_attr) const;
 
  bool SerializePerfEventAttr(
      const perf_event_attr& perf_event_attr,
      PerfDataProto_PerfEventAttr* perf_event_attr_proto) const;
  bool DeserializePerfEventAttr(
      const PerfDataProto_PerfEventAttr& perf_event_attr_proto,
      perf_event_attr* perf_event_attr) const;
 
  bool SerializePerfEventType(
      const PerfFileAttr& event_attr,
      PerfDataProto_PerfEventType* event_type_proto) const;
  bool DeserializePerfEventType(
      const PerfDataProto_PerfEventType& event_type_proto,
      PerfFileAttr* event_attr) const;
 
  bool SerializeEvent(const malloced_unique_ptr<event_t>& event_ptr,
                      PerfDataProto_PerfEvent* event_proto) const;
  bool DeserializeEvent(const PerfDataProto_PerfEvent& event_proto,
                        malloced_unique_ptr<event_t>* event_ptr) const;
  bool SerializeEventHeader(const perf_event_header& header,
                            PerfDataProto_EventHeader* header_proto) const;
  bool DeserializeEventHeader(const PerfDataProto_EventHeader& header_proto,
                              perf_event_header* header) const;
 
  bool SerializeSampleEvent(const event_t& event,
                            PerfDataProto_SampleEvent* sample) const;
  bool DeserializeSampleEvent(const PerfDataProto_SampleEvent& sample,
                              event_t* event) const;
 
  bool SerializeMMapEvent(const event_t& event,
                          PerfDataProto_MMapEvent* sample) const;
  bool DeserializeMMapEvent(const PerfDataProto_MMapEvent& sample,
                            event_t* event) const;
 
  bool SerializeMMap2Event(const event_t& event,
                           PerfDataProto_MMapEvent* sample) const;
  bool DeserializeMMap2Event(const PerfDataProto_MMapEvent& sample,
                             event_t* event) const;
 
  bool SerializeCommEvent(const event_t& event,
                          PerfDataProto_CommEvent* sample) const;
  bool DeserializeCommEvent(const PerfDataProto_CommEvent& sample,
                            event_t* event) const;
 
  // These handle both fork and exit events, which use the same protobuf
  // message definition.
  bool SerializeForkExitEvent(const event_t& event,
                              PerfDataProto_ForkEvent* sample) const;
  bool DeserializeForkExitEvent(const PerfDataProto_ForkEvent& sample,
                                event_t* event) const;
 
  bool SerializeLostEvent(const event_t& event,
                          PerfDataProto_LostEvent* sample) const;
  bool DeserializeLostEvent(const PerfDataProto_LostEvent& sample,
                            event_t* event) const;
 
  bool SerializeThrottleEvent(const event_t& event,
                              PerfDataProto_ThrottleEvent* sample) const;
  bool DeserializeThrottleEvent(const PerfDataProto_ThrottleEvent& sample,
                                event_t* event) const;
 
  bool SerializeReadEvent(const event_t& event,
                          PerfDataProto_ReadEvent* sample) const;
  bool DeserializeReadEvent(const PerfDataProto_ReadEvent& sample,
                            event_t* event) const;
 
  bool SerializeAuxEvent(const event_t& event,
                         PerfDataProto_AuxEvent* sample) const;
  bool DeserializeAuxEvent(const PerfDataProto_AuxEvent& sample,
                           event_t* event) const;
 
  bool SerializeSampleInfo(const event_t& event,
                           PerfDataProto_SampleInfo* sample_info) const;
  bool DeserializeSampleInfo(const PerfDataProto_SampleInfo& info,
                             event_t* event) const;
 
  bool SerializeTracingMetadata(const std::vector<char>& from,
                                PerfDataProto* to) const;
  bool DeserializeTracingMetadata(const PerfDataProto& from,
                                  std::vector<char>* to) const;
 
  bool SerializeBuildIDEvent(const malloced_unique_ptr<build_id_event>& from,
                             PerfDataProto_PerfBuildID* to) const;
  bool DeserializeBuildIDEvent(const PerfDataProto_PerfBuildID& from,
                               malloced_unique_ptr<build_id_event>* to) const;
 
  bool SerializeAuxtraceEvent(const event_t& event,
                              PerfDataProto_AuxtraceEvent* sample) const;
  bool SerializeAuxtraceEventTraceData(const std::vector<char>& from,
                                       PerfDataProto_AuxtraceEvent* to) const;
  bool DeserializeAuxtraceEvent(const PerfDataProto_AuxtraceEvent& sample,
                                event_t* event) const;
  bool DeserializeAuxtraceEventTraceData(
      const PerfDataProto_AuxtraceEvent& from, std::vector<char>* to) const;
 
  bool SerializeSingleUint32Metadata(
      const PerfUint32Metadata& metadata,
      PerfDataProto_PerfUint32Metadata* proto_metadata) const;
  bool DeserializeSingleUint32Metadata(
      const PerfDataProto_PerfUint32Metadata& proto_metadata,
      PerfUint32Metadata* metadata) const;
 
  bool SerializeSingleUint64Metadata(
      const PerfUint64Metadata& metadata,
      PerfDataProto_PerfUint64Metadata* proto_metadata) const;
  bool DeserializeSingleUint64Metadata(
      const PerfDataProto_PerfUint64Metadata& proto_metadata,
      PerfUint64Metadata* metadata) const;
 
  bool SerializeCPUTopologyMetadata(
      const PerfCPUTopologyMetadata& metadata,
      PerfDataProto_PerfCPUTopologyMetadata* proto_metadata) const;
  bool DeserializeCPUTopologyMetadata(
      const PerfDataProto_PerfCPUTopologyMetadata& proto_metadata,
      PerfCPUTopologyMetadata* metadata) const;
 
  bool SerializeNodeTopologyMetadata(
      const PerfNodeTopologyMetadata& metadata,
      PerfDataProto_PerfNodeTopologyMetadata* proto_metadata) const;
  bool DeserializeNodeTopologyMetadata(
      const PerfDataProto_PerfNodeTopologyMetadata& proto_metadata,
      PerfNodeTopologyMetadata* metadata) const;
 
  bool SerializePMUMappingsMetadata(
      const PerfPMUMappingsMetadata& metadata,
      PerfDataProto_PerfPMUMappingsMetadata* proto_metadata) const;
  bool DeserializePMUMappingsMetadata(
      const PerfDataProto_PerfPMUMappingsMetadata& proto_metadata,
      PerfPMUMappingsMetadata* metadata) const;
 
  bool SerializeGroupDescMetadata(
      const PerfGroupDescMetadata& metadata,
      PerfDataProto_PerfGroupDescMetadata* proto_metadata) const;
  bool DeserializeGroupDescMetadata(
      const PerfDataProto_PerfGroupDescMetadata& proto_metadata,
      PerfGroupDescMetadata* metadata) const;
 
  static void SerializeParserStats(const PerfEventStats& stats,
                                   PerfDataProto* perf_data_proto);
  static void DeserializeParserStats(const PerfDataProto& perf_data_proto,
                                     PerfEventStats* stats);
 
  // Instantiate a new PerfSampleReader with the given attr type. If an old one
  // exists for that attr type, it is discarded.
  void CreateSampleInfoReader(const PerfFileAttr& event_attr,
                              bool read_cross_endian);
 
  bool SampleInfoReaderAvailable() const {
    return !sample_info_reader_map_.empty();
  }
 
 private:
  // Special values for the event/other_event_id_pos_ fields.
  enum EventIdPosition {
    Uninitialized = -2,
    NotPresent = -1,
  };
 
  // Given a perf_event_attr, determines the offset of the ID field within an
  // event, relative to the start of sample info within an event. All attrs must
  // have the same ID field offset.
  void UpdateEventIdPositions(const struct perf_event_attr& attr);
 
  // Do non-SAMPLE events have a sample_id? Reflects the value of
  // sample_id_all in the first attr, which should be consistent accross all
  // attrs.
  bool SampleIdAll() const;
 
  // Find the event id in the event, and returns the corresponding
  // SampleInfoReader. Returns nullptr if a SampleInfoReader could not be found.
  const SampleInfoReader* GetSampleInfoReaderForEvent(
      const event_t& event) const;
 
  // Returns the SampleInfoReader associated with the given perf event ID, or
  // nullptr if none exists. |id| == 0 means there is no attr ID for each event
  // that associates it with a particular SampleInfoReader, in which case the
  // first available SampleInfoReader is returned.
  const SampleInfoReader* GetSampleInfoReaderForId(uint64_t id) const;
 
  // Reads the sample info fields from |event| into |sample_info|. If more than
  // one type of perf event attr is present, will pick the correct one. Also
  // returns a bitfield of available sample info fields for the attr, in
  // |sample_type|.
  // Returns true if successfully read.
  bool ReadPerfSampleInfoAndType(const event_t& event, perf_sample* sample_info,
                                 uint64_t* sample_type) const;
 
  bool SerializeKernelEvent(const event_t& event,
                            PerfDataProto_PerfEvent* event_proto) const;
  bool SerializeUserEvent(const event_t& event,
                          PerfDataProto_PerfEvent* event_proto) const;
 
  bool DeserializeKernelEvent(const PerfDataProto_PerfEvent& event_proto,
                              event_t* event) const;
  bool DeserializeUserEvent(const PerfDataProto_PerfEvent& event_proto,
                            event_t* event) const;
 
  // For SAMPLE events, the position of the sample id,
  // Or EventIdPosition::NotPresent if neither PERF_SAMPLE_ID(ENTIFIER) are set.
  // (Corresponds to evsel->id_pos in perf)
  ssize_t sample_event_id_pos_ = EventIdPosition::Uninitialized;
  // For non-SAMPLE events, the position of the sample id, counting backwards
  // from the end of the event.
  // Or EventIdPosition::NotPresent if neither PERF_SAMPLE_ID(ENTIFIER) are set.
  // (Corresponds to evsel->is_pos in perf)
  ssize_t other_event_id_pos_ = EventIdPosition::Uninitialized;
 
  // For each perf event attr ID, there is a SampleInfoReader to read events of
  // the associated perf attr type.
  std::map<uint64_t, std::unique_ptr<SampleInfoReader>> sample_info_reader_map_;
 
  DISALLOW_COPY_AND_ASSIGN(PerfSerializer);
};
 
}  // namespace quipper
 
#endif  // CHROMIUMOS_WIDE_PROFILING_PERF_SERIALIZER_H_