xref: /netbsd-src/sys/external/bsd/compiler_rt/dist/include/xray/xray_records.h (revision a7c257b03e4462df2b1020128fb82716512d7856)
1 //===-- xray_records.h ------------------------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of XRay, a dynamic runtime instrumentation system.
11 //
12 // This header exposes some record types useful for the XRay in-memory logging
13 // implementation.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #ifndef XRAY_XRAY_RECORDS_H
18 #define XRAY_XRAY_RECORDS_H
19 
20 #include <cstdint>
21 
22 namespace __xray {
23 
24 enum FileTypes {
25   NAIVE_LOG = 0,
26   FDR_LOG = 1,
27 };
28 
29 // FDR mode use of the union field in the XRayFileHeader.
30 struct alignas(16) FdrAdditionalHeaderData {
31   uint64_t ThreadBufferSize;
32 };
33 
34 static_assert(sizeof(FdrAdditionalHeaderData) == 16,
35               "FdrAdditionalHeaderData != 16 bytes");
36 
37 // This data structure is used to describe the contents of the file. We use this
38 // for versioning the supported XRay file formats.
39 struct alignas(32) XRayFileHeader {
40   uint16_t Version = 0;
41 
42   // The type of file we're writing out. See the FileTypes enum for more
43   // information. This allows different implementations of the XRay logging to
44   // have different files for different information being stored.
45   uint16_t Type = 0;
46 
47   // What follows are a set of flags that indicate useful things for when
48   // reading the data in the file.
49   bool ConstantTSC : 1;
50   bool NonstopTSC : 1;
51 
52   // The frequency by which TSC increases per-second.
53   alignas(8) uint64_t CycleFrequency = 0;
54 
55   union {
56     char FreeForm[16];
57     // The current civiltime timestamp, as retrieved from 'clock_gettime'. This
58     // allows readers of the file to determine when the file was created or
59     // written down.
60     struct timespec TS;
61 
62     struct FdrAdditionalHeaderData FdrData;
63   };
64 } __attribute__((packed));
65 
66 static_assert(sizeof(XRayFileHeader) == 32, "XRayFileHeader != 32 bytes");
67 
68 enum RecordTypes {
69   NORMAL = 0,
70   ARG_PAYLOAD = 1,
71 };
72 
73 struct alignas(32) XRayRecord {
74   // This is the type of the record being written. We use 16 bits to allow us to
75   // treat this as a discriminant, and so that the first 4 bytes get packed
76   // properly. See RecordTypes for more supported types.
77   uint16_t RecordType = RecordTypes::NORMAL;
78 
79   // The CPU where the thread is running. We assume number of CPUs <= 256.
80   uint8_t CPU = 0;
81 
82   // The type of the event. One of the following:
83   //   ENTER = 0
84   //   EXIT = 1
85   //   TAIL_EXIT = 2
86   //   ENTER_ARG = 3
87   uint8_t Type = 0;
88 
89   // The function ID for the record.
90   int32_t FuncId = 0;
91 
92   // Get the full 8 bytes of the TSC when we get the log record.
93   uint64_t TSC = 0;
94 
95   // The thread ID for the currently running thread.
96   uint32_t TId = 0;
97 
98   // The ID of process that is currently running
99   uint32_t PId = 0;
100 
101   // Use some bytes in the end of the record for buffers.
102   char Buffer[8] = {};
103 } __attribute__((packed));
104 
105 static_assert(sizeof(XRayRecord) == 32, "XRayRecord != 32 bytes");
106 
107 struct alignas(32) XRayArgPayload {
108   // We use the same 16 bits as a discriminant for the records in the log here
109   // too, and so that the first 4 bytes are packed properly.
110   uint16_t RecordType = RecordTypes::ARG_PAYLOAD;
111 
112   // Add a few bytes to pad.
113   uint8_t Padding[2] = {};
114 
115   // The function ID for the record.
116   int32_t FuncId = 0;
117 
118   // The thread ID for the currently running thread.
119   uint32_t TId = 0;
120 
121   // The ID of process that is currently running
122   uint32_t PId = 0;
123 
124   // The argument payload.
125   uint64_t Arg = 0;
126 
127   // The rest of this record ought to be left as padding.
128   uint8_t TailPadding[8] = {};
129 } __attribute__((packed));
130 
131 static_assert(sizeof(XRayArgPayload) == 32, "XRayArgPayload != 32 bytes");
132 
133 } // namespace __xray
134 
135 #endif // XRAY_XRAY_RECORDS_H
136