1 //===-- TraceIntelPTMultiCpuDecoder.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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #ifndef LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTMULTICPUDECODER_H 10 #define LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTMULTICPUDECODER_H 11 12 #include "LibiptDecoder.h" 13 #include "PerfContextSwitchDecoder.h" 14 #include "ThreadDecoder.h" 15 #include "forward-declarations.h" 16 17 namespace lldb_private { 18 namespace trace_intel_pt { 19 20 /// Class used to decode a multi-cpu Intel PT trace. It assumes that each 21 /// thread could have potentially been executed on different cpu cores. It uses 22 /// a context switch trace per CPU with timestamps to identify which thread owns 23 /// each Intel PT decoded instruction and in which order. It also assumes that 24 /// the Intel PT data and context switches might have gaps in their traces due 25 /// to contention or race conditions. Finally, it assumes that a tid is not 26 /// repeated twice for two different threads because of the shortness of the 27 /// intel pt trace. 28 /// 29 /// This object should be recreated after every stop in the case of live 30 /// processes. 31 class TraceIntelPTMultiCpuDecoder { 32 public: 33 /// \param[in] TraceIntelPT 34 /// The trace object to be decoded 35 TraceIntelPTMultiCpuDecoder(TraceIntelPTSP trace_sp); 36 37 /// \return 38 /// A \a DecodedThread for the \p thread by decoding its instructions on all 39 /// CPUs, sorted by TSCs. An \a llvm::Error is returned if the decoder 40 /// couldn't be properly set up. 41 llvm::Expected<DecodedThreadSP> Decode(Thread &thread); 42 43 /// \return 44 /// \b true if the given \p tid is managed by this decoder, regardless of 45 /// whether there's tracing data associated to it or not. 46 bool TracesThread(lldb::tid_t tid) const; 47 48 /// \return 49 /// The number of continuous executions found for the given \p tid. 50 size_t GetNumContinuousExecutionsForThread(lldb::tid_t tid) const; 51 52 /// \return 53 /// The number of PSB blocks for a given thread in all cores. 54 size_t GePSBBlocksCountForThread(lldb::tid_t tid) const; 55 56 /// \return 57 /// The total number of continuous executions found across CPUs. 58 size_t GetTotalContinuousExecutionsCount() const; 59 60 /// \return 61 /// The number of psb blocks in all cores that couldn't be matched with a 62 /// thread execution coming from context switch traces. 63 size_t GetUnattributedPSBBlocksCount() const; 64 65 /// \return 66 /// The total number of PSB blocks in all cores. 67 size_t GetTotalPSBBlocksCount() const; 68 69 /// \return 70 /// The lowest TSC value in this trace if available, \a llvm::None if the 71 /// trace is empty or the trace contains no timing information, or an \a 72 /// llvm::Error if it was not possible to set up the decoder. 73 llvm::Expected<llvm::Optional<uint64_t>> FindLowestTSC(); 74 75 private: 76 /// Traverse the context switch traces and the basic intel pt continuous 77 /// subtraces and produce a list of continuous executions for each process and 78 /// thread. 79 /// 80 /// See \a DoCorrelateContextSwitchesAndIntelPtTraces. 81 /// 82 /// Any errors are stored in \a m_setup_error. 83 llvm::Error CorrelateContextSwitchesAndIntelPtTraces(); 84 85 /// Produce a mapping from thread ids to the list of continuos executions with 86 /// their associated intel pt subtraces. 87 llvm::Expected< 88 llvm::DenseMap<lldb::tid_t, std::vector<IntelPTThreadContinousExecution>>> 89 DoCorrelateContextSwitchesAndIntelPtTraces(); 90 91 TraceIntelPTSP GetTrace(); 92 93 std::weak_ptr<TraceIntelPT> m_trace_wp; 94 std::set<lldb::tid_t> m_tids; 95 llvm::Optional< 96 llvm::DenseMap<lldb::tid_t, std::vector<IntelPTThreadContinousExecution>>> 97 m_continuous_executions_per_thread; 98 llvm::DenseMap<lldb::tid_t, DecodedThreadSP> m_decoded_threads; 99 /// This variable will be non-None if a severe error happened during the setup 100 /// of the decoder and we don't want decoding to be reattempted. 101 llvm::Optional<std::string> m_setup_error; 102 uint64_t m_unattributed_psb_blocks = 0; 103 uint64_t m_total_psb_blocks = 0; 104 }; 105 106 } // namespace trace_intel_pt 107 } // namespace lldb_private 108 109 #endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTMULTICPUDECODER_H 110