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 {
32 QueueImpl(const lldb::QueueSP &queue_sp)
33 : m_thread_list_fetched(false), m_pending_items_fetched(false) {
34 m_queue_wp = queue_sp;
37 QueueImpl(const QueueImpl &rhs) {
40 m_queue_wp = rhs.m_queue_wp;
41 m_threads = rhs.m_threads;
42 m_thread_list_fetched = rhs.m_thread_list_fetched;
43 m_pending_items = rhs.m_pending_items;
44 m_pending_items_fetched = rhs.m_pending_items_fetched;
47 ~QueueImpl() = default;
49 bool IsValid() { return m_queue_wp.lock() != nullptr; }
53 m_thread_list_fetched = false;
55 m_pending_items_fetched = false;
56 m_pending_items.clear();
59 void SetQueue(const lldb::QueueSP &queue_sp) {
61 m_queue_wp = queue_sp;
64 lldb::queue_id_t GetQueueID() const {
65 lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID;
66 lldb::QueueSP queue_sp = m_queue_wp.lock();
68 result = queue_sp->GetID();
73 uint32_t GetIndexID() const {
74 uint32_t result = LLDB_INVALID_INDEX32;
75 lldb::QueueSP queue_sp = m_queue_wp.lock();
77 result = queue_sp->GetIndexID();
82 const char *GetName() const {
83 const char *name = nullptr;
84 lldb::QueueSP queue_sp = m_queue_wp.lock();
86 name = queue_sp->GetName();
92 if (!m_thread_list_fetched) {
93 lldb::QueueSP queue_sp = m_queue_wp.lock();
95 Process::StopLocker stop_locker;
96 if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
97 const std::vector<ThreadSP> thread_list(queue_sp->GetThreads());
98 m_thread_list_fetched = true;
99 const uint32_t num_threads = thread_list.size();
100 for (uint32_t idx = 0; idx < num_threads; ++idx) {
101 ThreadSP thread_sp = thread_list[idx];
102 if (thread_sp && thread_sp->IsValid()) {
103 m_threads.push_back(thread_sp);
112 if (!m_pending_items_fetched) {
113 QueueSP queue_sp = m_queue_wp.lock();
115 Process::StopLocker stop_locker;
116 if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
117 const std::vector<QueueItemSP> queue_items(
118 queue_sp->GetPendingItems());
119 m_pending_items_fetched = true;
120 const uint32_t num_pending_items = queue_items.size();
121 for (uint32_t idx = 0; idx < num_pending_items; ++idx) {
122 QueueItemSP item = queue_items[idx];
123 if (item && item->IsValid()) {
124 m_pending_items.push_back(item);
132 uint32_t GetNumThreads() {
136 if (m_thread_list_fetched) {
137 result = m_threads.size();
142 lldb::SBThread GetThreadAtIndex(uint32_t idx) {
146 QueueSP queue_sp = m_queue_wp.lock();
147 if (queue_sp && idx < m_threads.size()) {
148 ProcessSP process_sp = queue_sp->GetProcess();
150 ThreadSP thread_sp = m_threads[idx].lock();
152 sb_thread.SetThread(thread_sp);
159 uint32_t GetNumPendingItems() {
162 QueueSP queue_sp = m_queue_wp.lock();
163 if (!m_pending_items_fetched && queue_sp) {
164 result = queue_sp->GetNumPendingWorkItems();
166 result = m_pending_items.size();
171 lldb::SBQueueItem GetPendingItemAtIndex(uint32_t idx) {
174 if (m_pending_items_fetched && idx < m_pending_items.size()) {
175 result.SetQueueItem(m_pending_items[idx]);
180 uint32_t GetNumRunningItems() {
182 QueueSP queue_sp = m_queue_wp.lock();
184 result = queue_sp->GetNumRunningWorkItems();
188 lldb::SBProcess GetProcess() {
190 QueueSP queue_sp = m_queue_wp.lock();
192 result.SetSP(queue_sp->GetProcess());
197 lldb::QueueKind GetKind() {
198 lldb::QueueKind kind = eQueueKindUnknown;
199 QueueSP queue_sp = m_queue_wp.lock();
201 kind = queue_sp->GetKind();
207 lldb::QueueWP m_queue_wp;
208 std::vector<lldb::ThreadWP>
209 m_threads; // threads currently executing this queue's items
210 bool m_thread_list_fetched =
211 false; // have we tried to fetch the threads list already?
212 std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued
213 bool m_pending_items_fetched =
214 false; // have we tried to fetch the item list already?
218 SBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) { LLDB_INSTRUMENT_VA(this); }
220 SBQueue::SBQueue(const QueueSP &queue_sp)
221 : m_opaque_sp(new QueueImpl(queue_sp)) {
222 LLDB_INSTRUMENT_VA(this, queue_sp);
225 SBQueue::SBQueue(const SBQueue &rhs) {
226 LLDB_INSTRUMENT_VA(this, rhs);
231 m_opaque_sp = rhs.m_opaque_sp;
234 const lldb::SBQueue &SBQueue::operator=(const lldb::SBQueue &rhs) {
235 LLDB_INSTRUMENT_VA(this, rhs);
237 m_opaque_sp = rhs.m_opaque_sp;
241 SBQueue::~SBQueue() = default;
243 bool SBQueue::IsValid() const {
244 LLDB_INSTRUMENT_VA(this);
245 return this->operator bool();
247 SBQueue::operator bool() const {
248 LLDB_INSTRUMENT_VA(this);
250 return m_opaque_sp->IsValid();
253 void SBQueue::Clear() {
254 LLDB_INSTRUMENT_VA(this);
256 m_opaque_sp->Clear();
259 void SBQueue::SetQueue(const QueueSP &queue_sp) {
260 m_opaque_sp->SetQueue(queue_sp);
263 lldb::queue_id_t SBQueue::GetQueueID() const {
264 LLDB_INSTRUMENT_VA(this);
266 return m_opaque_sp->GetQueueID();
269 uint32_t SBQueue::GetIndexID() const {
270 LLDB_INSTRUMENT_VA(this);
272 uint32_t index_id = m_opaque_sp->GetIndexID();
276 const char *SBQueue::GetName() const {
277 LLDB_INSTRUMENT_VA(this);
279 return m_opaque_sp->GetName();
282 uint32_t SBQueue::GetNumThreads() {
283 LLDB_INSTRUMENT_VA(this);
285 return m_opaque_sp->GetNumThreads();
288 SBThread SBQueue::GetThreadAtIndex(uint32_t idx) {
289 LLDB_INSTRUMENT_VA(this, idx);
291 SBThread th = m_opaque_sp->GetThreadAtIndex(idx);
295 uint32_t SBQueue::GetNumPendingItems() {
296 LLDB_INSTRUMENT_VA(this);
298 return m_opaque_sp->GetNumPendingItems();
301 SBQueueItem SBQueue::GetPendingItemAtIndex(uint32_t idx) {
302 LLDB_INSTRUMENT_VA(this, idx);
304 return m_opaque_sp->GetPendingItemAtIndex(idx);
307 uint32_t SBQueue::GetNumRunningItems() {
308 LLDB_INSTRUMENT_VA(this);
310 return m_opaque_sp->GetNumRunningItems();
313 SBProcess SBQueue::GetProcess() {
314 LLDB_INSTRUMENT_VA(this);
316 return m_opaque_sp->GetProcess();
319 lldb::QueueKind SBQueue::GetKind() {
320 LLDB_INSTRUMENT_VA(this);
322 return m_opaque_sp->GetKind();