// 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_