15d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Copyright (c) 2014 The Chromium OS Authors. All rights reserved.
25d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Use of this source code is governed by a BSD-style license that can be
35d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// found in the LICENSE file.
45d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
55d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#ifndef CHROMIUMOS_WIDE_PROFILING_TEST_PERF_DATA_H_
65d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#define CHROMIUMOS_WIDE_PROFILING_TEST_PERF_DATA_H_
75d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
85d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include <memory>
9bebe6ba1a6372c47fccde03567c28c07f4d1a3dflakshmana#include <ostream>
105d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include <vector>
115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "binary_data_utils.h"
135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "compat/string.h"
145d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#include "kernel/perf_internals.h"
155d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
165d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmananamespace quipper {
175d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmananamespace testing {
185d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Union for punning 32-bit words into a 64-bit word.
205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaunion PunU32U64 {
215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  u32 v32[2];
225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  u64 v64;
235d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
245d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
255d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass StreamWriteable {
265d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
275d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  StreamWriteable() : is_cross_endian_(false) {}
285d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  virtual ~StreamWriteable() {}
295d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
305d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  virtual void WriteTo(std::ostream* out) const = 0;
315d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
325d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  virtual StreamWriteable& WithCrossEndianness(bool value) {
335d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    is_cross_endian_ = value;
345d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return *this;
355d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
365d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
375d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // Do not call MaybeSwap() directly. The syntax of test data structure
385d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // initialization makes data sizes ambiguous, so these force the caller to
395d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // explicitly specify value sizes.
403fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  uint16_t MaybeSwap16(uint16_t value) const { return MaybeSwap(value); }
413fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  uint32_t MaybeSwap32(uint32_t value) const { return MaybeSwap(value); }
423fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  uint64_t MaybeSwap64(uint64_t value) const { return MaybeSwap(value); }
435d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
445d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana protected:
455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // Derived classes can call this to determine the cross-endianness. However,
465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // the actual implementation of cross-endianness is up to the derived class,
475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // if it supports it at all.
483fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  bool is_cross_endian() const { return is_cross_endian_; }
495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana private:
515d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  template <typename T>
525d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  T MaybeSwap(T value) const {
533fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    if (is_cross_endian()) ByteSwap(&value);
545d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return value;
555d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
565d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
575d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  bool is_cross_endian_;
585d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
595d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
605d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Normal mode header
615d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExamplePerfDataFileHeader : public StreamWriteable {
625d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
635d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  typedef ExamplePerfDataFileHeader SelfT;
64bebe6ba1a6372c47fccde03567c28c07f4d1a3dflakshmana  explicit ExamplePerfDataFileHeader(const unsigned long features);
655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
665d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SelfT& WithAttrIdsCount(size_t n);
675d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SelfT& WithAttrCount(size_t n);
685d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SelfT& WithDataSize(size_t sz);
695d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
705d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // Used for testing compatibility w.r.t. sizeof(perf_event_attr)
715d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SelfT& WithCustomPerfEventAttrSize(size_t sz);
725d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
733fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  const struct perf_file_header& header() const { return header_; }
745d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
755d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  u64 data_end_offset() const {
765d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return header_.data.offset + header_.data.size;
775d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
783fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  ssize_t data_end() const { return static_cast<ssize_t>(data_end_offset()); }
795d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
805d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override;
815d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
825d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana protected:
835d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  struct perf_file_header header_;
845d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  size_t attr_ids_count_ = 0;
855d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
865d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana private:
875d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void UpdateSectionOffsets();
885d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
895d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
905d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces the pipe-mode file header.
915d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExamplePipedPerfDataFileHeader : public StreamWriteable {
925d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
935d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  ExamplePipedPerfDataFileHeader() {}
945d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override;
955d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
965d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
975d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces a PERF_RECORD_HEADER_ATTR event with struct perf_event_attr
985d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// describing a hardware event. The sample_type mask and the sample_id_all
995d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// bit are paramatized.
1005d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExamplePerfEventAttrEvent_Hardware : public StreamWriteable {
1015d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
1025d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  typedef ExamplePerfEventAttrEvent_Hardware SelfT;
1035d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  explicit ExamplePerfEventAttrEvent_Hardware(u64 sample_type,
1045d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                                              bool sample_id_all)
1055d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      : attr_size_(sizeof(perf_event_attr)),
1065d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        sample_type_(sample_type),
1075d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        read_format_(0),
1085d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        sample_id_all_(sample_id_all),
1093fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        config_(0) {}
1103fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  SelfT& WithConfig(u64 config) {
1113fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    config_ = config;
1123fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    return *this;
1133fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  }
1143fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  SelfT& WithAttrSize(u32 size) {
1153fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    attr_size_ = size;
1163fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    return *this;
1173fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  }
1183fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  SelfT& WithReadFormat(u64 format) {
1193fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    read_format_ = format;
1203fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    return *this;
1215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
1225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
1233fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  SelfT& WithId(u64 id) {
1243fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    ids_.push_back(id);
1253fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    return *this;
1263fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  }
1275d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SelfT& WithIds(std::initializer_list<u64> ids) {
1285d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    ids_.insert(ids_.end(), ids.begin(), ids.end());
1295d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return *this;
1305d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
1315d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override;
1325d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
1335d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana private:
1345d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  u32 attr_size_;
1355d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u64 sample_type_;
1365d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  u64 read_format_;
1375d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const bool sample_id_all_;
1385d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  u64 config_;
1395d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  std::vector<u64> ids_;
1405d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
1415d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
1425d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass AttrIdsSection : public StreamWriteable {
1435d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
1445d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  explicit AttrIdsSection(size_t initial_offset) : offset_(initial_offset) {}
1455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
1465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  perf_file_section AddId(u64 id) { return AddIds({id}); }
1475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  perf_file_section AddIds(std::initializer_list<u64> ids) {
1485d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    ids_.insert(ids_.end(), ids.begin(), ids.end());
1495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    perf_file_section s = {
1503fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        .offset = offset_,
1513fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        .size = ids.size() * sizeof(decltype(ids)::value_type),
1525d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    };
1535d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    offset_ += s.size;
1545d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return s;
1555d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
1565d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override;
1573fa0a5f4b88119fac65f86971738ea0202797b6elakshmana
1585d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana private:
1595d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  u64 offset_;
1605d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  std::vector<u64> ids_;
1615d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
1625d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
1635d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces a struct perf_file_attr with a perf_event_attr describing a
1645d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// hardware event.
1655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExamplePerfFileAttr_Hardware : public StreamWriteable {
1665d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
1675d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  typedef ExamplePerfFileAttr_Hardware SelfT;
1685d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  explicit ExamplePerfFileAttr_Hardware(u64 sample_type, bool sample_id_all)
1695d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      : attr_size_(sizeof(perf_event_attr)),
1705d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        sample_type_(sample_type),
1715d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        sample_id_all_(sample_id_all),
1725d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        config_(0),
1733fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        ids_section_({.offset = MaybeSwap64(104), .size = MaybeSwap64(0)}) {}
1743fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  SelfT& WithAttrSize(u32 size) {
1753fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    attr_size_ = size;
1763fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    return *this;
1773fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  }
1783fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  SelfT& WithConfig(u64 config) {
1793fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    config_ = config;
1803fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    return *this;
1815d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
1825d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SelfT& WithIds(const perf_file_section& section) {
1835d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    ids_section_ = section;
1845d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return *this;
1855d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
1865d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override;
1873fa0a5f4b88119fac65f86971738ea0202797b6elakshmana
1885d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana private:
1895d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  u32 attr_size_;
1905d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u64 sample_type_;
1915d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const bool sample_id_all_;
1925d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  u64 config_;
1935d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  perf_file_section ids_section_;
1945d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
1955d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
1965d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces a struct perf_file_attr with a perf_event_attr describing a
1975d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// tracepoint event.
1985d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExamplePerfFileAttr_Tracepoint : public StreamWriteable {
1995d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
2005d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  explicit ExamplePerfFileAttr_Tracepoint(const u64 tracepoint_event_id)
2015d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      : tracepoint_event_id_(tracepoint_event_id) {}
2025d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override;
2033fa0a5f4b88119fac65f86971738ea0202797b6elakshmana
2045d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana private:
2055d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u64 tracepoint_event_id_;
2065d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
2075d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
2085d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces a sample field array that can be used with either SAMPLE events
2095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// or as the sample_id of another event.
2105d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// NB: This class simply places the fields in the order called. It does not
2115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// enforce that they are in the correct order, or match the sample type.
2125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// See enum perf_event_type in perf_event.h.
2135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass SampleInfo {
2145d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
2155d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SampleInfo& Ip(u64 ip) { return AddField(ip); }
2165d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SampleInfo& Tid(u32 pid, u32 tid) {
2175d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return AddField(PunU32U64{.v32 = {pid, tid}}.v64);
2185d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
2195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SampleInfo& Tid(u32 pid) {
2205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return AddField(PunU32U64{.v32 = {pid, pid}}.v64);
2215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
2225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SampleInfo& Time(u64 time) { return AddField(time); }
2235d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SampleInfo& Id(u64 id) { return AddField(id); }
2245d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SampleInfo& BranchStack_nr(u64 nr) { return AddField(nr); }
2255d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SampleInfo& BranchStack_lbr(u64 from, u64 to, u64 flags) {
2265d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    AddField(from);
2275d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    AddField(to);
2285d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    AddField(flags);
2295d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return *this;
2305d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
2315d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
2325d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const char* data() const {
2333fa0a5f4b88119fac65f86971738ea0202797b6elakshmana    return reinterpret_cast<const char*>(fields_.data());
2345d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
2355d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const size_t size() const {
2365d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return fields_.size() * sizeof(decltype(fields_)::value_type);
2375d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
2385d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
2395d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana private:
2405d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SampleInfo& AddField(u64 value) {
2415d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    fields_.push_back(value);
2425d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return *this;
2435d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
2445d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
2455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  std::vector<u64> fields_;
2465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
2475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
2485d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces a PERF_RECORD_MMAP event with the given file and mapping.
2495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExampleMmapEvent : public StreamWriteable {
2505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
2515d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  ExampleMmapEvent(u32 pid, u64 start, u64 len, u64 pgoff, string filename,
2525d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                   const SampleInfo& sample_id)
2535d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      : pid_(pid),
2545d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        start_(start),
2555d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        len_(len),
2565d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        pgoff_(pgoff),
2575d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        filename_(filename),
2583fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        sample_id_(sample_id) {}
2595d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  size_t GetSize() const;
2605d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override;
2613fa0a5f4b88119fac65f86971738ea0202797b6elakshmana
2625d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana private:
2635d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u32 pid_;
2645d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u64 start_;
2655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u64 len_;
2665d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u64 pgoff_;
2675d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const string filename_;
2685d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const SampleInfo sample_id_;
2695d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
2705d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
2715d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces a PERF_RECORD_MMAP2 event with the given file and mapping.
2725d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExampleMmap2Event : public StreamWriteable {
2735d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
2745d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  typedef ExampleMmap2Event SelfT;
2755d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // pid is used as both pid and tid.
2763fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  ExampleMmap2Event(u32 pid, u64 start, u64 len, u64 pgoff, string filename,
2773fa0a5f4b88119fac65f86971738ea0202797b6elakshmana                    const SampleInfo& sample_id)
2785d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      : ExampleMmap2Event(pid, pid, start, len, pgoff, filename, sample_id) {}
2795d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  ExampleMmap2Event(u32 pid, u32 tid, u64 start, u64 len, u64 pgoff,
2805d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                    string filename, const SampleInfo& sample_id)
2815d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      : pid_(pid),
2825d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        tid_(tid),
2835d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        start_(start),
2845d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        len_(len),
2855d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        pgoff_(pgoff),
2865d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        maj_(6),
2875d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        min_(7),
2885d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        ino_(8),
2895d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        filename_(filename),
2903fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        sample_id_(sample_id) {}
2915d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
2925d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  SelfT& WithDeviceInfo(u32 maj, u32 min, u64 ino) {
2935d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    maj_ = maj;
2945d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    min_ = min;
2955d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    ino_ = ino;
2965d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return *this;
2975d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
2985d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
2995d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override;
3005d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
3015d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana private:
3025d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u32 pid_;
3035d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u32 tid_;
3045d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u64 start_;
3055d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u64 len_;
3065d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u64 pgoff_;
3075d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  u32 maj_;
3085d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  u32 min_;
3095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  u64 ino_;
3105d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const string filename_;
3115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const SampleInfo sample_id_;
3125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
3135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
3145d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces a PERF_RECORD_FORK or PERF_RECORD_EXIT event.
3155d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Cannot be instantiated directly; use a derived class.
3165d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExampleForkExitEvent : public StreamWriteable {
3175d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
3185d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override;
3193fa0a5f4b88119fac65f86971738ea0202797b6elakshmana
3205d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana protected:
3215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  ExampleForkExitEvent(u32 type, u32 pid, u32 ppid, u32 tid, u32 ptid, u64 time,
3225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                       const SampleInfo& sample_id)
3235d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      : type_(type),
3243fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        pid_(pid),
3253fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        ppid_(ppid),
3263fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        tid_(tid),
3273fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        ptid_(ptid),
3285d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        time_(time),
3295d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana        sample_id_(sample_id) {}
3303fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  const u32 type_;  // Either PERF_RECORD_FORK or PERF_RECORD_EXIT.
3315d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana private:
3325d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u32 pid_;
3335d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u32 ppid_;
3345d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u32 tid_;
3355d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u32 ptid_;
3365d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const u64 time_;
3375d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const SampleInfo sample_id_;
3385d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
3395d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
3405d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces a PERF_RECORD_FORK event.
3415d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExampleForkEvent : public ExampleForkExitEvent {
3425d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
3435d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  ExampleForkEvent(u32 pid, u32 ppid, u32 tid, u32 ptid, u64 time,
3445d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                   const SampleInfo& sample_id)
3455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      : ExampleForkExitEvent(PERF_RECORD_FORK, pid, ppid, tid, ptid, time,
3465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                             sample_id) {}
3475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
3485d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
3495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces a PERF_RECORD_EXIT event.
3505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExampleExitEvent : public ExampleForkExitEvent {
3515d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
3525d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  ExampleExitEvent(u32 pid, u32 ppid, u32 tid, u32 ptid, u64 time,
3535d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                   const SampleInfo& sample_id)
3545d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      : ExampleForkExitEvent(PERF_RECORD_EXIT, pid, ppid, tid, ptid, time,
3555d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana                             sample_id) {}
3565d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
3575d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
3585d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces the PERF_RECORD_FINISHED_ROUND event. This event is just a header.
3595d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass FinishedRoundEvent : public StreamWriteable {
3605d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
3615d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override;
3625d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
3635d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
3645d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces a simple PERF_RECORD_SAMPLE event with the given sample info.
3655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// NB: The sample_info must match the sample_type of the relevant attr.
3665d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExamplePerfSampleEvent : public StreamWriteable {
3675d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
3685d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  explicit ExamplePerfSampleEvent(const SampleInfo& sample_info)
3693fa0a5f4b88119fac65f86971738ea0202797b6elakshmana      : sample_info_(sample_info) {}
3705d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  size_t GetSize() const;
3715d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override;
3723fa0a5f4b88119fac65f86971738ea0202797b6elakshmana
3735d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana private:
3745d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const SampleInfo sample_info_;
3755d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
3765d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
3775d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExamplePerfSampleEvent_BranchStack : public ExamplePerfSampleEvent {
3785d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
3795d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  ExamplePerfSampleEvent_BranchStack();
3805d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  static const size_t kEventSize;
3815d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
3825d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
3835d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces a struct sample_event matching ExamplePerfFileAttr_Tracepoint.
3845d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExamplePerfSampleEvent_Tracepoint : public StreamWriteable {
3855d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
3865d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  ExamplePerfSampleEvent_Tracepoint() {}
3875d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override;
3885d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  static const size_t kEventSize;
3895d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
3905d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
3915d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces a struct perf_file_section suitable for use in the metadata index.
3925d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass MetadataIndexEntry : public StreamWriteable {
3935d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
3945d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  MetadataIndexEntry(u64 offset, u64 size)
3953fa0a5f4b88119fac65f86971738ea0202797b6elakshmana      : index_entry_{.offset = offset, .size = size} {}
3965d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override {
3975d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    struct perf_file_section entry = {
3983fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        .offset = MaybeSwap64(index_entry_.offset),
3993fa0a5f4b88119fac65f86971738ea0202797b6elakshmana        .size = MaybeSwap64(index_entry_.size),
4005d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    };
4015d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    out->write(reinterpret_cast<const char*>(&entry), sizeof(entry));
4025d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
4033fa0a5f4b88119fac65f86971738ea0202797b6elakshmana
4045d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
4055d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const perf_file_section index_entry_;
4065d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
4075d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4085d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces sample string metadata, and corresponding metadata index entry.
4095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExampleStringMetadata : public StreamWriteable {
4105d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
4115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // The input string gets zero-padded/truncated to |kStringAlignSize| bytes if
4125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // it is shorter/longer, respectively.
4135d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  explicit ExampleStringMetadata(const string& data, size_t offset)
4143fa0a5f4b88119fac65f86971738ea0202797b6elakshmana      : data_(data), index_entry_(offset, sizeof(u32) + kStringAlignSize) {
4155d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    data_.resize(kStringAlignSize);
4165d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
4175d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override;
4185d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4195d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  const MetadataIndexEntry& index_entry() { return index_entry_; }
4203fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  size_t size() const { return sizeof(u32) + data_.size(); }
4215d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4225d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  StreamWriteable& WithCrossEndianness(bool value) override {
4235d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    // Set index_entry_'s endianness since it is owned by this class.
4245d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    index_entry_.WithCrossEndianness(value);
4255d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    return StreamWriteable::WithCrossEndianness(value);
4265d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
4275d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4285d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana private:
4295d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  string data_;
4305d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  MetadataIndexEntry index_entry_;
4315d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4325d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  static const int kStringAlignSize = 64;
4335d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
4345d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4355d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces sample string metadata event for piped mode.
4365d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExampleStringMetadataEvent : public StreamWriteable {
4375d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
4385d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  // The input string gets aligned to |kStringAlignSize|.
4395d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  explicit ExampleStringMetadataEvent(u32 type, const string& data)
4405d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      : type_(type), data_(data) {
4415d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    data_.resize(kStringAlignSize);
4425d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  }
4435d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  void WriteTo(std::ostream* out) const override;
4445d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4455d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana private:
4465d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  u32 type_;
4475d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  string data_;
4485d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4495d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  static const int kStringAlignSize = 64;
4505d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
4515d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4525d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana// Produces sample tracing metadata, and corresponding metadata index entry.
4535d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmanaclass ExampleTracingMetadata {
4545d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana public:
4555d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  class Data : public StreamWriteable {
4565d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana   public:
4575d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    static const string kTraceMetadata;
4585d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4595d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    explicit Data(ExampleTracingMetadata* parent) : parent_(parent) {}
4605d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4615d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    const string& value() const { return kTraceMetadata; }
4625d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4635d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    void WriteTo(std::ostream* out) const override;
4645d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4655d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana   private:
4665d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana    ExampleTracingMetadata* parent_;
4675d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  };
4685d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4695d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  explicit ExampleTracingMetadata(size_t offset)
4705d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana      : data_(this), index_entry_(offset, data_.value().size()) {}
4715d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4723fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  const Data& data() { return data_; }
4733fa0a5f4b88119fac65f86971738ea0202797b6elakshmana  const MetadataIndexEntry& index_entry() { return index_entry_; }
4745d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
4755d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana private:
4765d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  friend class Data;
4775d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  Data data_;
4785d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana  MetadataIndexEntry index_entry_;
4795d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana};
4805d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
48198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana// Produces a PERF_RECORD_AUXTRACE event.
48298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmanaclass ExampleAuxtraceEvent : public StreamWriteable {
48398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana public:
48498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  ExampleAuxtraceEvent(u64 size, u64 offset, u64 reference, u32 idx, u32 tid,
48598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana                       u32 cpu, u32 reserved, string trace_data)
48698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana      : size_(size),
48798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana        offset_(offset),
48898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana        reference_(reference),
48998ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana        idx_(idx),
49098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana        tid_(tid),
49198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana        cpu_(cpu),
49298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana        reserved_(reserved),
49398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana        trace_data_(std::move(trace_data)) {}
49498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  size_t GetSize() const;
49598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  size_t GetTraceSize() const;
49698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  void WriteTo(std::ostream* out) const override;
49798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
49898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana private:
49998ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  const u64 size_;
50098ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  const u64 offset_;
50198ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  const u64 reference_;
50298ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  const u32 idx_;
50398ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  const u32 tid_;
50498ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  const u32 cpu_;
50598ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  const u32 reserved_;
50698ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana  const string trace_data_;
50798ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana};
50898ed13a0f0e73766338cb486abe19e4b257ceb60lakshmana
5095d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}  // namespace testing
5105d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana}  // namespace quipper
5115d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana
5125d24e0b95af51d6d4fc3fc2c20ed54193fbcd4b9lakshmana#endif  // CHROMIUMOS_WIDE_PROFILING_TEST_PERF_DATA_H_
513