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 AndricSBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) { LLDB_INSTRUMENT_VA(this); } 214866dcdacSEd Maste SBQueue(const QueueSP & queue_sp)21514f1b3e8SDimitry AndricSBQueue::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 AndricSBQueue::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 Andricconst 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 Andricbool SBQueue::IsValid() const { 2396f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this); 2405f29bb8aSDimitry Andric return this->operator bool(); 2415f29bb8aSDimitry Andric } operator bool() const2425f29bb8aSDimitry AndricSBQueue::operator bool() const { 2436f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this); 2445f29bb8aSDimitry Andric 2455f29bb8aSDimitry Andric return m_opaque_sp->IsValid(); 246866dcdacSEd Maste } 247866dcdacSEd Maste Clear()24814f1b3e8SDimitry Andricvoid 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 Andricvoid SBQueue::SetQueue(const QueueSP &queue_sp) { 255866dcdacSEd Maste m_opaque_sp->SetQueue(queue_sp); 256866dcdacSEd Maste } 257866dcdacSEd Maste GetQueueID() const25814f1b3e8SDimitry Andriclldb::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 Andricuint32_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 Andricconst 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 Andricuint32_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 AndricSBThread 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 Andricuint32_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 AndricSBQueueItem 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 Andricuint32_t SBQueue::GetNumRunningItems() { 3036f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this); 3045f29bb8aSDimitry Andric 3055f29bb8aSDimitry Andric return m_opaque_sp->GetNumRunningItems(); 3060cac4ca3SEd Maste } 3070cac4ca3SEd Maste GetProcess()3085f29bb8aSDimitry AndricSBProcess SBQueue::GetProcess() { 3096f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this); 3100cac4ca3SEd Maste 3116f8fc217SDimitry Andric return m_opaque_sp->GetProcess(); 3125f29bb8aSDimitry Andric } 3135f29bb8aSDimitry Andric GetKind()3145f29bb8aSDimitry Andriclldb::QueueKind SBQueue::GetKind() { 3156f8fc217SDimitry Andric LLDB_INSTRUMENT_VA(this); 3165f29bb8aSDimitry Andric 3175f29bb8aSDimitry Andric return m_opaque_sp->GetKind(); 3185f29bb8aSDimitry Andric } 319