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