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