180814287SRaphael Isemann //===-- SBQueue.cpp -------------------------------------------------------===// 25e8dce4dSJason Molenda // 32946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 42946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 52946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65e8dce4dSJason Molenda // 75e8dce4dSJason Molenda //===----------------------------------------------------------------------===// 85e8dce4dSJason Molenda 976e47d48SRaphael Isemann #include <cinttypes> 10da0fc76eSVirgile Bello 115e8dce4dSJason Molenda #include "lldb/API/SBQueue.h" 121755f5b1SJonas Devlieghere #include "lldb/Utility/Instrumentation.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" 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: 30*24f9a2f5SShafik Yaghmour QueueImpl() = default; 315e8dce4dSJason Molenda QueueImpl(const lldb::QueueSP & queue_sp)3228c878aeSShafik Yaghmour QueueImpl(const lldb::QueueSP &queue_sp) { m_queue_wp = queue_sp; } 335e8dce4dSJason Molenda QueueImpl(const QueueImpl & rhs)34b9c1b51eSKate Stone QueueImpl(const QueueImpl &rhs) { 35c8064ac6SJason Molenda if (&rhs == this) 36c8064ac6SJason Molenda return; 37c8064ac6SJason Molenda m_queue_wp = rhs.m_queue_wp; 38c8064ac6SJason Molenda m_threads = rhs.m_threads; 39c8064ac6SJason Molenda m_thread_list_fetched = rhs.m_thread_list_fetched; 402fd83355SJason Molenda m_pending_items = rhs.m_pending_items; 412fd83355SJason Molenda m_pending_items_fetched = rhs.m_pending_items_fetched; 42c8064ac6SJason Molenda } 43c8064ac6SJason Molenda 44866b7a65SJonas Devlieghere ~QueueImpl() = default; 455e8dce4dSJason Molenda IsValid()46248a1305SKonrad Kleine bool IsValid() { return m_queue_wp.lock() != nullptr; } 475e8dce4dSJason Molenda Clear()48b9c1b51eSKate Stone void Clear() { 495e8dce4dSJason Molenda m_queue_wp.reset(); 505e8dce4dSJason Molenda m_thread_list_fetched = false; 515e8dce4dSJason Molenda m_threads.clear(); 522fd83355SJason Molenda m_pending_items_fetched = false; 532fd83355SJason Molenda m_pending_items.clear(); 545e8dce4dSJason Molenda } 555e8dce4dSJason Molenda SetQueue(const lldb::QueueSP & queue_sp)56b9c1b51eSKate Stone void SetQueue(const lldb::QueueSP &queue_sp) { 57c8064ac6SJason Molenda Clear(); 585e8dce4dSJason Molenda m_queue_wp = queue_sp; 595e8dce4dSJason Molenda } 605e8dce4dSJason Molenda GetQueueID() const61b9c1b51eSKate Stone lldb::queue_id_t GetQueueID() const { 62c8064ac6SJason Molenda lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID; 63c8064ac6SJason Molenda lldb::QueueSP queue_sp = m_queue_wp.lock(); 64b9c1b51eSKate Stone if (queue_sp) { 655e8dce4dSJason Molenda result = queue_sp->GetID(); 665e8dce4dSJason Molenda } 675e8dce4dSJason Molenda return result; 685e8dce4dSJason Molenda } 695e8dce4dSJason Molenda GetIndexID() const70b9c1b51eSKate Stone uint32_t GetIndexID() const { 715e8dce4dSJason Molenda uint32_t result = LLDB_INVALID_INDEX32; 72c8064ac6SJason Molenda lldb::QueueSP queue_sp = m_queue_wp.lock(); 73b9c1b51eSKate Stone if (queue_sp) { 745e8dce4dSJason Molenda result = queue_sp->GetIndexID(); 755e8dce4dSJason Molenda } 765e8dce4dSJason Molenda return result; 775e8dce4dSJason Molenda } 785e8dce4dSJason Molenda GetName() const79b9c1b51eSKate Stone const char *GetName() const { 80248a1305SKonrad Kleine const char *name = nullptr; 81c8064ac6SJason Molenda lldb::QueueSP queue_sp = m_queue_wp.lock(); 82b9c1b51eSKate Stone if (queue_sp.get()) { 835e8dce4dSJason Molenda name = queue_sp->GetName(); 845e8dce4dSJason Molenda } 855e8dce4dSJason Molenda return name; 865e8dce4dSJason Molenda } 875e8dce4dSJason Molenda FetchThreads()88b9c1b51eSKate Stone void FetchThreads() { 89a6682a41SJonas Devlieghere if (!m_thread_list_fetched) { 90c8064ac6SJason Molenda lldb::QueueSP queue_sp = m_queue_wp.lock(); 91b9c1b51eSKate Stone if (queue_sp) { 925e8dce4dSJason Molenda Process::StopLocker stop_locker; 93b9c1b51eSKate Stone if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) { 945e8dce4dSJason Molenda const std::vector<ThreadSP> thread_list(queue_sp->GetThreads()); 955e8dce4dSJason Molenda m_thread_list_fetched = true; 965e8dce4dSJason Molenda const uint32_t num_threads = thread_list.size(); 97b9c1b51eSKate Stone for (uint32_t idx = 0; idx < num_threads; ++idx) { 985e8dce4dSJason Molenda ThreadSP thread_sp = thread_list[idx]; 99b9c1b51eSKate Stone if (thread_sp && thread_sp->IsValid()) { 1005e8dce4dSJason Molenda m_threads.push_back(thread_sp); 1015e8dce4dSJason Molenda } 1025e8dce4dSJason Molenda } 1035e8dce4dSJason Molenda } 1045e8dce4dSJason Molenda } 1055e8dce4dSJason Molenda } 1065e8dce4dSJason Molenda } 1075e8dce4dSJason Molenda FetchItems()108b9c1b51eSKate Stone void FetchItems() { 109a6682a41SJonas Devlieghere if (!m_pending_items_fetched) { 1105e8dce4dSJason Molenda 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())) { 114b9c1b51eSKate Stone const std::vector<QueueItemSP> queue_items( 115b9c1b51eSKate Stone queue_sp->GetPendingItems()); 1162fd83355SJason Molenda m_pending_items_fetched = true; 1172fd83355SJason Molenda const uint32_t num_pending_items = queue_items.size(); 118b9c1b51eSKate Stone for (uint32_t idx = 0; idx < num_pending_items; ++idx) { 1195e8dce4dSJason Molenda QueueItemSP item = queue_items[idx]; 120b9c1b51eSKate Stone if (item && item->IsValid()) { 1212fd83355SJason Molenda m_pending_items.push_back(item); 1225e8dce4dSJason Molenda } 1235e8dce4dSJason Molenda } 1245e8dce4dSJason Molenda } 1255e8dce4dSJason Molenda } 1265e8dce4dSJason Molenda } 1275e8dce4dSJason Molenda } 1285e8dce4dSJason Molenda GetNumThreads()129b9c1b51eSKate Stone uint32_t GetNumThreads() { 1305e8dce4dSJason Molenda uint32_t result = 0; 1315e8dce4dSJason Molenda 1325e8dce4dSJason Molenda FetchThreads(); 133b9c1b51eSKate Stone if (m_thread_list_fetched) { 1345e8dce4dSJason Molenda result = m_threads.size(); 1355e8dce4dSJason Molenda } 1365e8dce4dSJason Molenda return result; 1375e8dce4dSJason Molenda } 1385e8dce4dSJason Molenda GetThreadAtIndex(uint32_t idx)139b9c1b51eSKate Stone lldb::SBThread GetThreadAtIndex(uint32_t idx) { 1405e8dce4dSJason Molenda FetchThreads(); 1415e8dce4dSJason Molenda 1425e8dce4dSJason Molenda SBThread sb_thread; 1435e8dce4dSJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 144b9c1b51eSKate Stone if (queue_sp && idx < m_threads.size()) { 1455e8dce4dSJason Molenda ProcessSP process_sp = queue_sp->GetProcess(); 146b9c1b51eSKate Stone if (process_sp) { 1475e8dce4dSJason Molenda ThreadSP thread_sp = m_threads[idx].lock(); 148b9c1b51eSKate Stone if (thread_sp) { 1495e8dce4dSJason Molenda sb_thread.SetThread(thread_sp); 1505e8dce4dSJason Molenda } 1515e8dce4dSJason Molenda } 1525e8dce4dSJason Molenda } 1535e8dce4dSJason Molenda return sb_thread; 1545e8dce4dSJason Molenda } 1555e8dce4dSJason Molenda GetNumPendingItems()156b9c1b51eSKate Stone uint32_t GetNumPendingItems() { 1575e8dce4dSJason Molenda uint32_t result = 0; 1585e8dce4dSJason Molenda 159fe95dc95SJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 160a6682a41SJonas Devlieghere if (!m_pending_items_fetched && queue_sp) { 161fe95dc95SJason Molenda result = queue_sp->GetNumPendingWorkItems(); 162b9c1b51eSKate Stone } else { 1632fd83355SJason Molenda result = m_pending_items.size(); 1645e8dce4dSJason Molenda } 1655e8dce4dSJason Molenda return result; 1665e8dce4dSJason Molenda } 1675e8dce4dSJason Molenda GetPendingItemAtIndex(uint32_t idx)168b9c1b51eSKate Stone lldb::SBQueueItem GetPendingItemAtIndex(uint32_t idx) { 1695e8dce4dSJason Molenda SBQueueItem result; 1705e8dce4dSJason Molenda FetchItems(); 171b9c1b51eSKate Stone if (m_pending_items_fetched && idx < m_pending_items.size()) { 1722fd83355SJason Molenda result.SetQueueItem(m_pending_items[idx]); 1735e8dce4dSJason Molenda } 1745e8dce4dSJason Molenda return result; 1755e8dce4dSJason Molenda } 1765e8dce4dSJason Molenda GetNumRunningItems()177b9c1b51eSKate Stone uint32_t GetNumRunningItems() { 178fe95dc95SJason Molenda uint32_t result = 0; 179fe95dc95SJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 180fe95dc95SJason Molenda if (queue_sp) 181fe95dc95SJason Molenda result = queue_sp->GetNumRunningWorkItems(); 182fe95dc95SJason Molenda return result; 183fe95dc95SJason Molenda } 184fe95dc95SJason Molenda GetProcess()185b9c1b51eSKate Stone lldb::SBProcess GetProcess() { 1865e8dce4dSJason Molenda SBProcess result; 1875e8dce4dSJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 188b9c1b51eSKate Stone if (queue_sp) { 1895e8dce4dSJason Molenda result.SetSP(queue_sp->GetProcess()); 1905e8dce4dSJason Molenda } 1915e8dce4dSJason Molenda return result; 1925e8dce4dSJason Molenda } 193c8064ac6SJason Molenda GetKind()194b9c1b51eSKate Stone lldb::QueueKind GetKind() { 195aac16e0fSJason Molenda lldb::QueueKind kind = eQueueKindUnknown; 196aac16e0fSJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 197aac16e0fSJason Molenda if (queue_sp) 198aac16e0fSJason Molenda kind = queue_sp->GetKind(); 199aac16e0fSJason Molenda 200aac16e0fSJason Molenda return kind; 201aac16e0fSJason Molenda } 202aac16e0fSJason Molenda 203c8064ac6SJason Molenda private: 204c8064ac6SJason Molenda lldb::QueueWP m_queue_wp; 205b9c1b51eSKate Stone std::vector<lldb::ThreadWP> 206b9c1b51eSKate Stone m_threads; // threads currently executing this queue's items 2079494c510SJonas Devlieghere bool m_thread_list_fetched = 2089494c510SJonas Devlieghere false; // have we tried to fetch the threads list already? 2092fd83355SJason Molenda std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued 2109494c510SJonas Devlieghere bool m_pending_items_fetched = 2119494c510SJonas Devlieghere false; // have we tried to fetch the item list already? 212c8064ac6SJason Molenda }; 213c8064ac6SJason Molenda } 214c8064ac6SJason Molenda SBQueue()2151755f5b1SJonas DevlieghereSBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) { LLDB_INSTRUMENT_VA(this); } 216c8064ac6SJason Molenda SBQueue(const QueueSP & queue_sp)217b9c1b51eSKate StoneSBQueue::SBQueue(const QueueSP &queue_sp) 218baf5664fSJonas Devlieghere : m_opaque_sp(new QueueImpl(queue_sp)) { 2191755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, queue_sp); 220baf5664fSJonas Devlieghere } 221c8064ac6SJason Molenda SBQueue(const SBQueue & rhs)222b9c1b51eSKate StoneSBQueue::SBQueue(const SBQueue &rhs) { 2231755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, rhs); 224baf5664fSJonas Devlieghere 225c8064ac6SJason Molenda if (&rhs == this) 226c8064ac6SJason Molenda return; 227c8064ac6SJason Molenda 228c8064ac6SJason Molenda m_opaque_sp = rhs.m_opaque_sp; 229c8064ac6SJason Molenda } 230c8064ac6SJason Molenda operator =(const lldb::SBQueue & rhs)231b9c1b51eSKate Stoneconst lldb::SBQueue &SBQueue::operator=(const lldb::SBQueue &rhs) { 2321755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, rhs); 233baf5664fSJonas Devlieghere 234c8064ac6SJason Molenda m_opaque_sp = rhs.m_opaque_sp; 235d232abc3SJonas Devlieghere return *this; 236c8064ac6SJason Molenda } 237c8064ac6SJason Molenda 238866b7a65SJonas Devlieghere SBQueue::~SBQueue() = default; 239c8064ac6SJason Molenda IsValid() const240b9c1b51eSKate Stonebool SBQueue::IsValid() const { 2411755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this); 2427f5237bcSPavel Labath return this->operator bool(); 2437f5237bcSPavel Labath } operator bool() const2447f5237bcSPavel LabathSBQueue::operator bool() const { 2451755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this); 246baf5664fSJonas Devlieghere 247581af8b0SJonas Devlieghere return m_opaque_sp->IsValid(); 248c8064ac6SJason Molenda } 249c8064ac6SJason Molenda Clear()250b9c1b51eSKate Stonevoid SBQueue::Clear() { 2511755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this); 252baf5664fSJonas Devlieghere 253c8064ac6SJason Molenda m_opaque_sp->Clear(); 254c8064ac6SJason Molenda } 255c8064ac6SJason Molenda SetQueue(const QueueSP & queue_sp)256b9c1b51eSKate Stonevoid SBQueue::SetQueue(const QueueSP &queue_sp) { 257c8064ac6SJason Molenda m_opaque_sp->SetQueue(queue_sp); 258c8064ac6SJason Molenda } 259c8064ac6SJason Molenda GetQueueID() const260b9c1b51eSKate Stonelldb::queue_id_t SBQueue::GetQueueID() const { 2611755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this); 262baf5664fSJonas Devlieghere 263581af8b0SJonas Devlieghere return m_opaque_sp->GetQueueID(); 264c8064ac6SJason Molenda } 265c8064ac6SJason Molenda GetIndexID() const266b9c1b51eSKate Stoneuint32_t SBQueue::GetIndexID() const { 2671755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this); 268baf5664fSJonas Devlieghere 269ac605f4aSJason Molenda uint32_t index_id = m_opaque_sp->GetIndexID(); 270ac605f4aSJason Molenda return index_id; 271c8064ac6SJason Molenda } 272c8064ac6SJason Molenda GetName() const273b9c1b51eSKate Stoneconst char *SBQueue::GetName() const { 2741755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this); 275baf5664fSJonas Devlieghere 276581af8b0SJonas Devlieghere return m_opaque_sp->GetName(); 277c8064ac6SJason Molenda } 278c8064ac6SJason Molenda GetNumThreads()279b9c1b51eSKate Stoneuint32_t SBQueue::GetNumThreads() { 2801755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this); 281baf5664fSJonas Devlieghere 282581af8b0SJonas Devlieghere return m_opaque_sp->GetNumThreads(); 283c8064ac6SJason Molenda } 284c8064ac6SJason Molenda GetThreadAtIndex(uint32_t idx)285b9c1b51eSKate StoneSBThread SBQueue::GetThreadAtIndex(uint32_t idx) { 2861755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, idx); 287baf5664fSJonas Devlieghere 288ac605f4aSJason Molenda SBThread th = m_opaque_sp->GetThreadAtIndex(idx); 289d232abc3SJonas Devlieghere return th; 290c8064ac6SJason Molenda } 291c8064ac6SJason Molenda GetNumPendingItems()292b9c1b51eSKate Stoneuint32_t SBQueue::GetNumPendingItems() { 2931755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this); 294baf5664fSJonas Devlieghere 295581af8b0SJonas Devlieghere return m_opaque_sp->GetNumPendingItems(); 296c8064ac6SJason Molenda } 297c8064ac6SJason Molenda GetPendingItemAtIndex(uint32_t idx)298b9c1b51eSKate StoneSBQueueItem SBQueue::GetPendingItemAtIndex(uint32_t idx) { 2991755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this, idx); 300baf5664fSJonas Devlieghere 301d232abc3SJonas Devlieghere return m_opaque_sp->GetPendingItemAtIndex(idx); 302c8064ac6SJason Molenda } 303c8064ac6SJason Molenda GetNumRunningItems()304b9c1b51eSKate Stoneuint32_t SBQueue::GetNumRunningItems() { 3051755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this); 306baf5664fSJonas Devlieghere 307581af8b0SJonas Devlieghere return m_opaque_sp->GetNumRunningItems(); 308fe95dc95SJason Molenda } 309fe95dc95SJason Molenda GetProcess()310baf5664fSJonas DevlieghereSBProcess SBQueue::GetProcess() { 3111755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this); 312aac16e0fSJason Molenda 313d232abc3SJonas Devlieghere return m_opaque_sp->GetProcess(); 314baf5664fSJonas Devlieghere } 315baf5664fSJonas Devlieghere GetKind()316baf5664fSJonas Devliegherelldb::QueueKind SBQueue::GetKind() { 3171755f5b1SJonas Devlieghere LLDB_INSTRUMENT_VA(this); 318baf5664fSJonas Devlieghere 319baf5664fSJonas Devlieghere return m_opaque_sp->GetKind(); 320baf5664fSJonas Devlieghere } 321