LLDB  mainline
SBQueue.cpp
Go to the documentation of this file.
1 //===-- SBQueue.cpp ---------------------------------------------*- C++ -*-===//
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 <inttypes.h>
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:
31  : m_queue_wp(), m_threads(), m_thread_list_fetched(false),
32  m_pending_items(), m_pending_items_fetched(false) {}
33 
34  QueueImpl(const lldb::QueueSP &queue_sp)
35  : m_queue_wp(), m_threads(), m_thread_list_fetched(false),
36  m_pending_items(), m_pending_items_fetched(false) {
37  m_queue_wp = queue_sp;
38  }
39 
40  QueueImpl(const QueueImpl &rhs) {
41  if (&rhs == this)
42  return;
43  m_queue_wp = rhs.m_queue_wp;
44  m_threads = rhs.m_threads;
45  m_thread_list_fetched = rhs.m_thread_list_fetched;
46  m_pending_items = rhs.m_pending_items;
47  m_pending_items_fetched = rhs.m_pending_items_fetched;
48  }
49 
51 
52  bool IsValid() { return m_queue_wp.lock() != NULL; }
53 
54  void Clear() {
55  m_queue_wp.reset();
56  m_thread_list_fetched = false;
57  m_threads.clear();
58  m_pending_items_fetched = false;
59  m_pending_items.clear();
60  }
61 
62  void SetQueue(const lldb::QueueSP &queue_sp) {
63  Clear();
64  m_queue_wp = queue_sp;
65  }
66 
69  lldb::QueueSP queue_sp = m_queue_wp.lock();
70  if (queue_sp) {
71  result = queue_sp->GetID();
72  }
73  return result;
74  }
75 
76  uint32_t GetIndexID() const {
78  lldb::QueueSP queue_sp = m_queue_wp.lock();
79  if (queue_sp) {
80  result = queue_sp->GetIndexID();
81  }
82  return result;
83  }
84 
85  const char *GetName() const {
86  const char *name = NULL;
87  lldb::QueueSP queue_sp = m_queue_wp.lock();
88  if (queue_sp.get()) {
89  name = queue_sp->GetName();
90  }
91  return name;
92  }
93 
94  void FetchThreads() {
95  if (!m_thread_list_fetched) {
96  lldb::QueueSP queue_sp = m_queue_wp.lock();
97  if (queue_sp) {
98  Process::StopLocker stop_locker;
99  if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
100  const std::vector<ThreadSP> thread_list(queue_sp->GetThreads());
101  m_thread_list_fetched = true;
102  const uint32_t num_threads = thread_list.size();
103  for (uint32_t idx = 0; idx < num_threads; ++idx) {
104  ThreadSP thread_sp = thread_list[idx];
105  if (thread_sp && thread_sp->IsValid()) {
106  m_threads.push_back(thread_sp);
107  }
108  }
109  }
110  }
111  }
112  }
113 
114  void FetchItems() {
115  if (!m_pending_items_fetched) {
116  QueueSP queue_sp = m_queue_wp.lock();
117  if (queue_sp) {
118  Process::StopLocker stop_locker;
119  if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
120  const std::vector<QueueItemSP> queue_items(
121  queue_sp->GetPendingItems());
122  m_pending_items_fetched = true;
123  const uint32_t num_pending_items = queue_items.size();
124  for (uint32_t idx = 0; idx < num_pending_items; ++idx) {
125  QueueItemSP item = queue_items[idx];
126  if (item && item->IsValid()) {
127  m_pending_items.push_back(item);
128  }
129  }
130  }
131  }
132  }
133  }
134 
136  uint32_t result = 0;
137 
138  FetchThreads();
139  if (m_thread_list_fetched) {
140  result = m_threads.size();
141  }
142  return result;
143  }
144 
146  FetchThreads();
147 
148  SBThread sb_thread;
149  QueueSP queue_sp = m_queue_wp.lock();
150  if (queue_sp && idx < m_threads.size()) {
151  ProcessSP process_sp = queue_sp->GetProcess();
152  if (process_sp) {
153  ThreadSP thread_sp = m_threads[idx].lock();
154  if (thread_sp) {
155  sb_thread.SetThread(thread_sp);
156  }
157  }
158  }
159  return sb_thread;
160  }
161 
163  uint32_t result = 0;
164 
165  QueueSP queue_sp = m_queue_wp.lock();
166  if (!m_pending_items_fetched && queue_sp) {
167  result = queue_sp->GetNumPendingWorkItems();
168  } else {
169  result = m_pending_items.size();
170  }
171  return result;
172  }
173 
175  SBQueueItem result;
176  FetchItems();
177  if (m_pending_items_fetched && idx < m_pending_items.size()) {
178  result.SetQueueItem(m_pending_items[idx]);
179  }
180  return result;
181  }
182 
184  uint32_t result = 0;
185  QueueSP queue_sp = m_queue_wp.lock();
186  if (queue_sp)
187  result = queue_sp->GetNumRunningWorkItems();
188  return result;
189  }
190 
192  SBProcess result;
193  QueueSP queue_sp = m_queue_wp.lock();
194  if (queue_sp) {
195  result.SetSP(queue_sp->GetProcess());
196  }
197  return result;
198  }
199 
202  QueueSP queue_sp = m_queue_wp.lock();
203  if (queue_sp)
204  kind = queue_sp->GetKind();
205 
206  return kind;
207  }
208 
209 private:
210  lldb::QueueWP m_queue_wp;
211  std::vector<lldb::ThreadWP>
212  m_threads; // threads currently executing this queue's items
213  bool
214  m_thread_list_fetched; // have we tried to fetch the threads list already?
215  std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued
216  bool m_pending_items_fetched; // have we tried to fetch the item list already?
217 };
218 }
219 
220 SBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) {
222 }
223 
224 SBQueue::SBQueue(const QueueSP &queue_sp)
225  : m_opaque_sp(new QueueImpl(queue_sp)) {
226  LLDB_RECORD_CONSTRUCTOR(SBQueue, (const lldb::QueueSP &), queue_sp);
227 }
228 
231 
232  if (&rhs == this)
233  return;
234 
235  m_opaque_sp = rhs.m_opaque_sp;
236 }
237 
240  SBQueue, operator=,(const lldb::SBQueue &), rhs);
241 
242  m_opaque_sp = rhs.m_opaque_sp;
243  return LLDB_RECORD_RESULT(*this);
244 }
245 
247 
248 bool SBQueue::IsValid() const {
250  return this->operator bool();
251 }
252 SBQueue::operator bool() const {
253  LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBQueue, operator bool);
254 
255  return m_opaque_sp->IsValid();
256 }
257 
260 
261  m_opaque_sp->Clear();
262 }
263 
264 void SBQueue::SetQueue(const QueueSP &queue_sp) {
265  m_opaque_sp->SetQueue(queue_sp);
266 }
267 
270 
271  return m_opaque_sp->GetQueueID();
272 }
273 
276 
277  uint32_t index_id = m_opaque_sp->GetIndexID();
278  return index_id;
279 }
280 
281 const char *SBQueue::GetName() const {
283 
284  return m_opaque_sp->GetName();
285 }
286 
289 
290  return m_opaque_sp->GetNumThreads();
291 }
292 
295  idx);
296 
297  SBThread th = m_opaque_sp->GetThreadAtIndex(idx);
298  return LLDB_RECORD_RESULT(th);
299 }
300 
303 
304  return m_opaque_sp->GetNumPendingItems();
305 }
306 
309  (uint32_t), idx);
310 
311  return LLDB_RECORD_RESULT(m_opaque_sp->GetPendingItemAtIndex(idx));
312 }
313 
316 
317  return m_opaque_sp->GetNumRunningItems();
318 }
319 
322 
323  return LLDB_RECORD_RESULT(m_opaque_sp->GetProcess());
324 }
325 
328 
329  return m_opaque_sp->GetKind();
330 }
331 
332 namespace lldb_private {
333 namespace repro {
334 
335 template <>
338  LLDB_REGISTER_CONSTRUCTOR(SBQueue, (const lldb::QueueSP &));
341  SBQueue, operator=,(const lldb::SBQueue &));
343  LLDB_REGISTER_METHOD_CONST(bool, SBQueue, operator bool, ());
344  LLDB_REGISTER_METHOD(void, SBQueue, Clear, ());
347  LLDB_REGISTER_METHOD_CONST(const char *, SBQueue, GetName, ());
352  (uint32_t));
356 }
357 
358 }
359 }
lldb::SBQueueItem GetPendingItemAtIndex(uint32_t)
Definition: SBQueue.cpp:307
The registry contains a unique mapping between functions and their ID.
Enumerations for broadcasting.
Definition: SBLaunchInfo.h:14
#define LLDB_RECORD_CONSTRUCTOR_NO_ARGS(Class)
lldb::queue_id_t GetQueueID() const
Definition: SBQueue.cpp:268
void SetSP(const lldb::ProcessSP &process_sp)
Definition: SBProcess.cpp:108
uint32_t GetNumRunningItems()
Definition: SBQueue.cpp:314
lldb::SBQueueItem GetPendingItemAtIndex(uint32_t idx)
Definition: SBQueue.cpp:174
#define LLDB_INVALID_QUEUE_ID
Definition: lldb-defines.h:98
void SetQueueItem(const lldb::QueueItemSP &queue_item_sp)
Definition: SBQueueItem.cpp:53
uint32_t GetIndexID() const
Definition: SBQueue.cpp:76
uint32_t GetNumPendingItems()
Definition: SBQueue.cpp:301
uint32_t GetNumRunningItems()
Definition: SBQueue.cpp:183
uint32_t GetIndexID() const
Definition: SBQueue.cpp:274
lldb::queue_id_t GetQueueID() const
Definition: SBQueue.cpp:67
void SetQueue(const lldb::QueueSP &queue_sp)
Definition: SBQueue.cpp:62
void SetQueue(const lldb::QueueSP &queue_sp)
Definition: SBQueue.cpp:264
#define LLDB_REGISTER_CONSTRUCTOR(Class, Signature)
#define LLDB_RECORD_METHOD_NO_ARGS(Result, Class, Method)
#define LLDB_INVALID_INDEX32
Definition: lldb-defines.h:86
lldb::SBThread GetThreadAtIndex(uint32_t idx)
Definition: SBQueue.cpp:145
const char * GetName() const
Definition: SBQueue.cpp:281
const char * GetName() const
Definition: SBQueue.cpp:85
#define LLDB_RECORD_CONSTRUCTOR(Class, Signature,...)
lldb::SBProcess GetProcess()
Definition: SBQueue.cpp:320
#define LLDB_RECORD_METHOD(Result, Class, Method, Signature,...)
uint32_t GetNumThreads()
Definition: SBQueue.cpp:287
void RegisterMethods< SBQueue >(Registry &R)
Definition: SBQueue.cpp:336
lldb::ProcessSP GetProcess() const
Definition: Thread.h:154
QueueImpl(const QueueImpl &rhs)
Definition: SBQueue.cpp:40
bool IsValid() const
Definition: SBQueue.cpp:248
uint64_t queue_id_t
Definition: lldb-types.h:91
lldb::QueueKind GetKind()
Definition: SBQueue.cpp:200
lldb::SBThread GetThreadAtIndex(uint32_t)
Definition: SBQueue.cpp:293
lldb::SBProcess GetProcess()
Definition: SBQueue.cpp:191
Definition: SBAddress.h:15
#define LLDB_REGISTER_METHOD(Result, Class, Method, Signature)
#define LLDB_RECORD_METHOD_CONST_NO_ARGS(Result, Class, Method)
void Clear()
Definition: SBQueue.cpp:258
uint32_t GetNumThreads()
Definition: SBQueue.cpp:135
uint32_t GetNumPendingItems()
Definition: SBQueue.cpp:162
#define LLDB_RECORD_RESULT(Result)
QueueImpl(const lldb::QueueSP &queue_sp)
Definition: SBQueue.cpp:34
#define LLDB_REGISTER_METHOD_CONST(Result, Class, Method, Signature)
lldb::QueueKind GetKind()
Definition: SBQueue.cpp:326
const SBQueue & operator=(const lldb::SBQueue &rhs)
Definition: SBQueue.cpp:238