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