xref: /src/contrib/llvm-project/lldb/source/API/SBQueue.cpp (revision 06c3fb2749bda94cb5201f81ffdb8fa6c3161b2e)
1cfca06d7SDimitry Andric //===-- SBQueue.cpp -------------------------------------------------------===//
2866dcdacSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6866dcdacSEd Maste //
7866dcdacSEd Maste //===----------------------------------------------------------------------===//
8866dcdacSEd Maste 
9344a3780SDimitry Andric #include <cinttypes>
100cac4ca3SEd Maste 
11866dcdacSEd Maste #include "lldb/API/SBQueue.h"
126f8fc217SDimitry Andric #include "lldb/Utility/Instrumentation.h"
13866dcdacSEd Maste 
14866dcdacSEd Maste #include "lldb/API/SBProcess.h"
150cac4ca3SEd Maste #include "lldb/API/SBQueueItem.h"
1614f1b3e8SDimitry Andric #include "lldb/API/SBThread.h"
170cac4ca3SEd Maste 
18866dcdacSEd Maste #include "lldb/Target/Process.h"
19866dcdacSEd Maste #include "lldb/Target/Queue.h"
20866dcdacSEd Maste #include "lldb/Target/QueueItem.h"
21866dcdacSEd Maste #include "lldb/Target/Thread.h"
22866dcdacSEd Maste 
23866dcdacSEd Maste using namespace lldb;
24866dcdacSEd Maste using namespace lldb_private;
25866dcdacSEd Maste 
2614f1b3e8SDimitry Andric namespace lldb_private {
27866dcdacSEd Maste 
2814f1b3e8SDimitry Andric class QueueImpl {
29866dcdacSEd Maste public:
30145449b1SDimitry Andric   QueueImpl() = default;
31866dcdacSEd Maste 
QueueImpl(const lldb::QueueSP & queue_sp)32145449b1SDimitry Andric   QueueImpl(const lldb::QueueSP &queue_sp) { m_queue_wp = queue_sp; }
33866dcdacSEd Maste 
QueueImpl(const QueueImpl & rhs)3414f1b3e8SDimitry Andric   QueueImpl(const QueueImpl &rhs) {
35866dcdacSEd Maste     if (&rhs == this)
36866dcdacSEd Maste       return;
37866dcdacSEd Maste     m_queue_wp = rhs.m_queue_wp;
38866dcdacSEd Maste     m_threads = rhs.m_threads;
39866dcdacSEd Maste     m_thread_list_fetched = rhs.m_thread_list_fetched;
40866dcdacSEd Maste     m_pending_items = rhs.m_pending_items;
41866dcdacSEd Maste     m_pending_items_fetched = rhs.m_pending_items_fetched;
42866dcdacSEd Maste   }
43866dcdacSEd Maste 
44cfca06d7SDimitry Andric   ~QueueImpl() = default;
45866dcdacSEd Maste 
IsValid()465f29bb8aSDimitry Andric   bool IsValid() { return m_queue_wp.lock() != nullptr; }
47866dcdacSEd Maste 
Clear()4814f1b3e8SDimitry Andric   void Clear() {
49866dcdacSEd Maste     m_queue_wp.reset();
50866dcdacSEd Maste     m_thread_list_fetched = false;
51866dcdacSEd Maste     m_threads.clear();
52866dcdacSEd Maste     m_pending_items_fetched = false;
53866dcdacSEd Maste     m_pending_items.clear();
54866dcdacSEd Maste   }
55866dcdacSEd Maste 
SetQueue(const lldb::QueueSP & queue_sp)5614f1b3e8SDimitry Andric   void SetQueue(const lldb::QueueSP &queue_sp) {
57866dcdacSEd Maste     Clear();
58866dcdacSEd Maste     m_queue_wp = queue_sp;
59866dcdacSEd Maste   }
60866dcdacSEd Maste 
GetQueueID() const6114f1b3e8SDimitry Andric   lldb::queue_id_t GetQueueID() const {
62866dcdacSEd Maste     lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID;
63866dcdacSEd Maste     lldb::QueueSP queue_sp = m_queue_wp.lock();
6414f1b3e8SDimitry Andric     if (queue_sp) {
65866dcdacSEd Maste       result = queue_sp->GetID();
66866dcdacSEd Maste     }
67866dcdacSEd Maste     return result;
68866dcdacSEd Maste   }
69866dcdacSEd Maste 
GetIndexID() const7014f1b3e8SDimitry Andric   uint32_t GetIndexID() const {
71866dcdacSEd Maste     uint32_t result = LLDB_INVALID_INDEX32;
72866dcdacSEd Maste     lldb::QueueSP queue_sp = m_queue_wp.lock();
7314f1b3e8SDimitry Andric     if (queue_sp) {
74866dcdacSEd Maste       result = queue_sp->GetIndexID();
75866dcdacSEd Maste     }
76866dcdacSEd Maste     return result;
77866dcdacSEd Maste   }
78866dcdacSEd Maste 
GetName() const7914f1b3e8SDimitry Andric   const char *GetName() const {
80866dcdacSEd Maste     lldb::QueueSP queue_sp = m_queue_wp.lock();
817fa27ce4SDimitry Andric     if (!queue_sp)
827fa27ce4SDimitry Andric       return nullptr;
837fa27ce4SDimitry Andric     return ConstString(queue_sp->GetName()).GetCString();
84866dcdacSEd Maste   }
85866dcdacSEd Maste 
FetchThreads()8614f1b3e8SDimitry Andric   void FetchThreads() {
8794994d37SDimitry Andric     if (!m_thread_list_fetched) {
88866dcdacSEd Maste       lldb::QueueSP queue_sp = m_queue_wp.lock();
8914f1b3e8SDimitry Andric       if (queue_sp) {
90866dcdacSEd Maste         Process::StopLocker stop_locker;
9114f1b3e8SDimitry Andric         if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
92866dcdacSEd Maste           const std::vector<ThreadSP> thread_list(queue_sp->GetThreads());
93866dcdacSEd Maste           m_thread_list_fetched = true;
94866dcdacSEd Maste           const uint32_t num_threads = thread_list.size();
9514f1b3e8SDimitry Andric           for (uint32_t idx = 0; idx < num_threads; ++idx) {
96866dcdacSEd Maste             ThreadSP thread_sp = thread_list[idx];
9714f1b3e8SDimitry Andric             if (thread_sp && thread_sp->IsValid()) {
98866dcdacSEd Maste               m_threads.push_back(thread_sp);
99866dcdacSEd Maste             }
100866dcdacSEd Maste           }
101866dcdacSEd Maste         }
102866dcdacSEd Maste       }
103866dcdacSEd Maste     }
104866dcdacSEd Maste   }
105866dcdacSEd Maste 
FetchItems()10614f1b3e8SDimitry Andric   void FetchItems() {
10794994d37SDimitry Andric     if (!m_pending_items_fetched) {
108866dcdacSEd Maste       QueueSP queue_sp = m_queue_wp.lock();
10914f1b3e8SDimitry Andric       if (queue_sp) {
110866dcdacSEd Maste         Process::StopLocker stop_locker;
11114f1b3e8SDimitry Andric         if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) {
11214f1b3e8SDimitry Andric           const std::vector<QueueItemSP> queue_items(
11314f1b3e8SDimitry Andric               queue_sp->GetPendingItems());
114866dcdacSEd Maste           m_pending_items_fetched = true;
115866dcdacSEd Maste           const uint32_t num_pending_items = queue_items.size();
11614f1b3e8SDimitry Andric           for (uint32_t idx = 0; idx < num_pending_items; ++idx) {
117866dcdacSEd Maste             QueueItemSP item = queue_items[idx];
11814f1b3e8SDimitry Andric             if (item && item->IsValid()) {
119866dcdacSEd Maste               m_pending_items.push_back(item);
120866dcdacSEd Maste             }
121866dcdacSEd Maste           }
122866dcdacSEd Maste         }
123866dcdacSEd Maste       }
124866dcdacSEd Maste     }
125866dcdacSEd Maste   }
126866dcdacSEd Maste 
GetNumThreads()12714f1b3e8SDimitry Andric   uint32_t GetNumThreads() {
128866dcdacSEd Maste     uint32_t result = 0;
129866dcdacSEd Maste 
130866dcdacSEd Maste     FetchThreads();
13114f1b3e8SDimitry Andric     if (m_thread_list_fetched) {
132866dcdacSEd Maste       result = m_threads.size();
133866dcdacSEd Maste     }
134866dcdacSEd Maste     return result;
135866dcdacSEd Maste   }
136866dcdacSEd Maste 
GetThreadAtIndex(uint32_t idx)13714f1b3e8SDimitry Andric   lldb::SBThread GetThreadAtIndex(uint32_t idx) {
138866dcdacSEd Maste     FetchThreads();
139866dcdacSEd Maste 
140866dcdacSEd Maste     SBThread sb_thread;
141866dcdacSEd Maste     QueueSP queue_sp = m_queue_wp.lock();
14214f1b3e8SDimitry Andric     if (queue_sp && idx < m_threads.size()) {
143866dcdacSEd Maste       ProcessSP process_sp = queue_sp->GetProcess();
14414f1b3e8SDimitry Andric       if (process_sp) {
145866dcdacSEd Maste         ThreadSP thread_sp = m_threads[idx].lock();
14614f1b3e8SDimitry Andric         if (thread_sp) {
147866dcdacSEd Maste           sb_thread.SetThread(thread_sp);
148866dcdacSEd Maste         }
149866dcdacSEd Maste       }
150866dcdacSEd Maste     }
151866dcdacSEd Maste     return sb_thread;
152866dcdacSEd Maste   }
153866dcdacSEd Maste 
GetNumPendingItems()15414f1b3e8SDimitry Andric   uint32_t GetNumPendingItems() {
155866dcdacSEd Maste     uint32_t result = 0;
156866dcdacSEd Maste 
1570cac4ca3SEd Maste     QueueSP queue_sp = m_queue_wp.lock();
15894994d37SDimitry Andric     if (!m_pending_items_fetched && queue_sp) {
1590cac4ca3SEd Maste       result = queue_sp->GetNumPendingWorkItems();
16014f1b3e8SDimitry Andric     } else {
161866dcdacSEd Maste       result = m_pending_items.size();
162866dcdacSEd Maste     }
163866dcdacSEd Maste     return result;
164866dcdacSEd Maste   }
165866dcdacSEd Maste 
GetPendingItemAtIndex(uint32_t idx)16614f1b3e8SDimitry Andric   lldb::SBQueueItem GetPendingItemAtIndex(uint32_t idx) {
167866dcdacSEd Maste     SBQueueItem result;
168866dcdacSEd Maste     FetchItems();
16914f1b3e8SDimitry Andric     if (m_pending_items_fetched && idx < m_pending_items.size()) {
170866dcdacSEd Maste       result.SetQueueItem(m_pending_items[idx]);
171866dcdacSEd Maste     }
172866dcdacSEd Maste     return result;
173866dcdacSEd Maste   }
174866dcdacSEd Maste 
GetNumRunningItems()17514f1b3e8SDimitry Andric   uint32_t GetNumRunningItems() {
1760cac4ca3SEd Maste     uint32_t result = 0;
1770cac4ca3SEd Maste     QueueSP queue_sp = m_queue_wp.lock();
1780cac4ca3SEd Maste     if (queue_sp)
1790cac4ca3SEd Maste       result = queue_sp->GetNumRunningWorkItems();
1800cac4ca3SEd Maste     return result;
1810cac4ca3SEd Maste   }
1820cac4ca3SEd Maste 
GetProcess()18314f1b3e8SDimitry Andric   lldb::SBProcess GetProcess() {
184866dcdacSEd Maste     SBProcess result;
185866dcdacSEd Maste     QueueSP queue_sp = m_queue_wp.lock();
18614f1b3e8SDimitry Andric     if (queue_sp) {
187866dcdacSEd Maste       result.SetSP(queue_sp->GetProcess());
188866dcdacSEd Maste     }
189866dcdacSEd Maste     return result;
190866dcdacSEd Maste   }
191866dcdacSEd Maste 
GetKind()19214f1b3e8SDimitry Andric   lldb::QueueKind GetKind() {
1930cac4ca3SEd Maste     lldb::QueueKind kind = eQueueKindUnknown;
1940cac4ca3SEd Maste     QueueSP queue_sp = m_queue_wp.lock();
1950cac4ca3SEd Maste     if (queue_sp)
1960cac4ca3SEd Maste       kind = queue_sp->GetKind();
1970cac4ca3SEd Maste 
1980cac4ca3SEd Maste     return kind;
1990cac4ca3SEd Maste   }
2000cac4ca3SEd Maste 
201866dcdacSEd Maste private:
202866dcdacSEd Maste   lldb::QueueWP m_queue_wp;
20314f1b3e8SDimitry Andric   std::vector<lldb::ThreadWP>
20414f1b3e8SDimitry Andric       m_threads; // threads currently executing this queue's items
205344a3780SDimitry Andric   bool m_thread_list_fetched =
206344a3780SDimitry Andric       false; // have we tried to fetch the threads list already?
207866dcdacSEd Maste   std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued
208344a3780SDimitry Andric   bool m_pending_items_fetched =
209344a3780SDimitry Andric       false; // have we tried to fetch the item list already?
210866dcdacSEd Maste };
211866dcdacSEd Maste }
212866dcdacSEd Maste 
SBQueue()2136f8fc217SDimitry Andric SBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) { LLDB_INSTRUMENT_VA(this); }
214866dcdacSEd Maste 
SBQueue(const QueueSP & queue_sp)21514f1b3e8SDimitry Andric SBQueue::SBQueue(const QueueSP &queue_sp)
2165f29bb8aSDimitry Andric     : m_opaque_sp(new QueueImpl(queue_sp)) {
2176f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, queue_sp);
2185f29bb8aSDimitry Andric }
219866dcdacSEd Maste 
SBQueue(const SBQueue & rhs)22014f1b3e8SDimitry Andric SBQueue::SBQueue(const SBQueue &rhs) {
2216f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
2225f29bb8aSDimitry Andric 
223866dcdacSEd Maste   if (&rhs == this)
224866dcdacSEd Maste     return;
225866dcdacSEd Maste 
226866dcdacSEd Maste   m_opaque_sp = rhs.m_opaque_sp;
227866dcdacSEd Maste }
228866dcdacSEd Maste 
operator =(const lldb::SBQueue & rhs)22914f1b3e8SDimitry Andric const lldb::SBQueue &SBQueue::operator=(const lldb::SBQueue &rhs) {
2306f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, rhs);
2315f29bb8aSDimitry Andric 
232866dcdacSEd Maste   m_opaque_sp = rhs.m_opaque_sp;
2336f8fc217SDimitry Andric   return *this;
234866dcdacSEd Maste }
235866dcdacSEd Maste 
236cfca06d7SDimitry Andric SBQueue::~SBQueue() = default;
237866dcdacSEd Maste 
IsValid() const23814f1b3e8SDimitry Andric bool SBQueue::IsValid() const {
2396f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2405f29bb8aSDimitry Andric   return this->operator bool();
2415f29bb8aSDimitry Andric }
operator bool() const2425f29bb8aSDimitry Andric SBQueue::operator bool() const {
2436f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2445f29bb8aSDimitry Andric 
2455f29bb8aSDimitry Andric   return m_opaque_sp->IsValid();
246866dcdacSEd Maste }
247866dcdacSEd Maste 
Clear()24814f1b3e8SDimitry Andric void SBQueue::Clear() {
2496f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2505f29bb8aSDimitry Andric 
251866dcdacSEd Maste   m_opaque_sp->Clear();
252866dcdacSEd Maste }
253866dcdacSEd Maste 
SetQueue(const QueueSP & queue_sp)25414f1b3e8SDimitry Andric void SBQueue::SetQueue(const QueueSP &queue_sp) {
255866dcdacSEd Maste   m_opaque_sp->SetQueue(queue_sp);
256866dcdacSEd Maste }
257866dcdacSEd Maste 
GetQueueID() const25814f1b3e8SDimitry Andric lldb::queue_id_t SBQueue::GetQueueID() const {
2596f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2605f29bb8aSDimitry Andric 
2615f29bb8aSDimitry Andric   return m_opaque_sp->GetQueueID();
262866dcdacSEd Maste }
263866dcdacSEd Maste 
GetIndexID() const26414f1b3e8SDimitry Andric uint32_t SBQueue::GetIndexID() const {
2656f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2665f29bb8aSDimitry Andric 
2670cac4ca3SEd Maste   uint32_t index_id = m_opaque_sp->GetIndexID();
2680cac4ca3SEd Maste   return index_id;
269866dcdacSEd Maste }
270866dcdacSEd Maste 
GetName() const27114f1b3e8SDimitry Andric const char *SBQueue::GetName() const {
2726f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2735f29bb8aSDimitry Andric 
2745f29bb8aSDimitry Andric   return m_opaque_sp->GetName();
275866dcdacSEd Maste }
276866dcdacSEd Maste 
GetNumThreads()27714f1b3e8SDimitry Andric uint32_t SBQueue::GetNumThreads() {
2786f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2795f29bb8aSDimitry Andric 
2805f29bb8aSDimitry Andric   return m_opaque_sp->GetNumThreads();
281866dcdacSEd Maste }
282866dcdacSEd Maste 
GetThreadAtIndex(uint32_t idx)28314f1b3e8SDimitry Andric SBThread SBQueue::GetThreadAtIndex(uint32_t idx) {
2846f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, idx);
2855f29bb8aSDimitry Andric 
2860cac4ca3SEd Maste   SBThread th = m_opaque_sp->GetThreadAtIndex(idx);
2876f8fc217SDimitry Andric   return th;
288866dcdacSEd Maste }
289866dcdacSEd Maste 
GetNumPendingItems()29014f1b3e8SDimitry Andric uint32_t SBQueue::GetNumPendingItems() {
2916f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
2925f29bb8aSDimitry Andric 
2935f29bb8aSDimitry Andric   return m_opaque_sp->GetNumPendingItems();
294866dcdacSEd Maste }
295866dcdacSEd Maste 
GetPendingItemAtIndex(uint32_t idx)29614f1b3e8SDimitry Andric SBQueueItem SBQueue::GetPendingItemAtIndex(uint32_t idx) {
2976f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this, idx);
2985f29bb8aSDimitry Andric 
2996f8fc217SDimitry Andric   return m_opaque_sp->GetPendingItemAtIndex(idx);
300866dcdacSEd Maste }
301866dcdacSEd Maste 
GetNumRunningItems()30214f1b3e8SDimitry Andric uint32_t SBQueue::GetNumRunningItems() {
3036f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3045f29bb8aSDimitry Andric 
3055f29bb8aSDimitry Andric   return m_opaque_sp->GetNumRunningItems();
3060cac4ca3SEd Maste }
3070cac4ca3SEd Maste 
GetProcess()3085f29bb8aSDimitry Andric SBProcess SBQueue::GetProcess() {
3096f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3100cac4ca3SEd Maste 
3116f8fc217SDimitry Andric   return m_opaque_sp->GetProcess();
3125f29bb8aSDimitry Andric }
3135f29bb8aSDimitry Andric 
GetKind()3145f29bb8aSDimitry Andric lldb::QueueKind SBQueue::GetKind() {
3156f8fc217SDimitry Andric   LLDB_INSTRUMENT_VA(this);
3165f29bb8aSDimitry Andric 
3175f29bb8aSDimitry Andric   return m_opaque_sp->GetKind();
3185f29bb8aSDimitry Andric }
319