1 // Copyright 2017 The Fuchsia 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 //
6 // Field declarations for the trace record format.
7 //
8
9 #pragma once
10
11 #include <trace-engine/types.h>
12
13 #ifdef __cplusplus
14
15 #include <type_traits>
16
17 namespace trace {
18
Pad(size_t size)19 inline constexpr size_t Pad(size_t size) {
20 return size + ((8 - (size & 7)) & 7);
21 }
22
BytesToWords(size_t num_bytes)23 inline constexpr size_t BytesToWords(size_t num_bytes) {
24 return Pad(num_bytes) / sizeof(uint64_t);
25 }
26
WordsToBytes(size_t num_words)27 inline constexpr size_t WordsToBytes(size_t num_words) {
28 return num_words * sizeof(uint64_t);
29 }
30
31 // Casts an enum's value to its underlying type.
32 template <typename T>
ToUnderlyingType(T value)33 inline constexpr typename std::underlying_type<T>::type ToUnderlyingType(T value) {
34 return static_cast<typename std::underlying_type<T>::type>(value);
35 }
36
37 // Describes the layout of a bit-field packed into a 64-bit word.
38 template <size_t begin, size_t end>
39 struct Field {
40 static_assert(begin < sizeof(uint64_t) * 8, "begin is out of bounds");
41 static_assert(end < sizeof(uint64_t) * 8, "end is out of bounds");
42 static_assert(begin <= end, "begin must not be larger than end");
43 static_assert(end - begin + 1 < 64, "must be a part of a word, not a whole word");
44
45 static constexpr uint64_t kMask = (uint64_t(1) << (end - begin + 1)) - 1;
46
MakeField47 static constexpr uint64_t Make(uint64_t value) { return value << begin; }
48
49 template <typename U>
GetField50 static constexpr U Get(uint64_t word) {
51 return static_cast<U>((word >> begin) & kMask);
52 }
53
SetField54 static constexpr void Set(uint64_t& word, uint64_t value) {
55 word = (word & ~(kMask << begin)) | (value << begin);
56 }
57 };
58
59 struct ArgumentFields {
60 using Type = Field<0, 3>;
61 using ArgumentSize = Field<4, 15>;
62 using NameRef = Field<16, 31>;
63 };
64
65 struct Int32ArgumentFields : ArgumentFields {
66 using Value = Field<32, 63>;
67 };
68
69 struct Uint32ArgumentFields : ArgumentFields {
70 using Value = Field<32, 63>;
71 };
72
73 struct StringArgumentFields : ArgumentFields {
74 using Index = Field<32, 47>;
75 };
76
77 struct RecordFields {
78 static constexpr size_t kMaxRecordSizeWords = 0xfff;
79 static constexpr size_t kMaxRecordSizeBytes = WordsToBytes(kMaxRecordSizeWords);
80
81 using Type = Field<0, 3>;
82 using RecordSize = Field<4, 15>;
83 };
84
85 struct MetadataRecordFields : RecordFields {
86 using MetadataType = Field<16, 19>;
87 };
88
89 struct ProviderInfoMetadataRecordFields : MetadataRecordFields {
90 static constexpr size_t kMaxNameLength = 0xff;
91
92 using Id = Field<20, 51>;
93 using NameLength = Field<52, 59>;
94 };
95
96 struct ProviderSectionMetadataRecordFields : MetadataRecordFields {
97 using Id = Field<20, 51>;
98 };
99
100 struct ProviderEventMetadataRecordFields : MetadataRecordFields {
101 using Id = Field<20, 51>;
102 using Event = Field<52, 55>;
103 };
104
105 using InitializationRecordFields = RecordFields;
106
107 struct StringRecordFields : RecordFields {
108 using StringIndex = Field<16, 30>;
109 using StringLength = Field<32, 46>;
110 };
111
112 struct ThreadRecordFields : RecordFields {
113 using ThreadIndex = Field<16, 23>;
114 };
115
116 struct EventRecordFields : RecordFields {
117 using EventType = Field<16, 19>;
118 using ArgumentCount = Field<20, 23>;
119 using ThreadRef = Field<24, 31>;
120 using CategoryStringRef = Field<32, 47>;
121 using NameStringRef = Field<48, 63>;
122 };
123
124 struct BlobRecordFields : RecordFields {
125 using NameStringRef = Field<16, 31>;
126 using BlobSize = Field<32, 46>;
127 using BlobType = Field<48, 55>;
128 };
129
130 struct KernelObjectRecordFields : RecordFields {
131 using ObjectType = Field<16, 23>;
132 using NameStringRef = Field<24, 39>;
133 using ArgumentCount = Field<40, 43>;
134 };
135
136 struct ContextSwitchRecordFields : RecordFields {
137 using CpuNumber = Field<16, 23>;
138 using OutgoingThreadState = Field<24, 27>;
139 using OutgoingThreadRef = Field<28, 35>;
140 using IncomingThreadRef = Field<36, 43>;
141 using OutgoingThreadPriority = Field<44, 51>;
142 using IncomingThreadPriority = Field<52, 59>;
143 };
144
145 struct LogRecordFields : RecordFields {
146 static constexpr size_t kMaxMessageLength = 0x7fff;
147 using LogMessageLength = Field<16, 30>;
148 using ThreadRef = Field<32, 39>;
149 };
150
151 } // namespace trace
152
153 #endif // __cplusplus
154