112b93ac6SEd Maste //===-- SBQueue.cpp ---------------------------------------------*- C++ -*-===//
212b93ac6SEd Maste //
312b93ac6SEd Maste //                     The LLVM Compiler Infrastructure
412b93ac6SEd Maste //
512b93ac6SEd Maste // This file is distributed under the University of Illinois Open Source
612b93ac6SEd Maste // License. See LICENSE.TXT for details.
712b93ac6SEd Maste //
812b93ac6SEd Maste //===----------------------------------------------------------------------===//
912b93ac6SEd Maste 
100127ef0fSEd Maste #include <inttypes.h>
110127ef0fSEd Maste 
1212b93ac6SEd Maste #include "lldb/API/SBQueue.h"
1312b93ac6SEd Maste 
1412b93ac6SEd Maste #include "lldb/API/SBProcess.h"
150127ef0fSEd Maste #include "lldb/API/SBQueueItem.h"
16435933ddSDimitry Andric #include "lldb/API/SBThread.h"
170127ef0fSEd Maste 
1812b93ac6SEd Maste #include "lldb/Target/Process.h"
1912b93ac6SEd Maste #include "lldb/Target/Queue.h"
2012b93ac6SEd Maste #include "lldb/Target/QueueItem.h"
2112b93ac6SEd Maste #include "lldb/Target/Thread.h"
22f678e45dSDimitry Andric #include "lldb/Utility/Log.h"
2312b93ac6SEd Maste 
2412b93ac6SEd Maste using namespace lldb;
2512b93ac6SEd Maste using namespace lldb_private;
2612b93ac6SEd Maste 
27435933ddSDimitry Andric namespace lldb_private {
2812b93ac6SEd Maste 
29435933ddSDimitry Andric class QueueImpl {
3012b93ac6SEd Maste public:
QueueImpl()31435933ddSDimitry Andric   QueueImpl()
32435933ddSDimitry Andric       : m_queue_wp(), m_threads(), m_thread_list_fetched(false),
33435933ddSDimitry Andric         m_pending_items(), m_pending_items_fetched(false) {}
3412b93ac6SEd Maste 
QueueImpl(const lldb::QueueSP & queue_sp)35435933ddSDimitry Andric   QueueImpl(const lldb::QueueSP &queue_sp)
36435933ddSDimitry Andric       : m_queue_wp(), m_threads(), m_thread_list_fetched(false),
37435933ddSDimitry Andric         m_pending_items(), m_pending_items_fetched(false) {
3812b93ac6SEd Maste     m_queue_wp = queue_sp;
3912b93ac6SEd Maste   }
4012b93ac6SEd Maste 
QueueImpl(const QueueImpl & rhs)41435933ddSDimitry Andric   QueueImpl(const QueueImpl &rhs) {
4212b93ac6SEd Maste     if (&rhs == this)
4312b93ac6SEd Maste       return;
4412b93ac6SEd Maste     m_queue_wp = rhs.m_queue_wp;
4512b93ac6SEd Maste     m_threads = rhs.m_threads;
4612b93ac6SEd Maste     m_thread_list_fetched = rhs.m_thread_list_fetched;
4712b93ac6SEd Maste     m_pending_items = rhs.m_pending_items;
4812b93ac6SEd Maste     m_pending_items_fetched = rhs.m_pending_items_fetched;
4912b93ac6SEd Maste   }
5012b93ac6SEd Maste 
~QueueImpl()51435933ddSDimitry Andric   ~QueueImpl() {}
5212b93ac6SEd Maste 
IsValid()53435933ddSDimitry Andric   bool IsValid() { return m_queue_wp.lock() != NULL; }
5412b93ac6SEd Maste 
Clear()55435933ddSDimitry Andric   void Clear() {
5612b93ac6SEd Maste     m_queue_wp.reset();
5712b93ac6SEd Maste     m_thread_list_fetched = false;
5812b93ac6SEd Maste     m_threads.clear();
5912b93ac6SEd Maste     m_pending_items_fetched = false;
6012b93ac6SEd Maste     m_pending_items.clear();
6112b93ac6SEd Maste   }
6212b93ac6SEd Maste 
SetQueue(const lldb::QueueSP & queue_sp)63435933ddSDimitry Andric   void SetQueue(const lldb::QueueSP &queue_sp) {
6412b93ac6SEd Maste     Clear();
6512b93ac6SEd Maste     m_queue_wp = queue_sp;
6612b93ac6SEd Maste   }
6712b93ac6SEd Maste 
GetQueueID() const68435933ddSDimitry Andric   lldb::queue_id_t GetQueueID() const {
6912b93ac6SEd Maste     lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID;
7012b93ac6SEd Maste     lldb::QueueSP queue_sp = m_queue_wp.lock();
71435933ddSDimitry Andric     if (queue_sp) {
7212b93ac6SEd Maste       result = queue_sp->GetID();
7312b93ac6SEd Maste     }
7412b93ac6SEd Maste     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
7512b93ac6SEd Maste     if (log)
760127ef0fSEd Maste       log->Printf("SBQueue(%p)::GetQueueID () => 0x%" PRIx64,
770127ef0fSEd Maste                   static_cast<const void *>(this), result);
7812b93ac6SEd Maste     return result;
7912b93ac6SEd Maste   }
8012b93ac6SEd Maste 
GetIndexID() const81435933ddSDimitry Andric   uint32_t GetIndexID() const {
8212b93ac6SEd Maste     uint32_t result = LLDB_INVALID_INDEX32;
8312b93ac6SEd Maste     lldb::QueueSP queue_sp = m_queue_wp.lock();
84435933ddSDimitry Andric     if (queue_sp) {
8512b93ac6SEd Maste       result = queue_sp->GetIndexID();
8612b93ac6SEd Maste     }
8712b93ac6SEd Maste     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
8812b93ac6SEd Maste     if (log)
890127ef0fSEd Maste       log->Printf("SBQueueImpl(%p)::GetIndexID () => %d",
900127ef0fSEd Maste                   static_cast<const void *>(this), result);
9112b93ac6SEd Maste     return result;
9212b93ac6SEd Maste   }
9312b93ac6SEd Maste 
GetName() const94435933ddSDimitry Andric   const char *GetName() const {
9512b93ac6SEd Maste     const char *name = NULL;
9612b93ac6SEd Maste     lldb::QueueSP queue_sp = m_queue_wp.lock();
97435933ddSDimitry Andric     if (queue_sp.get()) {
9812b93ac6SEd Maste       name = queue_sp->GetName();
9912b93ac6SEd Maste     }
10012b93ac6SEd Maste 
10112b93ac6SEd Maste     Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
10212b93ac6SEd Maste     if (log)
1030127ef0fSEd Maste       log->Printf("SBQueueImpl(%p)::GetName () => %s",
104435933ddSDimitry Andric                   static_cast<const void *>(this), name ? name : "NULL");
10512b93ac6SEd Maste 
10612b93ac6SEd Maste     return name;
10712b93ac6SEd Maste   }
10812b93ac6SEd Maste 
FetchThreads()109435933ddSDimitry Andric   void FetchThreads() {
110*b5893f02SDimitry Andric     if (!m_thread_list_fetched) {
11112b93ac6SEd Maste       lldb::QueueSP queue_sp = m_queue_wp.lock();
112435933ddSDimitry Andric       if (queue_sp) {
11312b93ac6SEd Maste         Process::StopLocker stop_locker;
114435933ddSDimitry Andric         if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
11512b93ac6SEd Maste           const std::vector<ThreadSP> thread_list(queue_sp->GetThreads());
11612b93ac6SEd Maste           m_thread_list_fetched = true;
11712b93ac6SEd Maste           const uint32_t num_threads = thread_list.size();
118435933ddSDimitry Andric           for (uint32_t idx = 0; idx < num_threads; ++idx) {
11912b93ac6SEd Maste             ThreadSP thread_sp = thread_list[idx];
120435933ddSDimitry Andric             if (thread_sp && thread_sp->IsValid()) {
12112b93ac6SEd Maste               m_threads.push_back(thread_sp);
12212b93ac6SEd Maste             }
12312b93ac6SEd Maste           }
12412b93ac6SEd Maste         }
12512b93ac6SEd Maste       }
12612b93ac6SEd Maste     }
12712b93ac6SEd Maste   }
12812b93ac6SEd Maste 
FetchItems()129435933ddSDimitry Andric   void FetchItems() {
130*b5893f02SDimitry Andric     if (!m_pending_items_fetched) {
13112b93ac6SEd Maste       QueueSP queue_sp = m_queue_wp.lock();
132435933ddSDimitry Andric       if (queue_sp) {
13312b93ac6SEd Maste         Process::StopLocker stop_locker;
134435933ddSDimitry Andric         if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
135435933ddSDimitry Andric           const std::vector<QueueItemSP> queue_items(
136435933ddSDimitry Andric               queue_sp->GetPendingItems());
13712b93ac6SEd Maste           m_pending_items_fetched = true;
13812b93ac6SEd Maste           const uint32_t num_pending_items = queue_items.size();
139435933ddSDimitry Andric           for (uint32_t idx = 0; idx < num_pending_items; ++idx) {
14012b93ac6SEd Maste             QueueItemSP item = queue_items[idx];
141435933ddSDimitry Andric             if (item && item->IsValid()) {
14212b93ac6SEd Maste               m_pending_items.push_back(item);
14312b93ac6SEd Maste             }
14412b93ac6SEd Maste           }
14512b93ac6SEd Maste         }
14612b93ac6SEd Maste       }
14712b93ac6SEd Maste     }
14812b93ac6SEd Maste   }
14912b93ac6SEd Maste 
GetNumThreads()150435933ddSDimitry Andric   uint32_t GetNumThreads() {
15112b93ac6SEd Maste     uint32_t result = 0;
15212b93ac6SEd Maste 
15312b93ac6SEd Maste     FetchThreads();
154435933ddSDimitry Andric     if (m_thread_list_fetched) {
15512b93ac6SEd Maste       result = m_threads.size();
15612b93ac6SEd Maste     }
15712b93ac6SEd Maste     return result;
15812b93ac6SEd Maste   }
15912b93ac6SEd Maste 
GetThreadAtIndex(uint32_t idx)160435933ddSDimitry Andric   lldb::SBThread GetThreadAtIndex(uint32_t idx) {
16112b93ac6SEd Maste     FetchThreads();
16212b93ac6SEd Maste 
16312b93ac6SEd Maste     SBThread sb_thread;
16412b93ac6SEd Maste     QueueSP queue_sp = m_queue_wp.lock();
165435933ddSDimitry Andric     if (queue_sp && idx < m_threads.size()) {
16612b93ac6SEd Maste       ProcessSP process_sp = queue_sp->GetProcess();
167435933ddSDimitry Andric       if (process_sp) {
16812b93ac6SEd Maste         ThreadSP thread_sp = m_threads[idx].lock();
169435933ddSDimitry Andric         if (thread_sp) {
17012b93ac6SEd Maste           sb_thread.SetThread(thread_sp);
17112b93ac6SEd Maste         }
17212b93ac6SEd Maste       }
17312b93ac6SEd Maste     }
17412b93ac6SEd Maste     return sb_thread;
17512b93ac6SEd Maste   }
17612b93ac6SEd Maste 
GetNumPendingItems()177435933ddSDimitry Andric   uint32_t GetNumPendingItems() {
17812b93ac6SEd Maste     uint32_t result = 0;
17912b93ac6SEd Maste 
1800127ef0fSEd Maste     QueueSP queue_sp = m_queue_wp.lock();
181*b5893f02SDimitry Andric     if (!m_pending_items_fetched && queue_sp) {
1820127ef0fSEd Maste       result = queue_sp->GetNumPendingWorkItems();
183435933ddSDimitry Andric     } else {
18412b93ac6SEd Maste       result = m_pending_items.size();
18512b93ac6SEd Maste     }
18612b93ac6SEd Maste     return result;
18712b93ac6SEd Maste   }
18812b93ac6SEd Maste 
GetPendingItemAtIndex(uint32_t idx)189435933ddSDimitry Andric   lldb::SBQueueItem GetPendingItemAtIndex(uint32_t idx) {
19012b93ac6SEd Maste     SBQueueItem result;
19112b93ac6SEd Maste     FetchItems();
192435933ddSDimitry Andric     if (m_pending_items_fetched && idx < m_pending_items.size()) {
19312b93ac6SEd Maste       result.SetQueueItem(m_pending_items[idx]);
19412b93ac6SEd Maste     }
19512b93ac6SEd Maste     return result;
19612b93ac6SEd Maste   }
19712b93ac6SEd Maste 
GetNumRunningItems()198435933ddSDimitry Andric   uint32_t GetNumRunningItems() {
1990127ef0fSEd Maste     uint32_t result = 0;
2000127ef0fSEd Maste     QueueSP queue_sp = m_queue_wp.lock();
2010127ef0fSEd Maste     if (queue_sp)
2020127ef0fSEd Maste       result = queue_sp->GetNumRunningWorkItems();
2030127ef0fSEd Maste     return result;
2040127ef0fSEd Maste   }
2050127ef0fSEd Maste 
GetProcess()206435933ddSDimitry Andric   lldb::SBProcess GetProcess() {
20712b93ac6SEd Maste     SBProcess result;
20812b93ac6SEd Maste     QueueSP queue_sp = m_queue_wp.lock();
209435933ddSDimitry Andric     if (queue_sp) {
21012b93ac6SEd Maste       result.SetSP(queue_sp->GetProcess());
21112b93ac6SEd Maste     }
21212b93ac6SEd Maste     return result;
21312b93ac6SEd Maste   }
21412b93ac6SEd Maste 
GetKind()215435933ddSDimitry Andric   lldb::QueueKind GetKind() {
2160127ef0fSEd Maste     lldb::QueueKind kind = eQueueKindUnknown;
2170127ef0fSEd Maste     QueueSP queue_sp = m_queue_wp.lock();
2180127ef0fSEd Maste     if (queue_sp)
2190127ef0fSEd Maste       kind = queue_sp->GetKind();
2200127ef0fSEd Maste 
2210127ef0fSEd Maste     return kind;
2220127ef0fSEd Maste   }
2230127ef0fSEd Maste 
22412b93ac6SEd Maste private:
22512b93ac6SEd Maste   lldb::QueueWP m_queue_wp;
226435933ddSDimitry Andric   std::vector<lldb::ThreadWP>
227435933ddSDimitry Andric       m_threads; // threads currently executing this queue's items
228435933ddSDimitry Andric   bool
229435933ddSDimitry Andric       m_thread_list_fetched; // have we tried to fetch the threads list already?
23012b93ac6SEd Maste   std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued
23112b93ac6SEd Maste   bool m_pending_items_fetched; // have we tried to fetch the item list already?
23212b93ac6SEd Maste };
23312b93ac6SEd Maste }
23412b93ac6SEd Maste 
SBQueue()235435933ddSDimitry Andric SBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) {}
23612b93ac6SEd Maste 
SBQueue(const QueueSP & queue_sp)237435933ddSDimitry Andric SBQueue::SBQueue(const QueueSP &queue_sp)
238435933ddSDimitry Andric     : m_opaque_sp(new QueueImpl(queue_sp)) {}
23912b93ac6SEd Maste 
SBQueue(const SBQueue & rhs)240435933ddSDimitry Andric SBQueue::SBQueue(const SBQueue &rhs) {
24112b93ac6SEd Maste   if (&rhs == this)
24212b93ac6SEd Maste     return;
24312b93ac6SEd Maste 
24412b93ac6SEd Maste   m_opaque_sp = rhs.m_opaque_sp;
24512b93ac6SEd Maste }
24612b93ac6SEd Maste 
operator =(const lldb::SBQueue & rhs)247435933ddSDimitry Andric const lldb::SBQueue &SBQueue::operator=(const lldb::SBQueue &rhs) {
24812b93ac6SEd Maste   m_opaque_sp = rhs.m_opaque_sp;
24912b93ac6SEd Maste   return *this;
25012b93ac6SEd Maste }
25112b93ac6SEd Maste 
~SBQueue()252435933ddSDimitry Andric SBQueue::~SBQueue() {}
25312b93ac6SEd Maste 
IsValid() const254435933ddSDimitry Andric bool SBQueue::IsValid() const {
2550127ef0fSEd Maste   bool is_valid = m_opaque_sp->IsValid();
2560127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
2570127ef0fSEd Maste   if (log)
258435933ddSDimitry Andric     log->Printf("SBQueue(0x%" PRIx64 ")::IsValid() == %s",
259435933ddSDimitry Andric                 m_opaque_sp->GetQueueID(), is_valid ? "true" : "false");
2600127ef0fSEd Maste   return is_valid;
26112b93ac6SEd Maste }
26212b93ac6SEd Maste 
Clear()263435933ddSDimitry Andric void SBQueue::Clear() {
2640127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
2650127ef0fSEd Maste   if (log)
2660127ef0fSEd Maste     log->Printf("SBQueue(0x%" PRIx64 ")::Clear()", m_opaque_sp->GetQueueID());
26712b93ac6SEd Maste   m_opaque_sp->Clear();
26812b93ac6SEd Maste }
26912b93ac6SEd Maste 
SetQueue(const QueueSP & queue_sp)270435933ddSDimitry Andric void SBQueue::SetQueue(const QueueSP &queue_sp) {
27112b93ac6SEd Maste   m_opaque_sp->SetQueue(queue_sp);
27212b93ac6SEd Maste }
27312b93ac6SEd Maste 
GetQueueID() const274435933ddSDimitry Andric lldb::queue_id_t SBQueue::GetQueueID() const {
2750127ef0fSEd Maste   lldb::queue_id_t qid = m_opaque_sp->GetQueueID();
2760127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
2770127ef0fSEd Maste   if (log)
278435933ddSDimitry Andric     log->Printf("SBQueue(0x%" PRIx64 ")::GetQueueID() == 0x%" PRIx64,
279435933ddSDimitry Andric                 m_opaque_sp->GetQueueID(), (uint64_t)qid);
2800127ef0fSEd Maste   return qid;
28112b93ac6SEd Maste }
28212b93ac6SEd Maste 
GetIndexID() const283435933ddSDimitry Andric uint32_t SBQueue::GetIndexID() const {
2840127ef0fSEd Maste   uint32_t index_id = m_opaque_sp->GetIndexID();
2850127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
2860127ef0fSEd Maste   if (log)
287435933ddSDimitry Andric     log->Printf("SBQueue(0x%" PRIx64 ")::GetIndexID() == 0x%" PRIx32,
288435933ddSDimitry Andric                 m_opaque_sp->GetQueueID(), index_id);
2890127ef0fSEd Maste   return index_id;
29012b93ac6SEd Maste }
29112b93ac6SEd Maste 
GetName() const292435933ddSDimitry Andric const char *SBQueue::GetName() const {
2930127ef0fSEd Maste   const char *name = m_opaque_sp->GetName();
2940127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
2950127ef0fSEd Maste   if (log)
296435933ddSDimitry Andric     log->Printf("SBQueue(0x%" PRIx64 ")::GetName() == %s",
297435933ddSDimitry Andric                 m_opaque_sp->GetQueueID(), name ? name : "");
2980127ef0fSEd Maste   return name;
29912b93ac6SEd Maste }
30012b93ac6SEd Maste 
GetNumThreads()301435933ddSDimitry Andric uint32_t SBQueue::GetNumThreads() {
3020127ef0fSEd Maste   uint32_t numthreads = m_opaque_sp->GetNumThreads();
3030127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
3040127ef0fSEd Maste   if (log)
305435933ddSDimitry Andric     log->Printf("SBQueue(0x%" PRIx64 ")::GetNumThreads() == %d",
306435933ddSDimitry Andric                 m_opaque_sp->GetQueueID(), numthreads);
3070127ef0fSEd Maste   return numthreads;
30812b93ac6SEd Maste }
30912b93ac6SEd Maste 
GetThreadAtIndex(uint32_t idx)310435933ddSDimitry Andric SBThread SBQueue::GetThreadAtIndex(uint32_t idx) {
3110127ef0fSEd Maste   SBThread th = m_opaque_sp->GetThreadAtIndex(idx);
3120127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
3130127ef0fSEd Maste   if (log)
314435933ddSDimitry Andric     log->Printf("SBQueue(0x%" PRIx64 ")::GetThreadAtIndex(%d)",
315435933ddSDimitry Andric                 m_opaque_sp->GetQueueID(), idx);
3160127ef0fSEd Maste   return th;
31712b93ac6SEd Maste }
31812b93ac6SEd Maste 
GetNumPendingItems()319435933ddSDimitry Andric uint32_t SBQueue::GetNumPendingItems() {
3200127ef0fSEd Maste   uint32_t pending_items = m_opaque_sp->GetNumPendingItems();
3210127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
3220127ef0fSEd Maste   if (log)
323435933ddSDimitry Andric     log->Printf("SBQueue(0x%" PRIx64 ")::GetNumPendingItems() == %d",
324435933ddSDimitry Andric                 m_opaque_sp->GetQueueID(), pending_items);
3250127ef0fSEd Maste   return pending_items;
32612b93ac6SEd Maste }
32712b93ac6SEd Maste 
GetPendingItemAtIndex(uint32_t idx)328435933ddSDimitry Andric SBQueueItem SBQueue::GetPendingItemAtIndex(uint32_t idx) {
3290127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
3300127ef0fSEd Maste   if (log)
331435933ddSDimitry Andric     log->Printf("SBQueue(0x%" PRIx64 ")::GetPendingItemAtIndex(%d)",
332435933ddSDimitry Andric                 m_opaque_sp->GetQueueID(), idx);
33312b93ac6SEd Maste   return m_opaque_sp->GetPendingItemAtIndex(idx);
33412b93ac6SEd Maste }
33512b93ac6SEd Maste 
GetNumRunningItems()336435933ddSDimitry Andric uint32_t SBQueue::GetNumRunningItems() {
3370127ef0fSEd Maste   uint32_t running_items = m_opaque_sp->GetNumRunningItems();
3380127ef0fSEd Maste   Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API));
3390127ef0fSEd Maste   if (log)
340435933ddSDimitry Andric     log->Printf("SBQueue(0x%" PRIx64 ")::GetNumRunningItems() == %d",
341435933ddSDimitry Andric                 m_opaque_sp->GetQueueID(), running_items);
3420127ef0fSEd Maste   return running_items;
3430127ef0fSEd Maste }
3440127ef0fSEd Maste 
GetProcess()345435933ddSDimitry Andric SBProcess SBQueue::GetProcess() { return m_opaque_sp->GetProcess(); }
3460127ef0fSEd Maste 
GetKind()347435933ddSDimitry Andric lldb::QueueKind SBQueue::GetKind() { return m_opaque_sp->GetKind(); }
348