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 
TracesThread(lldb::tid_t tid) const161188faa7SWalter Erquinigo bool IntelPTThreadTraceCollection::TracesThread(lldb::tid_t tid) const {
171188faa7SWalter Erquinigo   return m_thread_traces.count(tid);
181188faa7SWalter Erquinigo }
191188faa7SWalter Erquinigo 
TraceStop(lldb::tid_t tid)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);
25*6a5355e8SWalter Erquinigo   m_total_buffer_size -= it->second.GetIptTraceSize();
261188faa7SWalter Erquinigo   m_thread_traces.erase(tid);
271188faa7SWalter Erquinigo   return Error::success();
281188faa7SWalter Erquinigo }
291188faa7SWalter Erquinigo 
TraceStart(lldb::tid_t tid,const TraceIntelPTStartRequest & request)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 
41*6a5355e8SWalter Erquinigo   m_total_buffer_size += trace->GetIptTraceSize();
42a7582059SWalter Erquinigo   m_thread_traces.try_emplace(tid, std::move(*trace));
431188faa7SWalter Erquinigo   return Error::success();
441188faa7SWalter Erquinigo }
451188faa7SWalter Erquinigo 
GetTotalBufferSize() const461188faa7SWalter Erquinigo size_t IntelPTThreadTraceCollection::GetTotalBufferSize() const {
471188faa7SWalter Erquinigo   return m_total_buffer_size;
481188faa7SWalter Erquinigo }
491188faa7SWalter Erquinigo 
ForEachThread(std::function<void (lldb::tid_t tid,IntelPTSingleBufferTrace & thread_trace)> callback)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 &>
GetTracedThread(lldb::tid_t tid)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 
Clear()661188faa7SWalter Erquinigo void IntelPTThreadTraceCollection::Clear() {
671188faa7SWalter Erquinigo   m_thread_traces.clear();
681188faa7SWalter Erquinigo   m_total_buffer_size = 0;
691188faa7SWalter Erquinigo }
701188faa7SWalter Erquinigo 
GetTracedThreadsCount() const711188faa7SWalter Erquinigo size_t IntelPTThreadTraceCollection::GetTracedThreadsCount() const {
721188faa7SWalter Erquinigo   return m_thread_traces.size();
731188faa7SWalter Erquinigo }
74fc5ef57cSWalter Erquinigo 
75fc5ef57cSWalter Erquinigo llvm::Expected<llvm::Optional<std::vector<uint8_t>>>
TryGetBinaryData(const TraceGetBinaryDataRequest & request)76fc5ef57cSWalter Erquinigo IntelPTThreadTraceCollection::TryGetBinaryData(
77fc5ef57cSWalter Erquinigo     const TraceGetBinaryDataRequest &request) {
78fc5ef57cSWalter Erquinigo   if (!request.tid)
79fc5ef57cSWalter Erquinigo     return None;
80*6a5355e8SWalter Erquinigo   if (request.kind != IntelPTDataKinds::kIptTrace)
81fc5ef57cSWalter Erquinigo     return None;
82fc5ef57cSWalter Erquinigo 
83fc5ef57cSWalter Erquinigo   if (!TracesThread(*request.tid))
84fc5ef57cSWalter Erquinigo     return None;
85fc5ef57cSWalter Erquinigo 
86fc5ef57cSWalter Erquinigo   if (Expected<IntelPTSingleBufferTrace &> trace =
87fc5ef57cSWalter Erquinigo           GetTracedThread(*request.tid))
88*6a5355e8SWalter Erquinigo     return trace->GetIptTrace();
89fc5ef57cSWalter Erquinigo   else
90fc5ef57cSWalter Erquinigo     return trace.takeError();
91fc5ef57cSWalter Erquinigo }
92