15e8dce4dSJason Molenda //===-- SBQueue.cpp ---------------------------------------------*- C++ -*-===//
25e8dce4dSJason Molenda //
3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information.
5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
65e8dce4dSJason Molenda //
75e8dce4dSJason Molenda //===----------------------------------------------------------------------===//
85e8dce4dSJason Molenda 
9da0fc76eSVirgile Bello #include <inttypes.h>
10da0fc76eSVirgile Bello 
115e8dce4dSJason Molenda #include "lldb/API/SBQueue.h"
125e8dce4dSJason Molenda 
135e8dce4dSJason Molenda #include "lldb/API/SBProcess.h"
14b9ffa98cSJason Molenda #include "lldb/API/SBQueueItem.h"
15b9c1b51eSKate Stone #include "lldb/API/SBThread.h"
16b9ffa98cSJason Molenda 
175e8dce4dSJason Molenda #include "lldb/Target/Process.h"
185e8dce4dSJason Molenda #include "lldb/Target/Queue.h"
195e8dce4dSJason Molenda #include "lldb/Target/QueueItem.h"
205e8dce4dSJason Molenda #include "lldb/Target/Thread.h"
216f9e6901SZachary Turner #include "lldb/Utility/Log.h"
225e8dce4dSJason Molenda 
235e8dce4dSJason Molenda using namespace lldb;
245e8dce4dSJason Molenda using namespace lldb_private;
255e8dce4dSJason Molenda 
26b9c1b51eSKate Stone namespace lldb_private {
27c8064ac6SJason Molenda 
28b9c1b51eSKate Stone class QueueImpl {
29c8064ac6SJason Molenda public:
30b9c1b51eSKate Stone   QueueImpl()
31b9c1b51eSKate Stone       : m_queue_wp(), m_threads(), m_thread_list_fetched(false),
32b9c1b51eSKate Stone         m_pending_items(), m_pending_items_fetched(false) {}
335e8dce4dSJason Molenda 
34b9c1b51eSKate Stone   QueueImpl(const lldb::QueueSP &queue_sp)
35b9c1b51eSKate Stone       : m_queue_wp(), m_threads(), m_thread_list_fetched(false),
36b9c1b51eSKate Stone         m_pending_items(), m_pending_items_fetched(false) {
37b97f44d9SJason Molenda     m_queue_wp = queue_sp;
385e8dce4dSJason Molenda   }
395e8dce4dSJason Molenda 
40b9c1b51eSKate Stone   QueueImpl(const QueueImpl &rhs) {
41c8064ac6SJason Molenda     if (&rhs == this)
42c8064ac6SJason Molenda       return;
43c8064ac6SJason Molenda     m_queue_wp = rhs.m_queue_wp;
44c8064ac6SJason Molenda     m_threads = rhs.m_threads;
45c8064ac6SJason Molenda     m_thread_list_fetched = rhs.m_thread_list_fetched;
462fd83355SJason Molenda     m_pending_items = rhs.m_pending_items;
472fd83355SJason Molenda     m_pending_items_fetched = rhs.m_pending_items_fetched;
48c8064ac6SJason Molenda   }
49c8064ac6SJason Molenda 
50b9c1b51eSKate Stone   ~QueueImpl() {}
515e8dce4dSJason Molenda 
52b9c1b51eSKate Stone   bool IsValid() { return m_queue_wp.lock() != NULL; }
535e8dce4dSJason Molenda 
54b9c1b51eSKate Stone   void Clear() {
555e8dce4dSJason Molenda     m_queue_wp.reset();
565e8dce4dSJason Molenda     m_thread_list_fetched = false;
575e8dce4dSJason Molenda     m_threads.clear();
582fd83355SJason Molenda     m_pending_items_fetched = false;
592fd83355SJason Molenda     m_pending_items.clear();
605e8dce4dSJason Molenda   }
615e8dce4dSJason Molenda 
62b9c1b51eSKate Stone   void SetQueue(const lldb::QueueSP &queue_sp) {
63c8064ac6SJason Molenda     Clear();
645e8dce4dSJason Molenda     m_queue_wp = queue_sp;
655e8dce4dSJason Molenda   }
665e8dce4dSJason Molenda 
67b9c1b51eSKate Stone   lldb::queue_id_t GetQueueID() const {
68c8064ac6SJason Molenda     lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID;
69c8064ac6SJason Molenda     lldb::QueueSP queue_sp = m_queue_wp.lock();
70b9c1b51eSKate Stone     if (queue_sp) {
715e8dce4dSJason Molenda       result = queue_sp->GetID();
725e8dce4dSJason Molenda     }
735e8dce4dSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
745e8dce4dSJason Molenda     if (log)
75324a1036SSaleem Abdulrasool       log->Printf("SBQueue(%p)::GetQueueID () => 0x%" PRIx64,
76324a1036SSaleem Abdulrasool                   static_cast<const void *>(this), result);
775e8dce4dSJason Molenda     return result;
785e8dce4dSJason Molenda   }
795e8dce4dSJason Molenda 
80b9c1b51eSKate Stone   uint32_t GetIndexID() const {
815e8dce4dSJason Molenda     uint32_t result = LLDB_INVALID_INDEX32;
82c8064ac6SJason Molenda     lldb::QueueSP queue_sp = m_queue_wp.lock();
83b9c1b51eSKate Stone     if (queue_sp) {
845e8dce4dSJason Molenda       result = queue_sp->GetIndexID();
855e8dce4dSJason Molenda     }
865e8dce4dSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
875e8dce4dSJason Molenda     if (log)
88324a1036SSaleem Abdulrasool       log->Printf("SBQueueImpl(%p)::GetIndexID () => %d",
89324a1036SSaleem Abdulrasool                   static_cast<const void *>(this), result);
905e8dce4dSJason Molenda     return result;
915e8dce4dSJason Molenda   }
925e8dce4dSJason Molenda 
93b9c1b51eSKate Stone   const char *GetName() const {
945e8dce4dSJason Molenda     const char *name = NULL;
95c8064ac6SJason Molenda     lldb::QueueSP queue_sp = m_queue_wp.lock();
96b9c1b51eSKate Stone     if (queue_sp.get()) {
975e8dce4dSJason Molenda       name = queue_sp->GetName();
985e8dce4dSJason Molenda     }
995e8dce4dSJason Molenda 
1005e8dce4dSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1015e8dce4dSJason Molenda     if (log)
102324a1036SSaleem Abdulrasool       log->Printf("SBQueueImpl(%p)::GetName () => %s",
103b9c1b51eSKate Stone                   static_cast<const void *>(this), name ? name : "NULL");
1045e8dce4dSJason Molenda 
1055e8dce4dSJason Molenda     return name;
1065e8dce4dSJason Molenda   }
1075e8dce4dSJason Molenda 
108b9c1b51eSKate Stone   void FetchThreads() {
109a6682a41SJonas Devlieghere     if (!m_thread_list_fetched) {
110c8064ac6SJason Molenda       lldb::QueueSP queue_sp = m_queue_wp.lock();
111b9c1b51eSKate Stone       if (queue_sp) {
1125e8dce4dSJason Molenda         Process::StopLocker stop_locker;
113b9c1b51eSKate Stone         if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
1145e8dce4dSJason Molenda           const std::vector<ThreadSP> thread_list(queue_sp->GetThreads());
1155e8dce4dSJason Molenda           m_thread_list_fetched = true;
1165e8dce4dSJason Molenda           const uint32_t num_threads = thread_list.size();
117b9c1b51eSKate Stone           for (uint32_t idx = 0; idx < num_threads; ++idx) {
1185e8dce4dSJason Molenda             ThreadSP thread_sp = thread_list[idx];
119b9c1b51eSKate Stone             if (thread_sp && thread_sp->IsValid()) {
1205e8dce4dSJason Molenda               m_threads.push_back(thread_sp);
1215e8dce4dSJason Molenda             }
1225e8dce4dSJason Molenda           }
1235e8dce4dSJason Molenda         }
1245e8dce4dSJason Molenda       }
1255e8dce4dSJason Molenda     }
1265e8dce4dSJason Molenda   }
1275e8dce4dSJason Molenda 
128b9c1b51eSKate Stone   void FetchItems() {
129a6682a41SJonas Devlieghere     if (!m_pending_items_fetched) {
1305e8dce4dSJason Molenda       QueueSP queue_sp = m_queue_wp.lock();
131b9c1b51eSKate Stone       if (queue_sp) {
1325e8dce4dSJason Molenda         Process::StopLocker stop_locker;
133b9c1b51eSKate Stone         if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
134b9c1b51eSKate Stone           const std::vector<QueueItemSP> queue_items(
135b9c1b51eSKate Stone               queue_sp->GetPendingItems());
1362fd83355SJason Molenda           m_pending_items_fetched = true;
1372fd83355SJason Molenda           const uint32_t num_pending_items = queue_items.size();
138b9c1b51eSKate Stone           for (uint32_t idx = 0; idx < num_pending_items; ++idx) {
1395e8dce4dSJason Molenda             QueueItemSP item = queue_items[idx];
140b9c1b51eSKate Stone             if (item && item->IsValid()) {
1412fd83355SJason Molenda               m_pending_items.push_back(item);
1425e8dce4dSJason Molenda             }
1435e8dce4dSJason Molenda           }
1445e8dce4dSJason Molenda         }
1455e8dce4dSJason Molenda       }
1465e8dce4dSJason Molenda     }
1475e8dce4dSJason Molenda   }
1485e8dce4dSJason Molenda 
149b9c1b51eSKate Stone   uint32_t GetNumThreads() {
1505e8dce4dSJason Molenda     uint32_t result = 0;
1515e8dce4dSJason Molenda 
1525e8dce4dSJason Molenda     FetchThreads();
153b9c1b51eSKate Stone     if (m_thread_list_fetched) {
1545e8dce4dSJason Molenda       result = m_threads.size();
1555e8dce4dSJason Molenda     }
1565e8dce4dSJason Molenda     return result;
1575e8dce4dSJason Molenda   }
1585e8dce4dSJason Molenda 
159b9c1b51eSKate Stone   lldb::SBThread GetThreadAtIndex(uint32_t idx) {
1605e8dce4dSJason Molenda     FetchThreads();
1615e8dce4dSJason Molenda 
1625e8dce4dSJason Molenda     SBThread sb_thread;
1635e8dce4dSJason Molenda     QueueSP queue_sp = m_queue_wp.lock();
164b9c1b51eSKate Stone     if (queue_sp && idx < m_threads.size()) {
1655e8dce4dSJason Molenda       ProcessSP process_sp = queue_sp->GetProcess();
166b9c1b51eSKate Stone       if (process_sp) {
1675e8dce4dSJason Molenda         ThreadSP thread_sp = m_threads[idx].lock();
168b9c1b51eSKate Stone         if (thread_sp) {
1695e8dce4dSJason Molenda           sb_thread.SetThread(thread_sp);
1705e8dce4dSJason Molenda         }
1715e8dce4dSJason Molenda       }
1725e8dce4dSJason Molenda     }
1735e8dce4dSJason Molenda     return sb_thread;
1745e8dce4dSJason Molenda   }
1755e8dce4dSJason Molenda 
176b9c1b51eSKate Stone   uint32_t GetNumPendingItems() {
1775e8dce4dSJason Molenda     uint32_t result = 0;
1785e8dce4dSJason Molenda 
179fe95dc95SJason Molenda     QueueSP queue_sp = m_queue_wp.lock();
180a6682a41SJonas Devlieghere     if (!m_pending_items_fetched && queue_sp) {
181fe95dc95SJason Molenda       result = queue_sp->GetNumPendingWorkItems();
182b9c1b51eSKate Stone     } else {
1832fd83355SJason Molenda       result = m_pending_items.size();
1845e8dce4dSJason Molenda     }
1855e8dce4dSJason Molenda     return result;
1865e8dce4dSJason Molenda   }
1875e8dce4dSJason Molenda 
188b9c1b51eSKate Stone   lldb::SBQueueItem GetPendingItemAtIndex(uint32_t idx) {
1895e8dce4dSJason Molenda     SBQueueItem result;
1905e8dce4dSJason Molenda     FetchItems();
191b9c1b51eSKate Stone     if (m_pending_items_fetched && idx < m_pending_items.size()) {
1922fd83355SJason Molenda       result.SetQueueItem(m_pending_items[idx]);
1935e8dce4dSJason Molenda     }
1945e8dce4dSJason Molenda     return result;
1955e8dce4dSJason Molenda   }
1965e8dce4dSJason Molenda 
197b9c1b51eSKate Stone   uint32_t GetNumRunningItems() {
198fe95dc95SJason Molenda     uint32_t result = 0;
199fe95dc95SJason Molenda     QueueSP queue_sp = m_queue_wp.lock();
200fe95dc95SJason Molenda     if (queue_sp)
201fe95dc95SJason Molenda       result = queue_sp->GetNumRunningWorkItems();
202fe95dc95SJason Molenda     return result;
203fe95dc95SJason Molenda   }
204fe95dc95SJason Molenda 
205b9c1b51eSKate Stone   lldb::SBProcess GetProcess() {
2065e8dce4dSJason Molenda     SBProcess result;
2075e8dce4dSJason Molenda     QueueSP queue_sp = m_queue_wp.lock();
208b9c1b51eSKate Stone     if (queue_sp) {
2095e8dce4dSJason Molenda       result.SetSP(queue_sp->GetProcess());
2105e8dce4dSJason Molenda     }
2115e8dce4dSJason Molenda     return result;
2125e8dce4dSJason Molenda   }
213c8064ac6SJason Molenda 
214b9c1b51eSKate Stone   lldb::QueueKind GetKind() {
215aac16e0fSJason Molenda     lldb::QueueKind kind = eQueueKindUnknown;
216aac16e0fSJason Molenda     QueueSP queue_sp = m_queue_wp.lock();
217aac16e0fSJason Molenda     if (queue_sp)
218aac16e0fSJason Molenda       kind = queue_sp->GetKind();
219aac16e0fSJason Molenda 
220aac16e0fSJason Molenda     return kind;
221aac16e0fSJason Molenda   }
222aac16e0fSJason Molenda 
223c8064ac6SJason Molenda private:
224c8064ac6SJason Molenda   lldb::QueueWP m_queue_wp;
225b9c1b51eSKate Stone   std::vector<lldb::ThreadWP>
226b9c1b51eSKate Stone       m_threads; // threads currently executing this queue's items
227b9c1b51eSKate Stone   bool
228b9c1b51eSKate Stone       m_thread_list_fetched; // have we tried to fetch the threads list already?
2292fd83355SJason Molenda   std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued
2302fd83355SJason Molenda   bool m_pending_items_fetched; // have we tried to fetch the item list already?
231c8064ac6SJason Molenda };
232c8064ac6SJason Molenda }
233c8064ac6SJason Molenda 
234b9c1b51eSKate Stone SBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) {}
235c8064ac6SJason Molenda 
236b9c1b51eSKate Stone SBQueue::SBQueue(const QueueSP &queue_sp)
237b9c1b51eSKate Stone     : m_opaque_sp(new QueueImpl(queue_sp)) {}
238c8064ac6SJason Molenda 
239b9c1b51eSKate Stone SBQueue::SBQueue(const SBQueue &rhs) {
240c8064ac6SJason Molenda   if (&rhs == this)
241c8064ac6SJason Molenda     return;
242c8064ac6SJason Molenda 
243c8064ac6SJason Molenda   m_opaque_sp = rhs.m_opaque_sp;
244c8064ac6SJason Molenda }
245c8064ac6SJason Molenda 
246b9c1b51eSKate Stone const lldb::SBQueue &SBQueue::operator=(const lldb::SBQueue &rhs) {
247c8064ac6SJason Molenda   m_opaque_sp = rhs.m_opaque_sp;
248c8064ac6SJason Molenda   return *this;
249c8064ac6SJason Molenda }
250c8064ac6SJason Molenda 
251b9c1b51eSKate Stone SBQueue::~SBQueue() {}
252c8064ac6SJason Molenda 
253b9c1b51eSKate Stone bool SBQueue::IsValid() const {
254ac605f4aSJason Molenda   bool is_valid = m_opaque_sp->IsValid();
255ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
256ac605f4aSJason Molenda   if (log)
257b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::IsValid() == %s",
258b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), is_valid ? "true" : "false");
259ac605f4aSJason Molenda   return is_valid;
260c8064ac6SJason Molenda }
261c8064ac6SJason Molenda 
262b9c1b51eSKate Stone void SBQueue::Clear() {
263ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
264ac605f4aSJason Molenda   if (log)
265ac605f4aSJason Molenda     log->Printf("SBQueue(0x%" PRIx64 ")::Clear()", m_opaque_sp->GetQueueID());
266c8064ac6SJason Molenda   m_opaque_sp->Clear();
267c8064ac6SJason Molenda }
268c8064ac6SJason Molenda 
269b9c1b51eSKate Stone void SBQueue::SetQueue(const QueueSP &queue_sp) {
270c8064ac6SJason Molenda   m_opaque_sp->SetQueue(queue_sp);
271c8064ac6SJason Molenda }
272c8064ac6SJason Molenda 
273b9c1b51eSKate Stone lldb::queue_id_t SBQueue::GetQueueID() const {
274ac605f4aSJason Molenda   lldb::queue_id_t qid = m_opaque_sp->GetQueueID();
275ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
276ac605f4aSJason Molenda   if (log)
277b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetQueueID() == 0x%" PRIx64,
278b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), (uint64_t)qid);
279ac605f4aSJason Molenda   return qid;
280c8064ac6SJason Molenda }
281c8064ac6SJason Molenda 
282b9c1b51eSKate Stone uint32_t SBQueue::GetIndexID() const {
283ac605f4aSJason Molenda   uint32_t index_id = m_opaque_sp->GetIndexID();
284ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
285ac605f4aSJason Molenda   if (log)
286b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetIndexID() == 0x%" PRIx32,
287b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), index_id);
288ac605f4aSJason Molenda   return index_id;
289c8064ac6SJason Molenda }
290c8064ac6SJason Molenda 
291b9c1b51eSKate Stone const char *SBQueue::GetName() const {
292ac605f4aSJason Molenda   const char *name = m_opaque_sp->GetName();
293ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
294ac605f4aSJason Molenda   if (log)
295b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetName() == %s",
296b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), name ? name : "");
297ac605f4aSJason Molenda   return name;
298c8064ac6SJason Molenda }
299c8064ac6SJason Molenda 
300b9c1b51eSKate Stone uint32_t SBQueue::GetNumThreads() {
301ac605f4aSJason Molenda   uint32_t numthreads = m_opaque_sp->GetNumThreads();
302ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
303ac605f4aSJason Molenda   if (log)
304b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetNumThreads() == %d",
305b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), numthreads);
306ac605f4aSJason Molenda   return numthreads;
307c8064ac6SJason Molenda }
308c8064ac6SJason Molenda 
309b9c1b51eSKate Stone SBThread SBQueue::GetThreadAtIndex(uint32_t idx) {
310ac605f4aSJason Molenda   SBThread th = m_opaque_sp->GetThreadAtIndex(idx);
311ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
312ac605f4aSJason Molenda   if (log)
313b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetThreadAtIndex(%d)",
314b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), idx);
315ac605f4aSJason Molenda   return th;
316c8064ac6SJason Molenda }
317c8064ac6SJason Molenda 
318b9c1b51eSKate Stone uint32_t SBQueue::GetNumPendingItems() {
319ac605f4aSJason Molenda   uint32_t pending_items = m_opaque_sp->GetNumPendingItems();
320ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
321ac605f4aSJason Molenda   if (log)
322b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetNumPendingItems() == %d",
323b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), pending_items);
324ac605f4aSJason Molenda   return pending_items;
325c8064ac6SJason Molenda }
326c8064ac6SJason Molenda 
327b9c1b51eSKate Stone SBQueueItem SBQueue::GetPendingItemAtIndex(uint32_t idx) {
328ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
329ac605f4aSJason Molenda   if (log)
330b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetPendingItemAtIndex(%d)",
331b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), idx);
3322fd83355SJason Molenda   return m_opaque_sp->GetPendingItemAtIndex(idx);
333c8064ac6SJason Molenda }
334c8064ac6SJason Molenda 
335b9c1b51eSKate Stone uint32_t SBQueue::GetNumRunningItems() {
336fe95dc95SJason Molenda   uint32_t running_items = m_opaque_sp->GetNumRunningItems();
337fe95dc95SJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
338fe95dc95SJason Molenda   if (log)
339b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetNumRunningItems() == %d",
340b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), running_items);
341fe95dc95SJason Molenda   return running_items;
342fe95dc95SJason Molenda }
343fe95dc95SJason Molenda 
344b9c1b51eSKate Stone SBProcess SBQueue::GetProcess() { return m_opaque_sp->GetProcess(); }
345aac16e0fSJason Molenda 
346b9c1b51eSKate Stone lldb::QueueKind SBQueue::GetKind() { return m_opaque_sp->GetKind(); }
347