Home | History | Annotate | Line # | Download | only in xray
      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