1*1188faa7SWalter Erquinigo //===-- IntelPTThreadTraceCollection.cpp ----------------------------------===//
2*1188faa7SWalter Erquinigo //
3*1188faa7SWalter Erquinigo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*1188faa7SWalter Erquinigo // See https://llvm.org/LICENSE.txt for license information.
5*1188faa7SWalter Erquinigo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*1188faa7SWalter Erquinigo //
7*1188faa7SWalter Erquinigo //===----------------------------------------------------------------------===//
8*1188faa7SWalter Erquinigo 
9*1188faa7SWalter Erquinigo #include "IntelPTThreadTraceCollection.h"
10*1188faa7SWalter Erquinigo 
11*1188faa7SWalter Erquinigo using namespace lldb;
12*1188faa7SWalter Erquinigo using namespace lldb_private;
13*1188faa7SWalter Erquinigo using namespace process_linux;
14*1188faa7SWalter Erquinigo using namespace llvm;
15*1188faa7SWalter Erquinigo 
16*1188faa7SWalter Erquinigo bool IntelPTThreadTraceCollection::TracesThread(lldb::tid_t tid) const {
17*1188faa7SWalter Erquinigo   return m_thread_traces.count(tid);
18*1188faa7SWalter Erquinigo }
19*1188faa7SWalter Erquinigo 
20*1188faa7SWalter Erquinigo Error IntelPTThreadTraceCollection::TraceStop(lldb::tid_t tid) {
21*1188faa7SWalter Erquinigo   auto it = m_thread_traces.find(tid);
22*1188faa7SWalter Erquinigo   if (it == m_thread_traces.end())
23*1188faa7SWalter Erquinigo     return createStringError(inconvertibleErrorCode(),
24*1188faa7SWalter Erquinigo                              "Thread %" PRIu64 " not currently traced", tid);
25*1188faa7SWalter Erquinigo   m_total_buffer_size -= it->second->GetTraceBufferSize();
26*1188faa7SWalter Erquinigo   m_thread_traces.erase(tid);
27*1188faa7SWalter Erquinigo   return Error::success();
28*1188faa7SWalter Erquinigo }
29*1188faa7SWalter Erquinigo 
30*1188faa7SWalter Erquinigo Error IntelPTThreadTraceCollection::TraceStart(
31*1188faa7SWalter Erquinigo     lldb::tid_t tid, const TraceIntelPTStartRequest &request) {
32*1188faa7SWalter Erquinigo   if (TracesThread(tid))
33*1188faa7SWalter Erquinigo     return createStringError(inconvertibleErrorCode(),
34*1188faa7SWalter Erquinigo                              "Thread %" PRIu64 " already traced", tid);
35*1188faa7SWalter Erquinigo 
36*1188faa7SWalter Erquinigo   Expected<IntelPTSingleBufferTraceUP> trace_up =
37*1188faa7SWalter Erquinigo       IntelPTSingleBufferTrace::Start(request, tid, /*core_id=*/None,
38*1188faa7SWalter Erquinigo                                       TraceCollectionState::Running);
39*1188faa7SWalter Erquinigo   if (!trace_up)
40*1188faa7SWalter Erquinigo     return trace_up.takeError();
41*1188faa7SWalter Erquinigo 
42*1188faa7SWalter Erquinigo   m_total_buffer_size += (*trace_up)->GetTraceBufferSize();
43*1188faa7SWalter Erquinigo   m_thread_traces.try_emplace(tid, std::move(*trace_up));
44*1188faa7SWalter Erquinigo   return Error::success();
45*1188faa7SWalter Erquinigo }
46*1188faa7SWalter Erquinigo 
47*1188faa7SWalter Erquinigo size_t IntelPTThreadTraceCollection::GetTotalBufferSize() const {
48*1188faa7SWalter Erquinigo   return m_total_buffer_size;
49*1188faa7SWalter Erquinigo }
50*1188faa7SWalter Erquinigo 
51*1188faa7SWalter Erquinigo void IntelPTThreadTraceCollection::ForEachThread(
52*1188faa7SWalter Erquinigo     std::function<void(lldb::tid_t tid, IntelPTSingleBufferTrace &thread_trace)>
53*1188faa7SWalter Erquinigo         callback) {
54*1188faa7SWalter Erquinigo   for (auto &it : m_thread_traces)
55*1188faa7SWalter Erquinigo     callback(it.first, *it.second);
56*1188faa7SWalter Erquinigo }
57*1188faa7SWalter Erquinigo 
58*1188faa7SWalter Erquinigo Expected<IntelPTSingleBufferTrace &>
59*1188faa7SWalter Erquinigo IntelPTThreadTraceCollection::GetTracedThread(lldb::tid_t tid) {
60*1188faa7SWalter Erquinigo   auto it = m_thread_traces.find(tid);
61*1188faa7SWalter Erquinigo   if (it == m_thread_traces.end())
62*1188faa7SWalter Erquinigo     return createStringError(inconvertibleErrorCode(),
63*1188faa7SWalter Erquinigo                              "Thread %" PRIu64 " not currently traced", tid);
64*1188faa7SWalter Erquinigo   return *it->second.get();
65*1188faa7SWalter Erquinigo }
66*1188faa7SWalter Erquinigo 
67*1188faa7SWalter Erquinigo void IntelPTThreadTraceCollection::Clear() {
68*1188faa7SWalter Erquinigo   m_thread_traces.clear();
69*1188faa7SWalter Erquinigo   m_total_buffer_size = 0;
70*1188faa7SWalter Erquinigo }
71*1188faa7SWalter Erquinigo 
72*1188faa7SWalter Erquinigo size_t IntelPTThreadTraceCollection::GetTracedThreadsCount() const {
73*1188faa7SWalter Erquinigo   return m_thread_traces.size();
74*1188faa7SWalter Erquinigo }
75