]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/source/API/SBQueue.cpp
Merge llvm-project main llvmorg-14-init-17616-g024a1fab5c35
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / source / API / SBQueue.cpp
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 "lldb/API/SBQueue.h"
12 #include "lldb/Utility/Instrumentation.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() {}
31
32   QueueImpl(const lldb::QueueSP &queue_sp)
33       : m_thread_list_fetched(false), m_pending_items_fetched(false) {
34     m_queue_wp = queue_sp;
35   }
36
37   QueueImpl(const QueueImpl &rhs) {
38     if (&rhs == this)
39       return;
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;
45   }
46
47   ~QueueImpl() = default;
48
49   bool IsValid() { return m_queue_wp.lock() != nullptr; }
50
51   void Clear() {
52     m_queue_wp.reset();
53     m_thread_list_fetched = false;
54     m_threads.clear();
55     m_pending_items_fetched = false;
56     m_pending_items.clear();
57   }
58
59   void SetQueue(const lldb::QueueSP &queue_sp) {
60     Clear();
61     m_queue_wp = queue_sp;
62   }
63
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();
67     if (queue_sp) {
68       result = queue_sp->GetID();
69     }
70     return result;
71   }
72
73   uint32_t GetIndexID() const {
74     uint32_t result = LLDB_INVALID_INDEX32;
75     lldb::QueueSP queue_sp = m_queue_wp.lock();
76     if (queue_sp) {
77       result = queue_sp->GetIndexID();
78     }
79     return result;
80   }
81
82   const char *GetName() const {
83     const char *name = nullptr;
84     lldb::QueueSP queue_sp = m_queue_wp.lock();
85     if (queue_sp.get()) {
86       name = queue_sp->GetName();
87     }
88     return name;
89   }
90
91   void FetchThreads() {
92     if (!m_thread_list_fetched) {
93       lldb::QueueSP queue_sp = m_queue_wp.lock();
94       if (queue_sp) {
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);
104             }
105           }
106         }
107       }
108     }
109   }
110
111   void FetchItems() {
112     if (!m_pending_items_fetched) {
113       QueueSP queue_sp = m_queue_wp.lock();
114       if (queue_sp) {
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);
125             }
126           }
127         }
128       }
129     }
130   }
131
132   uint32_t GetNumThreads() {
133     uint32_t result = 0;
134
135     FetchThreads();
136     if (m_thread_list_fetched) {
137       result = m_threads.size();
138     }
139     return result;
140   }
141
142   lldb::SBThread GetThreadAtIndex(uint32_t idx) {
143     FetchThreads();
144
145     SBThread sb_thread;
146     QueueSP queue_sp = m_queue_wp.lock();
147     if (queue_sp && idx < m_threads.size()) {
148       ProcessSP process_sp = queue_sp->GetProcess();
149       if (process_sp) {
150         ThreadSP thread_sp = m_threads[idx].lock();
151         if (thread_sp) {
152           sb_thread.SetThread(thread_sp);
153         }
154       }
155     }
156     return sb_thread;
157   }
158
159   uint32_t GetNumPendingItems() {
160     uint32_t result = 0;
161
162     QueueSP queue_sp = m_queue_wp.lock();
163     if (!m_pending_items_fetched && queue_sp) {
164       result = queue_sp->GetNumPendingWorkItems();
165     } else {
166       result = m_pending_items.size();
167     }
168     return result;
169   }
170
171   lldb::SBQueueItem GetPendingItemAtIndex(uint32_t idx) {
172     SBQueueItem result;
173     FetchItems();
174     if (m_pending_items_fetched && idx < m_pending_items.size()) {
175       result.SetQueueItem(m_pending_items[idx]);
176     }
177     return result;
178   }
179
180   uint32_t GetNumRunningItems() {
181     uint32_t result = 0;
182     QueueSP queue_sp = m_queue_wp.lock();
183     if (queue_sp)
184       result = queue_sp->GetNumRunningWorkItems();
185     return result;
186   }
187
188   lldb::SBProcess GetProcess() {
189     SBProcess result;
190     QueueSP queue_sp = m_queue_wp.lock();
191     if (queue_sp) {
192       result.SetSP(queue_sp->GetProcess());
193     }
194     return result;
195   }
196
197   lldb::QueueKind GetKind() {
198     lldb::QueueKind kind = eQueueKindUnknown;
199     QueueSP queue_sp = m_queue_wp.lock();
200     if (queue_sp)
201       kind = queue_sp->GetKind();
202
203     return kind;
204   }
205
206 private:
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?
215 };
216 }
217
218 SBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) { LLDB_INSTRUMENT_VA(this); }
219
220 SBQueue::SBQueue(const QueueSP &queue_sp)
221     : m_opaque_sp(new QueueImpl(queue_sp)) {
222   LLDB_INSTRUMENT_VA(this, queue_sp);
223 }
224
225 SBQueue::SBQueue(const SBQueue &rhs) {
226   LLDB_INSTRUMENT_VA(this, rhs);
227
228   if (&rhs == this)
229     return;
230
231   m_opaque_sp = rhs.m_opaque_sp;
232 }
233
234 const lldb::SBQueue &SBQueue::operator=(const lldb::SBQueue &rhs) {
235   LLDB_INSTRUMENT_VA(this, rhs);
236
237   m_opaque_sp = rhs.m_opaque_sp;
238   return *this;
239 }
240
241 SBQueue::~SBQueue() = default;
242
243 bool SBQueue::IsValid() const {
244   LLDB_INSTRUMENT_VA(this);
245   return this->operator bool();
246 }
247 SBQueue::operator bool() const {
248   LLDB_INSTRUMENT_VA(this);
249
250   return m_opaque_sp->IsValid();
251 }
252
253 void SBQueue::Clear() {
254   LLDB_INSTRUMENT_VA(this);
255
256   m_opaque_sp->Clear();
257 }
258
259 void SBQueue::SetQueue(const QueueSP &queue_sp) {
260   m_opaque_sp->SetQueue(queue_sp);
261 }
262
263 lldb::queue_id_t SBQueue::GetQueueID() const {
264   LLDB_INSTRUMENT_VA(this);
265
266   return m_opaque_sp->GetQueueID();
267 }
268
269 uint32_t SBQueue::GetIndexID() const {
270   LLDB_INSTRUMENT_VA(this);
271
272   uint32_t index_id = m_opaque_sp->GetIndexID();
273   return index_id;
274 }
275
276 const char *SBQueue::GetName() const {
277   LLDB_INSTRUMENT_VA(this);
278
279   return m_opaque_sp->GetName();
280 }
281
282 uint32_t SBQueue::GetNumThreads() {
283   LLDB_INSTRUMENT_VA(this);
284
285   return m_opaque_sp->GetNumThreads();
286 }
287
288 SBThread SBQueue::GetThreadAtIndex(uint32_t idx) {
289   LLDB_INSTRUMENT_VA(this, idx);
290
291   SBThread th = m_opaque_sp->GetThreadAtIndex(idx);
292   return th;
293 }
294
295 uint32_t SBQueue::GetNumPendingItems() {
296   LLDB_INSTRUMENT_VA(this);
297
298   return m_opaque_sp->GetNumPendingItems();
299 }
300
301 SBQueueItem SBQueue::GetPendingItemAtIndex(uint32_t idx) {
302   LLDB_INSTRUMENT_VA(this, idx);
303
304   return m_opaque_sp->GetPendingItemAtIndex(idx);
305 }
306
307 uint32_t SBQueue::GetNumRunningItems() {
308   LLDB_INSTRUMENT_VA(this);
309
310   return m_opaque_sp->GetNumRunningItems();
311 }
312
313 SBProcess SBQueue::GetProcess() {
314   LLDB_INSTRUMENT_VA(this);
315
316   return m_opaque_sp->GetProcess();
317 }
318
319 lldb::QueueKind SBQueue::GetKind() {
320   LLDB_INSTRUMENT_VA(this);
321
322   return m_opaque_sp->GetKind();
323 }