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.
40   DecodedThreadSP Decode(Thread &thread);
41 
42   /// \return
43   ///   \b true if the given \p tid is managed by this decoder, regardless of
44   ///   whether there's tracing data associated to it or not.
45   bool TracesThread(lldb::tid_t tid) const;
46 
47   /// \return
48   ///   The number of continuous executions found for the given \p tid.
49   size_t GetNumContinuousExecutionsForThread(lldb::tid_t tid) const;
50 
51   /// \return
52   ///   The total number of continuous executions found across CPUs.
53   size_t GetTotalContinuousExecutionsCount() const;
54 
55 private:
56   /// Traverse the context switch traces and the basic intel pt continuous
57   /// subtraces and produce a list of continuous executions for each process and
58   /// thread.
59   ///
60   /// See \a DoCorrelateContextSwitchesAndIntelPtTraces.
61   ///
62   /// Any errors are stored in \a m_setup_error.
63   llvm::Error CorrelateContextSwitchesAndIntelPtTraces();
64 
65   /// Produce a mapping from thread ids to the list of continuos executions with
66   /// their associated intel pt subtraces.
67   llvm::Expected<
68       llvm::DenseMap<lldb::tid_t, std::vector<IntelPTThreadContinousExecution>>>
69   DoCorrelateContextSwitchesAndIntelPtTraces();
70 
71   TraceIntelPTSP GetTrace();
72 
73   std::weak_ptr<TraceIntelPT> m_trace_wp;
74   std::set<lldb::tid_t> m_tids;
75   llvm::Optional<
76       llvm::DenseMap<lldb::tid_t, std::vector<IntelPTThreadContinousExecution>>>
77       m_continuous_executions_per_thread;
78   llvm::DenseMap<lldb::tid_t, DecodedThreadSP> m_decoded_threads;
79   /// This variable will be non-None if a severe error happened during the setup
80   /// of the decoder and we don't want decoding to be reattempted.
81   llvm::Optional<std::string> m_setup_error;
82   uint64_t m_unattributed_intelpt_subtraces;
83 };
84 
85 } // namespace trace_intel_pt
86 } // namespace lldb_private
87 
88 #endif // LLDB_SOURCE_PLUGINS_TRACE_INTEL_PT_TRACEINTELPTMULTICPUDECODER_H
89