1 // Copyright 2016 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_DATA_UTILS_H_
6 #define CHROMIUMOS_WIDE_PROFILING_PERF_DATA_UTILS_H_
7
8 #include <stddef.h> // for size_t
9 #include <stdlib.h> // for free()
10
11 #include <memory>
12
13 #include "binary_data_utils.h" // for Align<T>
14 #include "compat/string.h"
15 #include "kernel/perf_internals.h"
16
17 namespace quipper {
18
19 class PerfDataProto_PerfEvent;
20 class PerfDataProto_SampleInfo;
21
22 // Based on kernel/perf_internals.h
23 const size_t kBuildIDArraySize = 20;
24 const size_t kBuildIDStringLength = kBuildIDArraySize * 2;
25
26 // Used by malloced_unique_ptr.
27 struct FreeDeleter {
operatorFreeDeleter28 inline void operator()(void* pointer) { free(pointer); }
29 };
30
31 // A modified version of std::unique_ptr that holds a pointer allocated by
32 // malloc or its cousins rather than by new. Calls free() to free the pointer
33 // when it is destroyed.
34 template <typename T>
35 using malloced_unique_ptr = std::unique_ptr<T, FreeDeleter>;
36
37 // Allocate |size| bytes of heap memory using calloc, returning the allocated
38 // memory as the variable-sized type event_t.
39 event_t* CallocMemoryForEvent(size_t size);
40
41 // Reallocate |event| which was previously allocated by CallocMemoryForEvent()
42 // to memory with a new size |new_size|.
43 event_t* ReallocMemoryForEvent(event_t* event, size_t new_size);
44
45 // Allocate |size| bytes of heap memory using calloc, returning the allocated
46 // memory as the variable-sized build ID type.
47 build_id_event* CallocMemoryForBuildID(size_t size);
48
49 // In perf data, strings are packed into the smallest number of 8-byte blocks
50 // possible, including a null terminator.
51 // e.g.
52 // "0123" -> 5 bytes -> packed into 8 bytes
53 // "0123456" -> 8 bytes -> packed into 8 bytes
54 // "01234567" -> 9 bytes -> packed into 16 bytes
55 // "0123456789abcd" -> 15 bytes -> packed into 16 bytes
56 // "0123456789abcde" -> 16 bytes -> packed into 16 bytes
57 // "0123456789abcdef" -> 17 bytes -> packed into 24 bytes
58 //
59 // Returns the size of the 8-byte-aligned memory for storing |string|.
GetUint64AlignedStringLength(const string & str)60 inline size_t GetUint64AlignedStringLength(const string& str) {
61 return Align<uint64_t>(str.size() + 1);
62 }
63
64 // Makes |build_id| fit the perf format, by either truncating it or adding
65 // zeroes to the end so that it has length kBuildIDStringLength.
66 void PerfizeBuildIDString(string* build_id);
67
68 // Changes |build_id| to the best guess of what the build id was before going
69 // through perf. Specifically, it keeps removing trailing sequences of four
70 // zero bytes (or eight '0' characters) until there are no more such sequences,
71 // or the build id would be empty if the process were repeated.
72 void TrimZeroesFromBuildIDString(string* build_id);
73
74 // If |event| is not of type PERF_RECORD_SAMPLE, returns the SampleInfo field
75 // within it. Otherwise returns nullptr.
76 const PerfDataProto_SampleInfo* GetSampleInfoForEvent(
77 const PerfDataProto_PerfEvent& event);
78
79 // Returns the correct |sample_time_ns| field of a PerfEvent.
80 uint64_t GetTimeFromPerfEvent(const PerfDataProto_PerfEvent& event);
81
82 } // namespace quipper
83
84 #endif // CHROMIUMOS_WIDE_PROFILING_PERF_DATA_UTILS_H_
85