LLDB  mainline
SBQueue.cpp
Go to the documentation of this file.
1 //===-- SBQueue.cpp -------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 
9 #include <cinttypes>
10 
11 #include "SBReproducerPrivate.h"
12 #include "lldb/API/SBQueue.h"
13 
14 #include "lldb/API/SBProcess.h"
15 #include "lldb/API/SBQueueItem.h"
16 #include "lldb/API/SBThread.h"
17 
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/Queue.h"
20 #include "lldb/Target/QueueItem.h"
21 #include "lldb/Target/Thread.h"
22 
23 using namespace lldb;
24 using namespace lldb_private;
25 
26 namespace lldb_private {
27 
28 class QueueImpl {
29 public:
30  QueueImpl() : m_queue_wp(), m_threads(), m_pending_items() {}
31 
32  QueueImpl(const lldb::QueueSP &queue_sp)
33  : m_queue_wp(), m_threads(), m_thread_list_fetched(false),
34  m_pending_items(), m_pending_items_fetched(false) {
35  m_queue_wp = queue_sp;
36  }
37 
38  QueueImpl(const QueueImpl &rhs) {
39  if (&rhs == this)
40  return;
41  m_queue_wp = rhs.m_queue_wp;
42  m_threads = rhs.m_threads;
43  m_thread_list_fetched = rhs.m_thread_list_fetched;
44  m_pending_items = rhs.m_pending_items;
45  m_pending_items_fetched = rhs.m_pending_items_fetched;
46  }
47 
48  ~QueueImpl() = default;
49 
50  bool IsValid() { return m_queue_wp.lock() != nullptr; }
51 
52  void Clear() {
53  m_queue_wp.reset();
54  m_thread_list_fetched = false;
55  m_threads.clear();
56  m_pending_items_fetched = false;
57  m_pending_items.clear();
58  }
59 
60  void SetQueue(const lldb::QueueSP &queue_sp) {
61  Clear();
62  m_queue_wp = queue_sp;
63  }
64 
67  lldb::QueueSP queue_sp = m_queue_wp.lock();
68  if (queue_sp) {
69  result = queue_sp->GetID();
70  }
71  return result;
72  }
73 
74  uint32_t GetIndexID() const {
76  lldb::QueueSP queue_sp = m_queue_wp.lock();
77  if (queue_sp) {
78  result = queue_sp->GetIndexID();
79  }
80  return result;
81  }
82 
83  const char *GetName() const {
84  const char *name = nullptr;
85  lldb::QueueSP queue_sp = m_queue_wp.lock();
86  if (queue_sp.get()) {
87  name = queue_sp->GetName();
88  }
89  return name;
90  }
91 
92  void FetchThreads() {
93  if (!m_thread_list_fetched) {
94  lldb::QueueSP queue_sp = m_queue_wp.lock();
95  if (queue_sp) {
96  Process::StopLocker stop_locker;
97  if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
98  const std::vector<ThreadSP> thread_list(queue_sp->GetThreads());
99  m_thread_list_fetched = true;
100  const uint32_t num_threads = thread_list.size();
101  for (uint32_t idx = 0; idx < num_threads; ++idx) {
102  ThreadSP thread_sp = thread_list[idx];
103  if (thread_sp && thread_sp->IsValid()) {
104  m_threads.push_back(thread_sp);
105  }
106  }
107  }
108  }
109  }
110  }
111 
112  void FetchItems() {
113  if (!m_pending_items_fetched) {
114  QueueSP queue_sp = m_queue_wp.lock();
115  if (queue_sp) {
116  Process::StopLocker stop_locker;
117  if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
118  const std::vector<QueueItemSP> queue_items(
119  queue_sp->GetPendingItems());
120  m_pending_items_fetched = true;
121  const uint32_t num_pending_items = queue_items.size();
122  for (uint32_t idx = 0; idx < num_pending_items; ++idx) {
123  QueueItemSP item = queue_items[idx];
124  if (item && item->IsValid()) {
125  m_pending_items.push_back(item);
126  }
127  }
128  }
129  }
130  }
131  }
132 
134  uint32_t result = 0;
135 
136  FetchThreads();
137  if (m_thread_list_fetched) {
138  result = m_threads.size();
139  }
140  return result;
141  }
142 
144  FetchThreads();
145 
146  SBThread sb_thread;
147  QueueSP queue_sp = m_queue_wp.lock();
148  if (queue_sp && idx < m_threads.size()) {
149  ProcessSP process_sp = queue_sp->GetProcess();
150  if (process_sp) {
151  ThreadSP thread_sp = m_threads[idx].lock();
152  if (thread_sp) {
153  sb_thread.SetThread(thread_sp);
154  }
155  }
156  }
157  return sb_thread;
158  }
159 
161  uint32_t result = 0;
162 
163  QueueSP queue_sp = m_queue_wp.lock();
164  if (!m_pending_items_fetched && queue_sp) {
165  result = queue_sp->GetNumPendingWorkItems();
166  } else {
167  result = m_pending_items.size();
168  }
169  return result;
170  }
171 
173  SBQueueItem result;
174  FetchItems();
175  if (m_pending_items_fetched && idx < m_pending_items.size()) {
176  result.SetQueueItem(m_pending_items[idx]);
177  }
178  return result;
179  }
180 
182  uint32_t result = 0;
183  QueueSP queue_sp = m_queue_wp.lock();
184  if (queue_sp)
185  result = queue_sp->GetNumRunningWorkItems();
186  return result;
187  }
188 
190  SBProcess result;
191  QueueSP queue_sp = m_queue_wp.lock();
192  if (queue_sp) {
193  result.SetSP(queue_sp->GetProcess());
194  }
195  return result;
196  }
197 
200  QueueSP queue_sp = m_queue_wp.lock();
201  if (queue_sp)
202  kind = queue_sp->GetKind();
203 
204  return kind;
205  }
206 
207 private:
208  lldb::QueueWP m_queue_wp;
209  std::vector<lldb::ThreadWP>
210  m_threads; // threads currently executing this queue's items
211  bool m_thread_list_fetched =
212  false; // have we tried to fetch the threads list already?
213  std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued
214  bool m_pending_items_fetched =
215  false; // have we tried to fetch the item list already?
216 };
217 }
218 
219 SBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) {
221 }
222 
223 SBQueue::SBQueue(const QueueSP &queue_sp)
224  : m_opaque_sp(new QueueImpl(queue_sp)) {
225  LLDB_RECORD_CONSTRUCTOR(SBQueue, (const lldb::QueueSP &), queue_sp);
226 }
227 
230 
231  if (&rhs == this)
232  return;
233 
234  m_opaque_sp = rhs.m_opaque_sp;
235 }
236 
239  SBQueue, operator=,(const lldb::SBQueue &), rhs);
240 
241  m_opaque_sp = rhs.m_opaque_sp;
242  return LLDB_RECORD_RESULT(*this);
243 }
244 
245 SBQueue::~SBQueue() = default;
246 
247 bool SBQueue::IsValid() const {
249  return this->operator bool();
250 }
251 SBQueue::operator bool() const {
252  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBQueue, operator bool);
253 
254  return m_opaque_sp->IsValid();
255 }
256 
259 
260  m_opaque_sp->Clear();
261 }
262 
263 void SBQueue::SetQueue(const QueueSP &queue_sp) {
264  m_opaque_sp->SetQueue(queue_sp);
265 }
266 
269 
270  return m_opaque_sp->GetQueueID();
271 }
272 
275 
276  uint32_t index_id = m_opaque_sp->GetIndexID();
277  return index_id;
278 }
279 
280 const char *SBQueue::GetName() const {
282 
283  return m_opaque_sp->GetName();
284 }
285 
288 
289  return m_opaque_sp->GetNumThreads();
290 }
291 
294  idx);
295 
296  SBThread th = m_opaque_sp->GetThreadAtIndex(idx);
297  return LLDB_RECORD_RESULT(th);
298 }
299 
302 
303  return m_opaque_sp->GetNumPendingItems();
304 }
305 
308  (uint32_t), idx);
309 
310  return LLDB_RECORD_RESULT(m_opaque_sp->GetPendingItemAtIndex(idx));
311 }
312 
315 
316  return m_opaque_sp->GetNumRunningItems();
317 }
318 
321 
322  return LLDB_RECORD_RESULT(m_opaque_sp->GetProcess());
323 }
324 
327 
328  return m_opaque_sp->GetKind();
329 }
330 
331 namespace lldb_private {
332 namespace repro {
333 
334 template <>
337  LLDB_REGISTER_CONSTRUCTOR(SBQueue, (const lldb::QueueSP &));
340  SBQueue, operator=,(const lldb::SBQueue &));
341  LLDB_REGISTER_METHOD_CONST(bool, SBQueue, IsValid, ());
342  LLDB_REGISTER_METHOD_CONST(bool, SBQueue, operator bool, ());
343  LLDB_REGISTER_METHOD(void, SBQueue, Clear, ());
345  LLDB_REGISTER_METHOD_CONST(uint32_t, SBQueue, GetIndexID, ());
346  LLDB_REGISTER_METHOD_CONST(const char *, SBQueue, GetName, ());
347  LLDB_REGISTER_METHOD(uint32_t, SBQueue, GetNumThreads, ());
348  LLDB_REGISTER_METHOD(lldb::SBThread, SBQueue, GetThreadAtIndex, (uint32_t));
349  LLDB_REGISTER_METHOD(uint32_t, SBQueue, GetNumPendingItems, ());
350  LLDB_REGISTER_METHOD(lldb::SBQueueItem, SBQueue, GetPendingItemAtIndex,
351  (uint32_t));
352  LLDB_REGISTER_METHOD(uint32_t, SBQueue, GetNumRunningItems, ());
353  LLDB_REGISTER_METHOD(lldb::SBProcess, SBQueue, GetProcess, ());
355 }
356 
357 }
358 }
lldb::SBQueue::IsValid
bool IsValid() const
Definition: SBQueue.cpp:247
lldb::SBQueue::GetName
const char * GetName() const
Definition: SBQueue.cpp:280
lldb_private::QueueImpl::m_queue_wp
lldb::QueueWP m_queue_wp
Definition: SBQueue.cpp:208
lldb::SBThread
Definition: SBThread.h:20
lldb::SBQueue::GetNumRunningItems
uint32_t GetNumRunningItems()
Definition: SBQueue.cpp:313
lldb::SBThread::SetThread
void SetThread(const lldb::ThreadSP &lldb_object_sp)
Definition: SBThread.cpp:379
lldb_private::QueueImpl::GetNumThreads
uint32_t GetNumThreads()
Definition: SBQueue.cpp:133
lldb_private::QueueImpl::FetchThreads
void FetchThreads()
Definition: SBQueue.cpp:92
lldb::SBQueue::GetNumPendingItems
uint32_t GetNumPendingItems()
Definition: SBQueue.cpp:300
lldb_private::QueueImpl::FetchItems
void FetchItems()
Definition: SBQueue.cpp:112
LLDB_RECORD_RESULT
#define LLDB_RECORD_RESULT(Result)
Definition: ReproducerInstrumentation.h:211
LLDB_RECORD_METHOD_CONST_NO_ARGS
#define LLDB_RECORD_METHOD_CONST_NO_ARGS(Result, Class, Method)
Definition: ReproducerInstrumentation.h:168
lldb_private::QueueImpl::IsValid
bool IsValid()
Definition: SBQueue.cpp:50
lldb_private::QueueImpl::QueueImpl
QueueImpl(const QueueImpl &rhs)
Definition: SBQueue.cpp:38
lldb::SBProcess::SetSP
void SetSP(const lldb::ProcessSP &process_sp)
Definition: SBProcess.cpp:108
LLDB_RECORD_METHOD_NO_ARGS
#define LLDB_RECORD_METHOD_NO_ARGS(Result, Class, Method)
Definition: ReproducerInstrumentation.h:165
lldb::SBQueue::operator=
const SBQueue & operator=(const lldb::SBQueue &rhs)
Definition: SBQueue.cpp:237
lldb_private::QueueImpl::GetPendingItemAtIndex
lldb::SBQueueItem GetPendingItemAtIndex(uint32_t idx)
Definition: SBQueue.cpp:172
lldb_private::QueueImpl::GetNumRunningItems
uint32_t GetNumRunningItems()
Definition: SBQueue.cpp:181
lldb_private::ProcessRunLock::ProcessRunLocker
Definition: ProcessRunLock.h:36
LLDB_RECORD_CONSTRUCTOR_NO_ARGS
#define LLDB_RECORD_CONSTRUCTOR_NO_ARGS(Class)
Definition: ReproducerInstrumentation.h:136
LLDB_REGISTER_METHOD_CONST
#define LLDB_REGISTER_METHOD_CONST(Result, Class, Method, Signature)
Definition: ReproducerInstrumentation.h:98
lldb::SBProcess
Definition: SBProcess.h:23
SBReproducerPrivate.h
lldb::SBQueueItem
Definition: SBQueueItem.h:17
LLDB_REGISTER_CONSTRUCTOR
#define LLDB_REGISTER_CONSTRUCTOR(Class, Signature)
Definition: ReproducerInstrumentation.h:89
lldb_private::QueueImpl::m_threads
std::vector< lldb::ThreadWP > m_threads
Definition: SBQueue.cpp:210
Process.h
lldb::queue_id_t
uint64_t queue_id_t
Definition: lldb-types.h:91
lldb_private::Thread::GetProcess
lldb::ProcessSP GetProcess() const
Definition: Thread.h:152
lldb_private::QueueImpl::m_pending_items
std::vector< lldb::QueueItemSP > m_pending_items
Definition: SBQueue.cpp:213
lldb::SBQueue::~SBQueue
~SBQueue()
LLDB_RECORD_METHOD
#define LLDB_RECORD_METHOD(Result, Class, Method, Signature,...)
Definition: ReproducerInstrumentation.h:158
lldb::SBQueue::GetKind
lldb::QueueKind GetKind()
Definition: SBQueue.cpp:325
SBThread.h
lldb::SBQueue::m_opaque_sp
std::shared_ptr< lldb_private::QueueImpl > m_opaque_sp
Definition: SBQueue.h:64
lldb_private::ProcessRunLock::ProcessRunLocker::TryLock
bool TryLock(ProcessRunLock *lock)
Definition: ProcessRunLock.h:43
lldb_private::QueueImpl::GetThreadAtIndex
lldb::SBThread GetThreadAtIndex(uint32_t idx)
Definition: SBQueue.cpp:143
GetName
static llvm::StringRef GetName(XcodeSDK::Type type)
Definition: XcodeSDK.cpp:21
lldb_private::QueueImpl::SetQueue
void SetQueue(const lldb::QueueSP &queue_sp)
Definition: SBQueue.cpp:60
lldb::eQueueKindUnknown
@ eQueueKindUnknown
Definition: lldb-enumerations.h:945
lldb::SBQueueItem::SetQueueItem
void SetQueueItem(const lldb::QueueItemSP &queue_item_sp)
Definition: SBQueueItem.cpp:53
lldb_private::QueueImpl::GetName
const char * GetName() const
Definition: SBQueue.cpp:83
lldb_private::QueueImpl
Definition: SBQueue.cpp:28
lldb_private::QueueImpl::GetIndexID
uint32_t GetIndexID() const
Definition: SBQueue.cpp:74
lldb_private::QueueImpl::QueueImpl
QueueImpl()
Definition: SBQueue.cpp:30
LLDB_INVALID_QUEUE_ID
#define LLDB_INVALID_QUEUE_ID
Definition: lldb-defines.h:100
Thread.h
lldb::SBQueue::GetProcess
lldb::SBProcess GetProcess()
Definition: SBQueue.cpp:319
Queue.h
lldb_private::QueueImpl::GetQueueID
lldb::queue_id_t GetQueueID() const
Definition: SBQueue.cpp:65
LLDB_RECORD_CONSTRUCTOR
#define LLDB_RECORD_CONSTRUCTOR(Class, Signature,...)
Definition: ReproducerInstrumentation.h:133
lldb_private::repro::Registry
The registry contains a unique mapping between functions and their ID.
Definition: ReproducerInstrumentation.h:517
lldb::SBQueue::GetPendingItemAtIndex
lldb::SBQueueItem GetPendingItemAtIndex(uint32_t)
Definition: SBQueue.cpp:306
lldb_private::QueueImpl::m_pending_items_fetched
bool m_pending_items_fetched
Definition: SBQueue.cpp:214
uint32_t
lldb::SBQueue
Definition: SBQueue.h:19
lldb_private::repro::RegisterMethods< SBQueue >
void RegisterMethods< SBQueue >(Registry &R)
Definition: SBQueue.cpp:335
lldb::SBQueue::Clear
void Clear()
Definition: SBQueue.cpp:257
lldb_private::QueueImpl::Clear
void Clear()
Definition: SBQueue.cpp:52
lldb::SBQueue::SBQueue
SBQueue()
Definition: SBQueue.cpp:219
lldb::SBQueue::GetQueueID
lldb::queue_id_t GetQueueID() const
Definition: SBQueue.cpp:267
lldb_private::QueueImpl::GetProcess
lldb::SBProcess GetProcess()
Definition: SBQueue.cpp:189
lldb_private::QueueImpl::m_thread_list_fetched
bool m_thread_list_fetched
Definition: SBQueue.cpp:211
lldb::SBQueue::SetQueue
void SetQueue(const lldb::QueueSP &queue_sp)
Definition: SBQueue.cpp:263
lldb_private::QueueImpl::QueueImpl
QueueImpl(const lldb::QueueSP &queue_sp)
Definition: SBQueue.cpp:32
lldb_private
A class that represents a running process on the host machine.
Definition: SBCommandInterpreterRunOptions.h:16
QueueItem.h
lldb_private::QueueImpl::GetKind
lldb::QueueKind GetKind()
Definition: SBQueue.cpp:198
lldb::SBQueue::GetThreadAtIndex
lldb::SBThread GetThreadAtIndex(uint32_t)
Definition: SBQueue.cpp:292
SBProcess.h
SBQueueItem.h
LLDB_INVALID_INDEX32
#define LLDB_INVALID_INDEX32
Definition: lldb-defines.h:87
lldb::SBQueue::GetNumThreads
uint32_t GetNumThreads()
Definition: SBQueue.cpp:286
lldb::SBQueue::GetIndexID
uint32_t GetIndexID() const
Definition: SBQueue.cpp:273
lldb
Definition: SBAddress.h:15
lldb::QueueKind
QueueKind
Queue type.
Definition: lldb-enumerations.h:944
SBQueue.h
lldb_private::QueueImpl::GetNumPendingItems
uint32_t GetNumPendingItems()
Definition: SBQueue.cpp:160
LLDB_REGISTER_METHOD
#define LLDB_REGISTER_METHOD(Result, Class, Method, Signature)
Definition: ReproducerInstrumentation.h:93