15e8dce4dSJason Molenda //===-- SBQueue.cpp ---------------------------------------------*- C++ -*-===//
25e8dce4dSJason Molenda //
35e8dce4dSJason Molenda //                     The LLVM Compiler Infrastructure
45e8dce4dSJason Molenda //
55e8dce4dSJason Molenda // This file is distributed under the University of Illinois Open Source
65e8dce4dSJason Molenda // License. See LICENSE.TXT for details.
75e8dce4dSJason Molenda //
85e8dce4dSJason Molenda //===----------------------------------------------------------------------===//
95e8dce4dSJason Molenda 
10da0fc76eSVirgile Bello #include <inttypes.h>
11da0fc76eSVirgile Bello 
125e8dce4dSJason Molenda #include "lldb/API/SBQueue.h"
135e8dce4dSJason Molenda 
145e8dce4dSJason Molenda #include "lldb/API/SBProcess.h"
15b9ffa98cSJason Molenda #include "lldb/API/SBQueueItem.h"
16b9c1b51eSKate Stone #include "lldb/API/SBThread.h"
17b9ffa98cSJason Molenda 
185e8dce4dSJason Molenda #include "lldb/Target/Process.h"
195e8dce4dSJason Molenda #include "lldb/Target/Queue.h"
205e8dce4dSJason Molenda #include "lldb/Target/QueueItem.h"
215e8dce4dSJason Molenda #include "lldb/Target/Thread.h"
22*6f9e6901SZachary Turner #include "lldb/Utility/Log.h"
235e8dce4dSJason Molenda 
245e8dce4dSJason Molenda using namespace lldb;
255e8dce4dSJason Molenda using namespace lldb_private;
265e8dce4dSJason Molenda 
27b9c1b51eSKate Stone namespace lldb_private {
28c8064ac6SJason Molenda 
29b9c1b51eSKate Stone class QueueImpl {
30c8064ac6SJason Molenda public:
31b9c1b51eSKate Stone   QueueImpl()
32b9c1b51eSKate Stone       : m_queue_wp(), m_threads(), m_thread_list_fetched(false),
33b9c1b51eSKate Stone         m_pending_items(), m_pending_items_fetched(false) {}
345e8dce4dSJason Molenda 
35b9c1b51eSKate Stone   QueueImpl(const lldb::QueueSP &queue_sp)
36b9c1b51eSKate Stone       : m_queue_wp(), m_threads(), m_thread_list_fetched(false),
37b9c1b51eSKate Stone         m_pending_items(), m_pending_items_fetched(false) {
38b97f44d9SJason Molenda     m_queue_wp = queue_sp;
395e8dce4dSJason Molenda   }
405e8dce4dSJason Molenda 
41b9c1b51eSKate Stone   QueueImpl(const QueueImpl &rhs) {
42c8064ac6SJason Molenda     if (&rhs == this)
43c8064ac6SJason Molenda       return;
44c8064ac6SJason Molenda     m_queue_wp = rhs.m_queue_wp;
45c8064ac6SJason Molenda     m_threads = rhs.m_threads;
46c8064ac6SJason Molenda     m_thread_list_fetched = rhs.m_thread_list_fetched;
472fd83355SJason Molenda     m_pending_items = rhs.m_pending_items;
482fd83355SJason Molenda     m_pending_items_fetched = rhs.m_pending_items_fetched;
49c8064ac6SJason Molenda   }
50c8064ac6SJason Molenda 
51b9c1b51eSKate Stone   ~QueueImpl() {}
525e8dce4dSJason Molenda 
53b9c1b51eSKate Stone   bool IsValid() { return m_queue_wp.lock() != NULL; }
545e8dce4dSJason Molenda 
55b9c1b51eSKate Stone   void Clear() {
565e8dce4dSJason Molenda     m_queue_wp.reset();
575e8dce4dSJason Molenda     m_thread_list_fetched = false;
585e8dce4dSJason Molenda     m_threads.clear();
592fd83355SJason Molenda     m_pending_items_fetched = false;
602fd83355SJason Molenda     m_pending_items.clear();
615e8dce4dSJason Molenda   }
625e8dce4dSJason Molenda 
63b9c1b51eSKate Stone   void SetQueue(const lldb::QueueSP &queue_sp) {
64c8064ac6SJason Molenda     Clear();
655e8dce4dSJason Molenda     m_queue_wp = queue_sp;
665e8dce4dSJason Molenda   }
675e8dce4dSJason Molenda 
68b9c1b51eSKate Stone   lldb::queue_id_t GetQueueID() const {
69c8064ac6SJason Molenda     lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID;
70c8064ac6SJason Molenda     lldb::QueueSP queue_sp = m_queue_wp.lock();
71b9c1b51eSKate Stone     if (queue_sp) {
725e8dce4dSJason Molenda       result = queue_sp->GetID();
735e8dce4dSJason Molenda     }
745e8dce4dSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
755e8dce4dSJason Molenda     if (log)
76324a1036SSaleem Abdulrasool       log->Printf("SBQueue(%p)::GetQueueID () => 0x%" PRIx64,
77324a1036SSaleem Abdulrasool                   static_cast<const void *>(this), result);
785e8dce4dSJason Molenda     return result;
795e8dce4dSJason Molenda   }
805e8dce4dSJason Molenda 
81b9c1b51eSKate Stone   uint32_t GetIndexID() const {
825e8dce4dSJason Molenda     uint32_t result = LLDB_INVALID_INDEX32;
83c8064ac6SJason Molenda     lldb::QueueSP queue_sp = m_queue_wp.lock();
84b9c1b51eSKate Stone     if (queue_sp) {
855e8dce4dSJason Molenda       result = queue_sp->GetIndexID();
865e8dce4dSJason Molenda     }
875e8dce4dSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
885e8dce4dSJason Molenda     if (log)
89324a1036SSaleem Abdulrasool       log->Printf("SBQueueImpl(%p)::GetIndexID () => %d",
90324a1036SSaleem Abdulrasool                   static_cast<const void *>(this), result);
915e8dce4dSJason Molenda     return result;
925e8dce4dSJason Molenda   }
935e8dce4dSJason Molenda 
94b9c1b51eSKate Stone   const char *GetName() const {
955e8dce4dSJason Molenda     const char *name = NULL;
96c8064ac6SJason Molenda     lldb::QueueSP queue_sp = m_queue_wp.lock();
97b9c1b51eSKate Stone     if (queue_sp.get()) {
985e8dce4dSJason Molenda       name = queue_sp->GetName();
995e8dce4dSJason Molenda     }
1005e8dce4dSJason Molenda 
1015e8dce4dSJason Molenda     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
1025e8dce4dSJason Molenda     if (log)
103324a1036SSaleem Abdulrasool       log->Printf("SBQueueImpl(%p)::GetName () => %s",
104b9c1b51eSKate Stone                   static_cast<const void *>(this), name ? name : "NULL");
1055e8dce4dSJason Molenda 
1065e8dce4dSJason Molenda     return name;
1075e8dce4dSJason Molenda   }
1085e8dce4dSJason Molenda 
109b9c1b51eSKate Stone   void FetchThreads() {
110b9c1b51eSKate Stone     if (m_thread_list_fetched == false) {
111c8064ac6SJason Molenda       lldb::QueueSP queue_sp = m_queue_wp.lock();
112b9c1b51eSKate Stone       if (queue_sp) {
1135e8dce4dSJason Molenda         Process::StopLocker stop_locker;
114b9c1b51eSKate Stone         if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
1155e8dce4dSJason Molenda           const std::vector<ThreadSP> thread_list(queue_sp->GetThreads());
1165e8dce4dSJason Molenda           m_thread_list_fetched = true;
1175e8dce4dSJason Molenda           const uint32_t num_threads = thread_list.size();
118b9c1b51eSKate Stone           for (uint32_t idx = 0; idx < num_threads; ++idx) {
1195e8dce4dSJason Molenda             ThreadSP thread_sp = thread_list[idx];
120b9c1b51eSKate Stone             if (thread_sp && thread_sp->IsValid()) {
1215e8dce4dSJason Molenda               m_threads.push_back(thread_sp);
1225e8dce4dSJason Molenda             }
1235e8dce4dSJason Molenda           }
1245e8dce4dSJason Molenda         }
1255e8dce4dSJason Molenda       }
1265e8dce4dSJason Molenda     }
1275e8dce4dSJason Molenda   }
1285e8dce4dSJason Molenda 
129b9c1b51eSKate Stone   void FetchItems() {
130b9c1b51eSKate Stone     if (m_pending_items_fetched == false) {
1315e8dce4dSJason Molenda       QueueSP queue_sp = m_queue_wp.lock();
132b9c1b51eSKate Stone       if (queue_sp) {
1335e8dce4dSJason Molenda         Process::StopLocker stop_locker;
134b9c1b51eSKate Stone         if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
135b9c1b51eSKate Stone           const std::vector<QueueItemSP> queue_items(
136b9c1b51eSKate Stone               queue_sp->GetPendingItems());
1372fd83355SJason Molenda           m_pending_items_fetched = true;
1382fd83355SJason Molenda           const uint32_t num_pending_items = queue_items.size();
139b9c1b51eSKate Stone           for (uint32_t idx = 0; idx < num_pending_items; ++idx) {
1405e8dce4dSJason Molenda             QueueItemSP item = queue_items[idx];
141b9c1b51eSKate Stone             if (item && item->IsValid()) {
1422fd83355SJason Molenda               m_pending_items.push_back(item);
1435e8dce4dSJason Molenda             }
1445e8dce4dSJason Molenda           }
1455e8dce4dSJason Molenda         }
1465e8dce4dSJason Molenda       }
1475e8dce4dSJason Molenda     }
1485e8dce4dSJason Molenda   }
1495e8dce4dSJason Molenda 
150b9c1b51eSKate Stone   uint32_t GetNumThreads() {
1515e8dce4dSJason Molenda     uint32_t result = 0;
1525e8dce4dSJason Molenda 
1535e8dce4dSJason Molenda     FetchThreads();
154b9c1b51eSKate Stone     if (m_thread_list_fetched) {
1555e8dce4dSJason Molenda       result = m_threads.size();
1565e8dce4dSJason Molenda     }
1575e8dce4dSJason Molenda     return result;
1585e8dce4dSJason Molenda   }
1595e8dce4dSJason Molenda 
160b9c1b51eSKate Stone   lldb::SBThread GetThreadAtIndex(uint32_t idx) {
1615e8dce4dSJason Molenda     FetchThreads();
1625e8dce4dSJason Molenda 
1635e8dce4dSJason Molenda     SBThread sb_thread;
1645e8dce4dSJason Molenda     QueueSP queue_sp = m_queue_wp.lock();
165b9c1b51eSKate Stone     if (queue_sp && idx < m_threads.size()) {
1665e8dce4dSJason Molenda       ProcessSP process_sp = queue_sp->GetProcess();
167b9c1b51eSKate Stone       if (process_sp) {
1685e8dce4dSJason Molenda         ThreadSP thread_sp = m_threads[idx].lock();
169b9c1b51eSKate Stone         if (thread_sp) {
1705e8dce4dSJason Molenda           sb_thread.SetThread(thread_sp);
1715e8dce4dSJason Molenda         }
1725e8dce4dSJason Molenda       }
1735e8dce4dSJason Molenda     }
1745e8dce4dSJason Molenda     return sb_thread;
1755e8dce4dSJason Molenda   }
1765e8dce4dSJason Molenda 
177b9c1b51eSKate Stone   uint32_t GetNumPendingItems() {
1785e8dce4dSJason Molenda     uint32_t result = 0;
1795e8dce4dSJason Molenda 
180fe95dc95SJason Molenda     QueueSP queue_sp = m_queue_wp.lock();
181b9c1b51eSKate Stone     if (m_pending_items_fetched == false && queue_sp) {
182fe95dc95SJason Molenda       result = queue_sp->GetNumPendingWorkItems();
183b9c1b51eSKate Stone     } else {
1842fd83355SJason Molenda       result = m_pending_items.size();
1855e8dce4dSJason Molenda     }
1865e8dce4dSJason Molenda     return result;
1875e8dce4dSJason Molenda   }
1885e8dce4dSJason Molenda 
189b9c1b51eSKate Stone   lldb::SBQueueItem GetPendingItemAtIndex(uint32_t idx) {
1905e8dce4dSJason Molenda     SBQueueItem result;
1915e8dce4dSJason Molenda     FetchItems();
192b9c1b51eSKate Stone     if (m_pending_items_fetched && idx < m_pending_items.size()) {
1932fd83355SJason Molenda       result.SetQueueItem(m_pending_items[idx]);
1945e8dce4dSJason Molenda     }
1955e8dce4dSJason Molenda     return result;
1965e8dce4dSJason Molenda   }
1975e8dce4dSJason Molenda 
198b9c1b51eSKate Stone   uint32_t GetNumRunningItems() {
199fe95dc95SJason Molenda     uint32_t result = 0;
200fe95dc95SJason Molenda     QueueSP queue_sp = m_queue_wp.lock();
201fe95dc95SJason Molenda     if (queue_sp)
202fe95dc95SJason Molenda       result = queue_sp->GetNumRunningWorkItems();
203fe95dc95SJason Molenda     return result;
204fe95dc95SJason Molenda   }
205fe95dc95SJason Molenda 
206b9c1b51eSKate Stone   lldb::SBProcess GetProcess() {
2075e8dce4dSJason Molenda     SBProcess result;
2085e8dce4dSJason Molenda     QueueSP queue_sp = m_queue_wp.lock();
209b9c1b51eSKate Stone     if (queue_sp) {
2105e8dce4dSJason Molenda       result.SetSP(queue_sp->GetProcess());
2115e8dce4dSJason Molenda     }
2125e8dce4dSJason Molenda     return result;
2135e8dce4dSJason Molenda   }
214c8064ac6SJason Molenda 
215b9c1b51eSKate Stone   lldb::QueueKind GetKind() {
216aac16e0fSJason Molenda     lldb::QueueKind kind = eQueueKindUnknown;
217aac16e0fSJason Molenda     QueueSP queue_sp = m_queue_wp.lock();
218aac16e0fSJason Molenda     if (queue_sp)
219aac16e0fSJason Molenda       kind = queue_sp->GetKind();
220aac16e0fSJason Molenda 
221aac16e0fSJason Molenda     return kind;
222aac16e0fSJason Molenda   }
223aac16e0fSJason Molenda 
224c8064ac6SJason Molenda private:
225c8064ac6SJason Molenda   lldb::QueueWP m_queue_wp;
226b9c1b51eSKate Stone   std::vector<lldb::ThreadWP>
227b9c1b51eSKate Stone       m_threads; // threads currently executing this queue's items
228b9c1b51eSKate Stone   bool
229b9c1b51eSKate Stone       m_thread_list_fetched; // have we tried to fetch the threads list already?
2302fd83355SJason Molenda   std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued
2312fd83355SJason Molenda   bool m_pending_items_fetched; // have we tried to fetch the item list already?
232c8064ac6SJason Molenda };
233c8064ac6SJason Molenda }
234c8064ac6SJason Molenda 
235b9c1b51eSKate Stone SBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) {}
236c8064ac6SJason Molenda 
237b9c1b51eSKate Stone SBQueue::SBQueue(const QueueSP &queue_sp)
238b9c1b51eSKate Stone     : m_opaque_sp(new QueueImpl(queue_sp)) {}
239c8064ac6SJason Molenda 
240b9c1b51eSKate Stone SBQueue::SBQueue(const SBQueue &rhs) {
241c8064ac6SJason Molenda   if (&rhs == this)
242c8064ac6SJason Molenda     return;
243c8064ac6SJason Molenda 
244c8064ac6SJason Molenda   m_opaque_sp = rhs.m_opaque_sp;
245c8064ac6SJason Molenda }
246c8064ac6SJason Molenda 
247b9c1b51eSKate Stone const lldb::SBQueue &SBQueue::operator=(const lldb::SBQueue &rhs) {
248c8064ac6SJason Molenda   m_opaque_sp = rhs.m_opaque_sp;
249c8064ac6SJason Molenda   return *this;
250c8064ac6SJason Molenda }
251c8064ac6SJason Molenda 
252b9c1b51eSKate Stone SBQueue::~SBQueue() {}
253c8064ac6SJason Molenda 
254b9c1b51eSKate Stone bool SBQueue::IsValid() const {
255ac605f4aSJason Molenda   bool is_valid = m_opaque_sp->IsValid();
256ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
257ac605f4aSJason Molenda   if (log)
258b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::IsValid() == %s",
259b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), is_valid ? "true" : "false");
260ac605f4aSJason Molenda   return is_valid;
261c8064ac6SJason Molenda }
262c8064ac6SJason Molenda 
263b9c1b51eSKate Stone void SBQueue::Clear() {
264ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
265ac605f4aSJason Molenda   if (log)
266ac605f4aSJason Molenda     log->Printf("SBQueue(0x%" PRIx64 ")::Clear()", m_opaque_sp->GetQueueID());
267c8064ac6SJason Molenda   m_opaque_sp->Clear();
268c8064ac6SJason Molenda }
269c8064ac6SJason Molenda 
270b9c1b51eSKate Stone void SBQueue::SetQueue(const QueueSP &queue_sp) {
271c8064ac6SJason Molenda   m_opaque_sp->SetQueue(queue_sp);
272c8064ac6SJason Molenda }
273c8064ac6SJason Molenda 
274b9c1b51eSKate Stone lldb::queue_id_t SBQueue::GetQueueID() const {
275ac605f4aSJason Molenda   lldb::queue_id_t qid = m_opaque_sp->GetQueueID();
276ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
277ac605f4aSJason Molenda   if (log)
278b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetQueueID() == 0x%" PRIx64,
279b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), (uint64_t)qid);
280ac605f4aSJason Molenda   return qid;
281c8064ac6SJason Molenda }
282c8064ac6SJason Molenda 
283b9c1b51eSKate Stone uint32_t SBQueue::GetIndexID() const {
284ac605f4aSJason Molenda   uint32_t index_id = m_opaque_sp->GetIndexID();
285ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
286ac605f4aSJason Molenda   if (log)
287b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetIndexID() == 0x%" PRIx32,
288b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), index_id);
289ac605f4aSJason Molenda   return index_id;
290c8064ac6SJason Molenda }
291c8064ac6SJason Molenda 
292b9c1b51eSKate Stone const char *SBQueue::GetName() const {
293ac605f4aSJason Molenda   const char *name = m_opaque_sp->GetName();
294ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
295ac605f4aSJason Molenda   if (log)
296b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetName() == %s",
297b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), name ? name : "");
298ac605f4aSJason Molenda   return name;
299c8064ac6SJason Molenda }
300c8064ac6SJason Molenda 
301b9c1b51eSKate Stone uint32_t SBQueue::GetNumThreads() {
302ac605f4aSJason Molenda   uint32_t numthreads = m_opaque_sp->GetNumThreads();
303ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
304ac605f4aSJason Molenda   if (log)
305b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetNumThreads() == %d",
306b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), numthreads);
307ac605f4aSJason Molenda   return numthreads;
308c8064ac6SJason Molenda }
309c8064ac6SJason Molenda 
310b9c1b51eSKate Stone SBThread SBQueue::GetThreadAtIndex(uint32_t idx) {
311ac605f4aSJason Molenda   SBThread th = m_opaque_sp->GetThreadAtIndex(idx);
312ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
313ac605f4aSJason Molenda   if (log)
314b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetThreadAtIndex(%d)",
315b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), idx);
316ac605f4aSJason Molenda   return th;
317c8064ac6SJason Molenda }
318c8064ac6SJason Molenda 
319b9c1b51eSKate Stone uint32_t SBQueue::GetNumPendingItems() {
320ac605f4aSJason Molenda   uint32_t pending_items = m_opaque_sp->GetNumPendingItems();
321ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
322ac605f4aSJason Molenda   if (log)
323b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetNumPendingItems() == %d",
324b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), pending_items);
325ac605f4aSJason Molenda   return pending_items;
326c8064ac6SJason Molenda }
327c8064ac6SJason Molenda 
328b9c1b51eSKate Stone SBQueueItem SBQueue::GetPendingItemAtIndex(uint32_t idx) {
329ac605f4aSJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
330ac605f4aSJason Molenda   if (log)
331b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetPendingItemAtIndex(%d)",
332b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), idx);
3332fd83355SJason Molenda   return m_opaque_sp->GetPendingItemAtIndex(idx);
334c8064ac6SJason Molenda }
335c8064ac6SJason Molenda 
336b9c1b51eSKate Stone uint32_t SBQueue::GetNumRunningItems() {
337fe95dc95SJason Molenda   uint32_t running_items = m_opaque_sp->GetNumRunningItems();
338fe95dc95SJason Molenda   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
339fe95dc95SJason Molenda   if (log)
340b9c1b51eSKate Stone     log->Printf("SBQueue(0x%" PRIx64 ")::GetNumRunningItems() == %d",
341b9c1b51eSKate Stone                 m_opaque_sp->GetQueueID(), running_items);
342fe95dc95SJason Molenda   return running_items;
343fe95dc95SJason Molenda }
344fe95dc95SJason Molenda 
345b9c1b51eSKate Stone SBProcess SBQueue::GetProcess() { return m_opaque_sp->GetProcess(); }
346aac16e0fSJason Molenda 
347b9c1b51eSKate Stone lldb::QueueKind SBQueue::GetKind() { return m_opaque_sp->GetKind(); }
348