1 //===-- SBQueue.cpp ---------------------------------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
11 #include "SBReproducerPrivate.h"
12 #include "lldb/API/SBQueue.h"
14 #include "lldb/API/SBProcess.h"
15 #include "lldb/API/SBQueueItem.h"
16 #include "lldb/API/SBThread.h"
18 #include "lldb/Target/Process.h"
19 #include "lldb/Target/Queue.h"
20 #include "lldb/Target/QueueItem.h"
21 #include "lldb/Target/Thread.h"
24 using namespace lldb_private
;
26 namespace lldb_private
{
31 : m_queue_wp(), m_threads(), m_thread_list_fetched(false),
32 m_pending_items(), m_pending_items_fetched(false) {}
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
;
40 QueueImpl(const QueueImpl
&rhs
) {
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
;
52 bool IsValid() { return m_queue_wp
.lock() != nullptr; }
56 m_thread_list_fetched
= false;
58 m_pending_items_fetched
= false;
59 m_pending_items
.clear();
62 void SetQueue(const lldb::QueueSP
&queue_sp
) {
64 m_queue_wp
= queue_sp
;
67 lldb::queue_id_t
GetQueueID() const {
68 lldb::queue_id_t result
= LLDB_INVALID_QUEUE_ID
;
69 lldb::QueueSP queue_sp
= m_queue_wp
.lock();
71 result
= queue_sp
->GetID();
76 uint32_t GetIndexID() const {
77 uint32_t result
= LLDB_INVALID_INDEX32
;
78 lldb::QueueSP queue_sp
= m_queue_wp
.lock();
80 result
= queue_sp
->GetIndexID();
85 const char *GetName() const {
86 const char *name
= nullptr;
87 lldb::QueueSP queue_sp
= m_queue_wp
.lock();
89 name
= queue_sp
->GetName();
95 if (!m_thread_list_fetched
) {
96 lldb::QueueSP queue_sp
= m_queue_wp
.lock();
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
);
115 if (!m_pending_items_fetched
) {
116 QueueSP queue_sp
= m_queue_wp
.lock();
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
);
135 uint32_t GetNumThreads() {
139 if (m_thread_list_fetched
) {
140 result
= m_threads
.size();
145 lldb::SBThread
GetThreadAtIndex(uint32_t idx
) {
149 QueueSP queue_sp
= m_queue_wp
.lock();
150 if (queue_sp
&& idx
< m_threads
.size()) {
151 ProcessSP process_sp
= queue_sp
->GetProcess();
153 ThreadSP thread_sp
= m_threads
[idx
].lock();
155 sb_thread
.SetThread(thread_sp
);
162 uint32_t GetNumPendingItems() {
165 QueueSP queue_sp
= m_queue_wp
.lock();
166 if (!m_pending_items_fetched
&& queue_sp
) {
167 result
= queue_sp
->GetNumPendingWorkItems();
169 result
= m_pending_items
.size();
174 lldb::SBQueueItem
GetPendingItemAtIndex(uint32_t idx
) {
177 if (m_pending_items_fetched
&& idx
< m_pending_items
.size()) {
178 result
.SetQueueItem(m_pending_items
[idx
]);
183 uint32_t GetNumRunningItems() {
185 QueueSP queue_sp
= m_queue_wp
.lock();
187 result
= queue_sp
->GetNumRunningWorkItems();
191 lldb::SBProcess
GetProcess() {
193 QueueSP queue_sp
= m_queue_wp
.lock();
195 result
.SetSP(queue_sp
->GetProcess());
200 lldb::QueueKind
GetKind() {
201 lldb::QueueKind kind
= eQueueKindUnknown
;
202 QueueSP queue_sp
= m_queue_wp
.lock();
204 kind
= queue_sp
->GetKind();
210 lldb::QueueWP m_queue_wp
;
211 std::vector
<lldb::ThreadWP
>
212 m_threads
; // threads currently executing this queue's items
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?
220 SBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) {
221 LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBQueue
);
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
);
229 SBQueue::SBQueue(const SBQueue
&rhs
) {
230 LLDB_RECORD_CONSTRUCTOR(SBQueue
, (const lldb::SBQueue
&), rhs
);
235 m_opaque_sp
= rhs
.m_opaque_sp
;
238 const lldb::SBQueue
&SBQueue::operator=(const lldb::SBQueue
&rhs
) {
239 LLDB_RECORD_METHOD(const lldb::SBQueue
&,
240 SBQueue
, operator=,(const lldb::SBQueue
&), rhs
);
242 m_opaque_sp
= rhs
.m_opaque_sp
;
243 return LLDB_RECORD_RESULT(*this);
246 SBQueue::~SBQueue() {}
248 bool SBQueue::IsValid() const {
249 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBQueue
, IsValid
);
250 return this->operator bool();
252 SBQueue::operator bool() const {
253 LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBQueue
, operator bool);
255 return m_opaque_sp
->IsValid();
258 void SBQueue::Clear() {
259 LLDB_RECORD_METHOD_NO_ARGS(void, SBQueue
, Clear
);
261 m_opaque_sp
->Clear();
264 void SBQueue::SetQueue(const QueueSP
&queue_sp
) {
265 m_opaque_sp
->SetQueue(queue_sp
);
268 lldb::queue_id_t
SBQueue::GetQueueID() const {
269 LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::queue_id_t
, SBQueue
, GetQueueID
);
271 return m_opaque_sp
->GetQueueID();
274 uint32_t SBQueue::GetIndexID() const {
275 LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBQueue
, GetIndexID
);
277 uint32_t index_id
= m_opaque_sp
->GetIndexID();
281 const char *SBQueue::GetName() const {
282 LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBQueue
, GetName
);
284 return m_opaque_sp
->GetName();
287 uint32_t SBQueue::GetNumThreads() {
288 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBQueue
, GetNumThreads
);
290 return m_opaque_sp
->GetNumThreads();
293 SBThread
SBQueue::GetThreadAtIndex(uint32_t idx
) {
294 LLDB_RECORD_METHOD(lldb::SBThread
, SBQueue
, GetThreadAtIndex
, (uint32_t),
297 SBThread th
= m_opaque_sp
->GetThreadAtIndex(idx
);
298 return LLDB_RECORD_RESULT(th
);
301 uint32_t SBQueue::GetNumPendingItems() {
302 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBQueue
, GetNumPendingItems
);
304 return m_opaque_sp
->GetNumPendingItems();
307 SBQueueItem
SBQueue::GetPendingItemAtIndex(uint32_t idx
) {
308 LLDB_RECORD_METHOD(lldb::SBQueueItem
, SBQueue
, GetPendingItemAtIndex
,
311 return LLDB_RECORD_RESULT(m_opaque_sp
->GetPendingItemAtIndex(idx
));
314 uint32_t SBQueue::GetNumRunningItems() {
315 LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBQueue
, GetNumRunningItems
);
317 return m_opaque_sp
->GetNumRunningItems();
320 SBProcess
SBQueue::GetProcess() {
321 LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess
, SBQueue
, GetProcess
);
323 return LLDB_RECORD_RESULT(m_opaque_sp
->GetProcess());
326 lldb::QueueKind
SBQueue::GetKind() {
327 LLDB_RECORD_METHOD_NO_ARGS(lldb::QueueKind
, SBQueue
, GetKind
);
329 return m_opaque_sp
->GetKind();
332 namespace lldb_private
{
336 void RegisterMethods
<SBQueue
>(Registry
&R
) {
337 LLDB_REGISTER_CONSTRUCTOR(SBQueue
, ());
338 LLDB_REGISTER_CONSTRUCTOR(SBQueue
, (const lldb::QueueSP
&));
339 LLDB_REGISTER_CONSTRUCTOR(SBQueue
, (const lldb::SBQueue
&));
340 LLDB_REGISTER_METHOD(const lldb::SBQueue
&,
341 SBQueue
, operator=,(const lldb::SBQueue
&));
342 LLDB_REGISTER_METHOD_CONST(bool, SBQueue
, IsValid
, ());
343 LLDB_REGISTER_METHOD_CONST(bool, SBQueue
, operator bool, ());
344 LLDB_REGISTER_METHOD(void, SBQueue
, Clear
, ());
345 LLDB_REGISTER_METHOD_CONST(lldb::queue_id_t
, SBQueue
, GetQueueID
, ());
346 LLDB_REGISTER_METHOD_CONST(uint32_t, SBQueue
, GetIndexID
, ());
347 LLDB_REGISTER_METHOD_CONST(const char *, SBQueue
, GetName
, ());
348 LLDB_REGISTER_METHOD(uint32_t, SBQueue
, GetNumThreads
, ());
349 LLDB_REGISTER_METHOD(lldb::SBThread
, SBQueue
, GetThreadAtIndex
, (uint32_t));
350 LLDB_REGISTER_METHOD(uint32_t, SBQueue
, GetNumPendingItems
, ());
351 LLDB_REGISTER_METHOD(lldb::SBQueueItem
, SBQueue
, GetPendingItemAtIndex
,
353 LLDB_REGISTER_METHOD(uint32_t, SBQueue
, GetNumRunningItems
, ());
354 LLDB_REGISTER_METHOD(lldb::SBProcess
, SBQueue
, GetProcess
, ());
355 LLDB_REGISTER_METHOD(lldb::QueueKind
, SBQueue
, GetKind
, ());