13 #include "llvm/Support/Error.h"
20 TraceIntelPTMultiCpuDecoder::TraceIntelPTMultiCpuDecoder(
22 : m_trace_wp(trace_sp) {
23 for (
Process *proc : trace_sp->GetAllProcesses()) {
24 for (ThreadSP thread_sp : proc->GetThreadList().Threads()) {
25 m_tids.insert(thread_sp->GetID());
40 return std::move(err);
45 ->GetThreadTimer(thread.
GetID())
46 .TimeTask(
"Decoding instructions", [&]() -> Expected<DecodedThreadSP> {
52 std::make_shared<DecodedThread>(thread.shared_from_this());
54 Error err = trace_sp->OnAllCpusBinaryDataRead(
56 [&](
const DenseMap<
cpu_id_t, ArrayRef<uint8_t>> &buffers) ->
Error {
58 m_continuous_executions_per_thread->find(thread.GetID());
59 if (it != m_continuous_executions_per_thread->end())
60 return DecodeSystemWideTraceForThread(
61 *decoded_thread_sp, *trace_sp, buffers, it->second);
63 return Error::success();
66 return std::move(err);
69 return decoded_thread_sp;
73 static Expected<std::vector<IntelPTThreadSubtrace>>
75 std::vector<IntelPTThreadSubtrace> intel_pt_subtraces;
78 [&](ArrayRef<uint8_t> data) ->
Error {
79 Expected<std::vector<IntelPTThreadSubtrace>> split_trace =
82 return split_trace.takeError();
84 intel_pt_subtraces = std::move(*split_trace);
85 return Error::success();
88 return std::move(err);
89 return intel_pt_subtraces;
92 Expected<DenseMap<lldb::tid_t, std::vector<IntelPTThreadContinousExecution>>>
94 DenseMap<lldb::tid_t, std::vector<IntelPTThreadContinousExecution>>
95 continuous_executions_per_thread;
98 Optional<LinuxPerfZeroTscConversion> conv_opt =
99 trace_sp->GetPerfZeroTscConversion();
101 return createStringError(
102 inconvertibleErrorCode(),
103 "TSC to nanoseconds conversion values were not found");
107 for (
cpu_id_t cpu_id : trace_sp->GetTracedCpus()) {
108 Expected<std::vector<IntelPTThreadSubtrace>> intel_pt_subtraces =
110 if (!intel_pt_subtraces)
111 return intel_pt_subtraces.takeError();
116 auto it = intel_pt_subtraces->begin();
117 auto on_new_thread_execution =
121 for (; it != intel_pt_subtraces->end() &&
122 it->tsc < thread_execution.GetEndTSC();
124 if (it->tsc > thread_execution.GetStartTSC()) {
130 continuous_executions_per_thread[thread_execution.tid].push_back(
133 Error err = trace_sp->OnCpuBinaryDataRead(
135 [&](ArrayRef<uint8_t> data) ->
Error {
136 Expected<std::vector<ThreadContinuousExecution>> executions =
139 return executions.takeError();
141 on_new_thread_execution(exec);
142 return Error::success();
145 return std::move(err);
151 for (
auto &tid_executions : continuous_executions_per_thread)
152 std::sort(tid_executions.second.begin(), tid_executions.second.end());
154 return continuous_executions_per_thread;
159 return createStringError(inconvertibleErrorCode(),
m_setup_error->c_str());
162 return Error::success();
165 "Context switch and Intel PT traces correlation", [&]() ->
Error {
168 return Error::success();
170 return correlation.takeError();
175 return createStringError(inconvertibleErrorCode(),
m_setup_error->c_str());
177 return Error::success();
187 return it->second.size();
195 count += kv.second.size();