149 lines · c
1//===-- PerfContextSwitchDecoder.h --======----------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_PERFCONTEXTSWITCHDECODER_H10#define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_PERFCONTEXTSWITCHDECODER_H11 12#include "lldb/Utility/TraceIntelPTGDBRemotePackets.h"13#include "lldb/lldb-types.h"14#include "llvm/Support/Error.h"15#include <set>16#include <vector>17 18namespace lldb_private {19namespace trace_intel_pt {20 21/// This class indicates the time interval in which a thread was running22/// continuously on a cpu core.23struct ThreadContinuousExecution {24 25 /// In most cases both the start and end of a continuous execution can be26 /// accurately recovered from the context switch trace, but in some cases one27 /// of these endpoints might be guessed or not known at all, due to contention28 /// problems in the trace or because tracing was interrupted, e.g. with ioctl29 /// calls, which causes gaps in the trace. Because of that, we identify which30 /// situation we fall into with the following variants.31 enum class Variant {32 /// Both endpoints are known.33 Complete,34 /// The end is known and we have a lower bound for the start, i.e. the35 /// previous execution in the same cpu happens strictly before the hinted36 /// start.37 HintedStart,38 /// The start is known and we have an upper bound for the end, i.e. the next39 /// execution in the same cpu happens strictly after the hinted end.40 HintedEnd,41 /// We only know the start. This might be the last entry of a cpu trace.42 OnlyStart,43 /// We only know the end. This might be the first entry or a cpu trace.44 OnlyEnd,45 } variant;46 47 /// \return48 /// The lowest tsc that we are sure of, i.e. not hinted.49 uint64_t GetLowestKnownTSC() const;50 51 /// \return52 /// The known or hinted start tsc, or 0 if the variant is \a OnlyEnd.53 uint64_t GetStartTSC() const;54 55 /// \return56 /// The known or hinted end tsc, or max \a uint64_t if the variant is \a57 /// OnlyStart.58 uint64_t GetEndTSC() const;59 60 /// Constructors for the different variants of this object61 ///62 /// \{63 static ThreadContinuousExecution64 CreateCompleteExecution(lldb::cpu_id_t cpu_id, lldb::tid_t tid,65 lldb::pid_t pid, uint64_t start, uint64_t end);66 67 static ThreadContinuousExecution68 CreateHintedStartExecution(lldb::cpu_id_t cpu_id, lldb::tid_t tid,69 lldb::pid_t pid, uint64_t hinted_start,70 uint64_t end);71 72 static ThreadContinuousExecution73 CreateHintedEndExecution(lldb::cpu_id_t cpu_id, lldb::tid_t tid,74 lldb::pid_t pid, uint64_t start,75 uint64_t hinted_end);76 77 static ThreadContinuousExecution CreateOnlyEndExecution(lldb::cpu_id_t cpu_id,78 lldb::tid_t tid,79 lldb::pid_t pid,80 uint64_t end);81 82 static ThreadContinuousExecution83 CreateOnlyStartExecution(lldb::cpu_id_t cpu_id, lldb::tid_t tid,84 lldb::pid_t pid, uint64_t start);85 /// \}86 87 union {88 struct {89 uint64_t start;90 uint64_t end;91 } complete;92 struct {93 uint64_t start;94 } only_start;95 struct {96 uint64_t end;97 } only_end;98 /// The following 'hinted' structures are useful when there are contention99 /// problems in the trace100 struct {101 uint64_t hinted_start;102 uint64_t end;103 } hinted_start;104 struct {105 uint64_t start;106 uint64_t hinted_end;107 } hinted_end;108 } tscs;109 110 lldb::cpu_id_t cpu_id;111 lldb::tid_t tid;112 lldb::pid_t pid;113 114private:115 /// We keep this constructor private to force the usage of the static named116 /// constructors.117 ThreadContinuousExecution(lldb::cpu_id_t cpu_id, lldb::tid_t tid,118 lldb::pid_t pid)119 : cpu_id(cpu_id), tid(tid), pid(pid) {}120};121 122/// Decodes a context switch trace collected with perf_event_open.123///124/// \param[in] data125/// The context switch trace in binary format.126///127/// \param[i] cpu_id128/// The cpu_id where the trace were gotten from.129///130/// \param[in] tsc_conversion131/// The conversion values used to confert nanoseconds to TSC.132///133/// \return134/// A list of continuous executions recovered from the raw trace sorted by135/// time, or an \a llvm::Error if the data is malformed.136llvm::Expected<std::vector<ThreadContinuousExecution>>137DecodePerfContextSwitchTrace(llvm::ArrayRef<uint8_t> data,138 lldb::cpu_id_t cpu_id,139 const LinuxPerfZeroTscConversion &tsc_conversion);140 141llvm::Expected<std::vector<uint8_t>>142FilterProcessesFromContextSwitchTrace(llvm::ArrayRef<uint8_t> data,143 const std::set<lldb::pid_t> &pids);144 145} // namespace trace_intel_pt146} // namespace lldb_private147 148#endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_PERFCONTEXTSWITCHDECODER_H149