1 //===-- SBQueue.cpp -------------------------------------------------------===//
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 "lldb/API/SBQueue.h"
12 #include "lldb/Utility/Instrumentation.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
{
30 QueueImpl() = default;
32 QueueImpl(const lldb::QueueSP
&queue_sp
) { m_queue_wp
= queue_sp
; }
34 QueueImpl(const QueueImpl
&rhs
) {
37 m_queue_wp
= rhs
.m_queue_wp
;
38 m_threads
= rhs
.m_threads
;
39 m_thread_list_fetched
= rhs
.m_thread_list_fetched
;
40 m_pending_items
= rhs
.m_pending_items
;
41 m_pending_items_fetched
= rhs
.m_pending_items_fetched
;
44 ~QueueImpl() = default;
46 bool IsValid() { return m_queue_wp
.lock() != nullptr; }
50 m_thread_list_fetched
= false;
52 m_pending_items_fetched
= false;
53 m_pending_items
.clear();
56 void SetQueue(const lldb::QueueSP
&queue_sp
) {
58 m_queue_wp
= queue_sp
;
61 lldb::queue_id_t
GetQueueID() const {
62 lldb::queue_id_t result
= LLDB_INVALID_QUEUE_ID
;
63 lldb::QueueSP queue_sp
= m_queue_wp
.lock();
65 result
= queue_sp
->GetID();
70 uint32_t GetIndexID() const {
71 uint32_t result
= LLDB_INVALID_INDEX32
;
72 lldb::QueueSP queue_sp
= m_queue_wp
.lock();
74 result
= queue_sp
->GetIndexID();
79 const char *GetName() const {
80 lldb::QueueSP queue_sp
= m_queue_wp
.lock();
83 return ConstString(queue_sp
->GetName()).GetCString();
87 if (!m_thread_list_fetched
) {
88 lldb::QueueSP queue_sp
= m_queue_wp
.lock();
90 Process::StopLocker stop_locker
;
91 if (stop_locker
.TryLock(&queue_sp
->GetProcess()->GetRunLock())) {
92 const std::vector
<ThreadSP
> thread_list(queue_sp
->GetThreads());
93 m_thread_list_fetched
= true;
94 const uint32_t num_threads
= thread_list
.size();
95 for (uint32_t idx
= 0; idx
< num_threads
; ++idx
) {
96 ThreadSP thread_sp
= thread_list
[idx
];
97 if (thread_sp
&& thread_sp
->IsValid()) {
98 m_threads
.push_back(thread_sp
);
107 if (!m_pending_items_fetched
) {
108 QueueSP queue_sp
= m_queue_wp
.lock();
110 Process::StopLocker stop_locker
;
111 if (stop_locker
.TryLock(&queue_sp
->GetProcess()->GetRunLock())) {
112 const std::vector
<QueueItemSP
> queue_items(
113 queue_sp
->GetPendingItems());
114 m_pending_items_fetched
= true;
115 const uint32_t num_pending_items
= queue_items
.size();
116 for (uint32_t idx
= 0; idx
< num_pending_items
; ++idx
) {
117 QueueItemSP item
= queue_items
[idx
];
118 if (item
&& item
->IsValid()) {
119 m_pending_items
.push_back(item
);
127 uint32_t GetNumThreads() {
131 if (m_thread_list_fetched
) {
132 result
= m_threads
.size();
137 lldb::SBThread
GetThreadAtIndex(uint32_t idx
) {
141 QueueSP queue_sp
= m_queue_wp
.lock();
142 if (queue_sp
&& idx
< m_threads
.size()) {
143 ProcessSP process_sp
= queue_sp
->GetProcess();
145 ThreadSP thread_sp
= m_threads
[idx
].lock();
147 sb_thread
.SetThread(thread_sp
);
154 uint32_t GetNumPendingItems() {
157 QueueSP queue_sp
= m_queue_wp
.lock();
158 if (!m_pending_items_fetched
&& queue_sp
) {
159 result
= queue_sp
->GetNumPendingWorkItems();
161 result
= m_pending_items
.size();
166 lldb::SBQueueItem
GetPendingItemAtIndex(uint32_t idx
) {
169 if (m_pending_items_fetched
&& idx
< m_pending_items
.size()) {
170 result
.SetQueueItem(m_pending_items
[idx
]);
175 uint32_t GetNumRunningItems() {
177 QueueSP queue_sp
= m_queue_wp
.lock();
179 result
= queue_sp
->GetNumRunningWorkItems();
183 lldb::SBProcess
GetProcess() {
185 QueueSP queue_sp
= m_queue_wp
.lock();
187 result
.SetSP(queue_sp
->GetProcess());
192 lldb::QueueKind
GetKind() {
193 lldb::QueueKind kind
= eQueueKindUnknown
;
194 QueueSP queue_sp
= m_queue_wp
.lock();
196 kind
= queue_sp
->GetKind();
202 lldb::QueueWP m_queue_wp
;
203 std::vector
<lldb::ThreadWP
>
204 m_threads
; // threads currently executing this queue's items
205 bool m_thread_list_fetched
=
206 false; // have we tried to fetch the threads list already?
207 std::vector
<lldb::QueueItemSP
> m_pending_items
; // items currently enqueued
208 bool m_pending_items_fetched
=
209 false; // have we tried to fetch the item list already?
213 SBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) { LLDB_INSTRUMENT_VA(this); }
215 SBQueue::SBQueue(const QueueSP
&queue_sp
)
216 : m_opaque_sp(new QueueImpl(queue_sp
)) {
217 LLDB_INSTRUMENT_VA(this, queue_sp
);
220 SBQueue::SBQueue(const SBQueue
&rhs
) {
221 LLDB_INSTRUMENT_VA(this, rhs
);
226 m_opaque_sp
= rhs
.m_opaque_sp
;
229 const lldb::SBQueue
&SBQueue::operator=(const lldb::SBQueue
&rhs
) {
230 LLDB_INSTRUMENT_VA(this, rhs
);
232 m_opaque_sp
= rhs
.m_opaque_sp
;
236 SBQueue::~SBQueue() = default;
238 bool SBQueue::IsValid() const {
239 LLDB_INSTRUMENT_VA(this);
240 return this->operator bool();
242 SBQueue::operator bool() const {
243 LLDB_INSTRUMENT_VA(this);
245 return m_opaque_sp
->IsValid();
248 void SBQueue::Clear() {
249 LLDB_INSTRUMENT_VA(this);
251 m_opaque_sp
->Clear();
254 void SBQueue::SetQueue(const QueueSP
&queue_sp
) {
255 m_opaque_sp
->SetQueue(queue_sp
);
258 lldb::queue_id_t
SBQueue::GetQueueID() const {
259 LLDB_INSTRUMENT_VA(this);
261 return m_opaque_sp
->GetQueueID();
264 uint32_t SBQueue::GetIndexID() const {
265 LLDB_INSTRUMENT_VA(this);
267 uint32_t index_id
= m_opaque_sp
->GetIndexID();
271 const char *SBQueue::GetName() const {
272 LLDB_INSTRUMENT_VA(this);
274 return m_opaque_sp
->GetName();
277 uint32_t SBQueue::GetNumThreads() {
278 LLDB_INSTRUMENT_VA(this);
280 return m_opaque_sp
->GetNumThreads();
283 SBThread
SBQueue::GetThreadAtIndex(uint32_t idx
) {
284 LLDB_INSTRUMENT_VA(this, idx
);
286 SBThread th
= m_opaque_sp
->GetThreadAtIndex(idx
);
290 uint32_t SBQueue::GetNumPendingItems() {
291 LLDB_INSTRUMENT_VA(this);
293 return m_opaque_sp
->GetNumPendingItems();
296 SBQueueItem
SBQueue::GetPendingItemAtIndex(uint32_t idx
) {
297 LLDB_INSTRUMENT_VA(this, idx
);
299 return m_opaque_sp
->GetPendingItemAtIndex(idx
);
302 uint32_t SBQueue::GetNumRunningItems() {
303 LLDB_INSTRUMENT_VA(this);
305 return m_opaque_sp
->GetNumRunningItems();
308 SBProcess
SBQueue::GetProcess() {
309 LLDB_INSTRUMENT_VA(this);
311 return m_opaque_sp
->GetProcess();
314 lldb::QueueKind
SBQueue::GetKind() {
315 LLDB_INSTRUMENT_VA(this);
317 return m_opaque_sp
->GetKind();