11188faa7SWalter Erquinigo //===-- IntelPTThreadTraceCollection.cpp ----------------------------------===// 21188faa7SWalter Erquinigo // 31188faa7SWalter Erquinigo // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 41188faa7SWalter Erquinigo // See https://llvm.org/LICENSE.txt for license information. 51188faa7SWalter Erquinigo // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 61188faa7SWalter Erquinigo // 71188faa7SWalter Erquinigo //===----------------------------------------------------------------------===// 81188faa7SWalter Erquinigo 91188faa7SWalter Erquinigo #include "IntelPTThreadTraceCollection.h" 101188faa7SWalter Erquinigo 111188faa7SWalter Erquinigo using namespace lldb; 121188faa7SWalter Erquinigo using namespace lldb_private; 131188faa7SWalter Erquinigo using namespace process_linux; 141188faa7SWalter Erquinigo using namespace llvm; 151188faa7SWalter Erquinigo 161188faa7SWalter Erquinigo bool IntelPTThreadTraceCollection::TracesThread(lldb::tid_t tid) const { 171188faa7SWalter Erquinigo return m_thread_traces.count(tid); 181188faa7SWalter Erquinigo } 191188faa7SWalter Erquinigo 201188faa7SWalter Erquinigo Error IntelPTThreadTraceCollection::TraceStop(lldb::tid_t tid) { 211188faa7SWalter Erquinigo auto it = m_thread_traces.find(tid); 221188faa7SWalter Erquinigo if (it == m_thread_traces.end()) 231188faa7SWalter Erquinigo return createStringError(inconvertibleErrorCode(), 241188faa7SWalter Erquinigo "Thread %" PRIu64 " not currently traced", tid); 25a7582059SWalter Erquinigo m_total_buffer_size -= it->second.GetTraceBufferSize(); 261188faa7SWalter Erquinigo m_thread_traces.erase(tid); 271188faa7SWalter Erquinigo return Error::success(); 281188faa7SWalter Erquinigo } 291188faa7SWalter Erquinigo 301188faa7SWalter Erquinigo Error IntelPTThreadTraceCollection::TraceStart( 311188faa7SWalter Erquinigo lldb::tid_t tid, const TraceIntelPTStartRequest &request) { 321188faa7SWalter Erquinigo if (TracesThread(tid)) 331188faa7SWalter Erquinigo return createStringError(inconvertibleErrorCode(), 341188faa7SWalter Erquinigo "Thread %" PRIu64 " already traced", tid); 351188faa7SWalter Erquinigo 36a7582059SWalter Erquinigo Expected<IntelPTSingleBufferTrace> trace = 37a7582059SWalter Erquinigo IntelPTSingleBufferTrace::Start(request, tid); 38a7582059SWalter Erquinigo if (!trace) 39a7582059SWalter Erquinigo return trace.takeError(); 401188faa7SWalter Erquinigo 41a7582059SWalter Erquinigo m_total_buffer_size += trace->GetTraceBufferSize(); 42a7582059SWalter Erquinigo m_thread_traces.try_emplace(tid, std::move(*trace)); 431188faa7SWalter Erquinigo return Error::success(); 441188faa7SWalter Erquinigo } 451188faa7SWalter Erquinigo 461188faa7SWalter Erquinigo size_t IntelPTThreadTraceCollection::GetTotalBufferSize() const { 471188faa7SWalter Erquinigo return m_total_buffer_size; 481188faa7SWalter Erquinigo } 491188faa7SWalter Erquinigo 501188faa7SWalter Erquinigo void IntelPTThreadTraceCollection::ForEachThread( 511188faa7SWalter Erquinigo std::function<void(lldb::tid_t tid, IntelPTSingleBufferTrace &thread_trace)> 521188faa7SWalter Erquinigo callback) { 531188faa7SWalter Erquinigo for (auto &it : m_thread_traces) 54a7582059SWalter Erquinigo callback(it.first, it.second); 551188faa7SWalter Erquinigo } 561188faa7SWalter Erquinigo 571188faa7SWalter Erquinigo Expected<IntelPTSingleBufferTrace &> 581188faa7SWalter Erquinigo IntelPTThreadTraceCollection::GetTracedThread(lldb::tid_t tid) { 591188faa7SWalter Erquinigo auto it = m_thread_traces.find(tid); 601188faa7SWalter Erquinigo if (it == m_thread_traces.end()) 611188faa7SWalter Erquinigo return createStringError(inconvertibleErrorCode(), 621188faa7SWalter Erquinigo "Thread %" PRIu64 " not currently traced", tid); 63a7582059SWalter Erquinigo return it->second; 641188faa7SWalter Erquinigo } 651188faa7SWalter Erquinigo 661188faa7SWalter Erquinigo void IntelPTThreadTraceCollection::Clear() { 671188faa7SWalter Erquinigo m_thread_traces.clear(); 681188faa7SWalter Erquinigo m_total_buffer_size = 0; 691188faa7SWalter Erquinigo } 701188faa7SWalter Erquinigo 711188faa7SWalter Erquinigo size_t IntelPTThreadTraceCollection::GetTracedThreadsCount() const { 721188faa7SWalter Erquinigo return m_thread_traces.size(); 731188faa7SWalter Erquinigo } 74*fc5ef57cSWalter Erquinigo 75*fc5ef57cSWalter Erquinigo llvm::Expected<llvm::Optional<std::vector<uint8_t>>> 76*fc5ef57cSWalter Erquinigo IntelPTThreadTraceCollection::TryGetBinaryData( 77*fc5ef57cSWalter Erquinigo const TraceGetBinaryDataRequest &request) { 78*fc5ef57cSWalter Erquinigo if (!request.tid) 79*fc5ef57cSWalter Erquinigo return None; 80*fc5ef57cSWalter Erquinigo if (request.kind != IntelPTDataKinds::kTraceBuffer) 81*fc5ef57cSWalter Erquinigo return None; 82*fc5ef57cSWalter Erquinigo 83*fc5ef57cSWalter Erquinigo if (!TracesThread(*request.tid)) 84*fc5ef57cSWalter Erquinigo return None; 85*fc5ef57cSWalter Erquinigo 86*fc5ef57cSWalter Erquinigo if (Expected<IntelPTSingleBufferTrace &> trace = 87*fc5ef57cSWalter Erquinigo GetTracedThread(*request.tid)) 88*fc5ef57cSWalter Erquinigo return trace->GetTraceBuffer(request.offset, request.size); 89*fc5ef57cSWalter Erquinigo else 90*fc5ef57cSWalter Erquinigo return trace.takeError(); 91*fc5ef57cSWalter Erquinigo } 92