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 11d51402acSJonas Devlieghere #include "lldb/Utility/ReproducerInstrumentation.h" 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" 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: 30a3436f73SKazu Hirata QueueImpl() {} 315e8dce4dSJason Molenda 32b9c1b51eSKate Stone QueueImpl(const lldb::QueueSP &queue_sp) 33a3436f73SKazu Hirata : m_thread_list_fetched(false), m_pending_items_fetched(false) { 34b97f44d9SJason Molenda m_queue_wp = queue_sp; 355e8dce4dSJason Molenda } 365e8dce4dSJason Molenda 37b9c1b51eSKate Stone QueueImpl(const QueueImpl &rhs) { 38c8064ac6SJason Molenda if (&rhs == this) 39c8064ac6SJason Molenda return; 40c8064ac6SJason Molenda m_queue_wp = rhs.m_queue_wp; 41c8064ac6SJason Molenda m_threads = rhs.m_threads; 42c8064ac6SJason Molenda m_thread_list_fetched = rhs.m_thread_list_fetched; 432fd83355SJason Molenda m_pending_items = rhs.m_pending_items; 442fd83355SJason Molenda m_pending_items_fetched = rhs.m_pending_items_fetched; 45c8064ac6SJason Molenda } 46c8064ac6SJason Molenda 47866b7a65SJonas Devlieghere ~QueueImpl() = default; 485e8dce4dSJason Molenda 49248a1305SKonrad Kleine bool IsValid() { return m_queue_wp.lock() != nullptr; } 505e8dce4dSJason Molenda 51b9c1b51eSKate Stone void Clear() { 525e8dce4dSJason Molenda m_queue_wp.reset(); 535e8dce4dSJason Molenda m_thread_list_fetched = false; 545e8dce4dSJason Molenda m_threads.clear(); 552fd83355SJason Molenda m_pending_items_fetched = false; 562fd83355SJason Molenda m_pending_items.clear(); 575e8dce4dSJason Molenda } 585e8dce4dSJason Molenda 59b9c1b51eSKate Stone void SetQueue(const lldb::QueueSP &queue_sp) { 60c8064ac6SJason Molenda Clear(); 615e8dce4dSJason Molenda m_queue_wp = queue_sp; 625e8dce4dSJason Molenda } 635e8dce4dSJason Molenda 64b9c1b51eSKate Stone lldb::queue_id_t GetQueueID() const { 65c8064ac6SJason Molenda lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID; 66c8064ac6SJason Molenda lldb::QueueSP queue_sp = m_queue_wp.lock(); 67b9c1b51eSKate Stone if (queue_sp) { 685e8dce4dSJason Molenda result = queue_sp->GetID(); 695e8dce4dSJason Molenda } 705e8dce4dSJason Molenda return result; 715e8dce4dSJason Molenda } 725e8dce4dSJason Molenda 73b9c1b51eSKate Stone uint32_t GetIndexID() const { 745e8dce4dSJason Molenda uint32_t result = LLDB_INVALID_INDEX32; 75c8064ac6SJason Molenda lldb::QueueSP queue_sp = m_queue_wp.lock(); 76b9c1b51eSKate Stone if (queue_sp) { 775e8dce4dSJason Molenda result = queue_sp->GetIndexID(); 785e8dce4dSJason Molenda } 795e8dce4dSJason Molenda return result; 805e8dce4dSJason Molenda } 815e8dce4dSJason Molenda 82b9c1b51eSKate Stone const char *GetName() const { 83248a1305SKonrad Kleine const char *name = nullptr; 84c8064ac6SJason Molenda lldb::QueueSP queue_sp = m_queue_wp.lock(); 85b9c1b51eSKate Stone if (queue_sp.get()) { 865e8dce4dSJason Molenda name = queue_sp->GetName(); 875e8dce4dSJason Molenda } 885e8dce4dSJason Molenda return name; 895e8dce4dSJason Molenda } 905e8dce4dSJason Molenda 91b9c1b51eSKate Stone void FetchThreads() { 92a6682a41SJonas Devlieghere if (!m_thread_list_fetched) { 93c8064ac6SJason Molenda lldb::QueueSP queue_sp = m_queue_wp.lock(); 94b9c1b51eSKate Stone if (queue_sp) { 955e8dce4dSJason Molenda Process::StopLocker stop_locker; 96b9c1b51eSKate Stone if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) { 975e8dce4dSJason Molenda const std::vector<ThreadSP> thread_list(queue_sp->GetThreads()); 985e8dce4dSJason Molenda m_thread_list_fetched = true; 995e8dce4dSJason Molenda const uint32_t num_threads = thread_list.size(); 100b9c1b51eSKate Stone for (uint32_t idx = 0; idx < num_threads; ++idx) { 1015e8dce4dSJason Molenda ThreadSP thread_sp = thread_list[idx]; 102b9c1b51eSKate Stone if (thread_sp && thread_sp->IsValid()) { 1035e8dce4dSJason Molenda m_threads.push_back(thread_sp); 1045e8dce4dSJason Molenda } 1055e8dce4dSJason Molenda } 1065e8dce4dSJason Molenda } 1075e8dce4dSJason Molenda } 1085e8dce4dSJason Molenda } 1095e8dce4dSJason Molenda } 1105e8dce4dSJason Molenda 111b9c1b51eSKate Stone void FetchItems() { 112a6682a41SJonas Devlieghere if (!m_pending_items_fetched) { 1135e8dce4dSJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 114b9c1b51eSKate Stone if (queue_sp) { 1155e8dce4dSJason Molenda Process::StopLocker stop_locker; 116b9c1b51eSKate Stone if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) { 117b9c1b51eSKate Stone const std::vector<QueueItemSP> queue_items( 118b9c1b51eSKate Stone queue_sp->GetPendingItems()); 1192fd83355SJason Molenda m_pending_items_fetched = true; 1202fd83355SJason Molenda const uint32_t num_pending_items = queue_items.size(); 121b9c1b51eSKate Stone for (uint32_t idx = 0; idx < num_pending_items; ++idx) { 1225e8dce4dSJason Molenda QueueItemSP item = queue_items[idx]; 123b9c1b51eSKate Stone if (item && item->IsValid()) { 1242fd83355SJason Molenda m_pending_items.push_back(item); 1255e8dce4dSJason Molenda } 1265e8dce4dSJason Molenda } 1275e8dce4dSJason Molenda } 1285e8dce4dSJason Molenda } 1295e8dce4dSJason Molenda } 1305e8dce4dSJason Molenda } 1315e8dce4dSJason Molenda 132b9c1b51eSKate Stone uint32_t GetNumThreads() { 1335e8dce4dSJason Molenda uint32_t result = 0; 1345e8dce4dSJason Molenda 1355e8dce4dSJason Molenda FetchThreads(); 136b9c1b51eSKate Stone if (m_thread_list_fetched) { 1375e8dce4dSJason Molenda result = m_threads.size(); 1385e8dce4dSJason Molenda } 1395e8dce4dSJason Molenda return result; 1405e8dce4dSJason Molenda } 1415e8dce4dSJason Molenda 142b9c1b51eSKate Stone lldb::SBThread GetThreadAtIndex(uint32_t idx) { 1435e8dce4dSJason Molenda FetchThreads(); 1445e8dce4dSJason Molenda 1455e8dce4dSJason Molenda SBThread sb_thread; 1465e8dce4dSJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 147b9c1b51eSKate Stone if (queue_sp && idx < m_threads.size()) { 1485e8dce4dSJason Molenda ProcessSP process_sp = queue_sp->GetProcess(); 149b9c1b51eSKate Stone if (process_sp) { 1505e8dce4dSJason Molenda ThreadSP thread_sp = m_threads[idx].lock(); 151b9c1b51eSKate Stone if (thread_sp) { 1525e8dce4dSJason Molenda sb_thread.SetThread(thread_sp); 1535e8dce4dSJason Molenda } 1545e8dce4dSJason Molenda } 1555e8dce4dSJason Molenda } 1565e8dce4dSJason Molenda return sb_thread; 1575e8dce4dSJason Molenda } 1585e8dce4dSJason Molenda 159b9c1b51eSKate Stone uint32_t GetNumPendingItems() { 1605e8dce4dSJason Molenda uint32_t result = 0; 1615e8dce4dSJason Molenda 162fe95dc95SJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 163a6682a41SJonas Devlieghere if (!m_pending_items_fetched && queue_sp) { 164fe95dc95SJason Molenda result = queue_sp->GetNumPendingWorkItems(); 165b9c1b51eSKate Stone } else { 1662fd83355SJason Molenda result = m_pending_items.size(); 1675e8dce4dSJason Molenda } 1685e8dce4dSJason Molenda return result; 1695e8dce4dSJason Molenda } 1705e8dce4dSJason Molenda 171b9c1b51eSKate Stone lldb::SBQueueItem GetPendingItemAtIndex(uint32_t idx) { 1725e8dce4dSJason Molenda SBQueueItem result; 1735e8dce4dSJason Molenda FetchItems(); 174b9c1b51eSKate Stone if (m_pending_items_fetched && idx < m_pending_items.size()) { 1752fd83355SJason Molenda result.SetQueueItem(m_pending_items[idx]); 1765e8dce4dSJason Molenda } 1775e8dce4dSJason Molenda return result; 1785e8dce4dSJason Molenda } 1795e8dce4dSJason Molenda 180b9c1b51eSKate Stone uint32_t GetNumRunningItems() { 181fe95dc95SJason Molenda uint32_t result = 0; 182fe95dc95SJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 183fe95dc95SJason Molenda if (queue_sp) 184fe95dc95SJason Molenda result = queue_sp->GetNumRunningWorkItems(); 185fe95dc95SJason Molenda return result; 186fe95dc95SJason Molenda } 187fe95dc95SJason Molenda 188b9c1b51eSKate Stone lldb::SBProcess GetProcess() { 1895e8dce4dSJason Molenda SBProcess result; 1905e8dce4dSJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 191b9c1b51eSKate Stone if (queue_sp) { 1925e8dce4dSJason Molenda result.SetSP(queue_sp->GetProcess()); 1935e8dce4dSJason Molenda } 1945e8dce4dSJason Molenda return result; 1955e8dce4dSJason Molenda } 196c8064ac6SJason Molenda 197b9c1b51eSKate Stone lldb::QueueKind GetKind() { 198aac16e0fSJason Molenda lldb::QueueKind kind = eQueueKindUnknown; 199aac16e0fSJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 200aac16e0fSJason Molenda if (queue_sp) 201aac16e0fSJason Molenda kind = queue_sp->GetKind(); 202aac16e0fSJason Molenda 203aac16e0fSJason Molenda return kind; 204aac16e0fSJason Molenda } 205aac16e0fSJason Molenda 206c8064ac6SJason Molenda private: 207c8064ac6SJason Molenda lldb::QueueWP m_queue_wp; 208b9c1b51eSKate Stone std::vector<lldb::ThreadWP> 209b9c1b51eSKate Stone m_threads; // threads currently executing this queue's items 2109494c510SJonas Devlieghere bool m_thread_list_fetched = 2119494c510SJonas Devlieghere false; // have we tried to fetch the threads list already? 2122fd83355SJason Molenda std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued 2139494c510SJonas Devlieghere bool m_pending_items_fetched = 2149494c510SJonas Devlieghere false; // have we tried to fetch the item list already? 215c8064ac6SJason Molenda }; 216c8064ac6SJason Molenda } 217c8064ac6SJason Molenda 218baf5664fSJonas Devlieghere SBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) { 219baf5664fSJonas Devlieghere LLDB_RECORD_CONSTRUCTOR_NO_ARGS(SBQueue); 220baf5664fSJonas Devlieghere } 221c8064ac6SJason Molenda 222b9c1b51eSKate Stone SBQueue::SBQueue(const QueueSP &queue_sp) 223baf5664fSJonas Devlieghere : m_opaque_sp(new QueueImpl(queue_sp)) { 224baf5664fSJonas Devlieghere LLDB_RECORD_CONSTRUCTOR(SBQueue, (const lldb::QueueSP &), queue_sp); 225baf5664fSJonas Devlieghere } 226c8064ac6SJason Molenda 227b9c1b51eSKate Stone SBQueue::SBQueue(const SBQueue &rhs) { 228baf5664fSJonas Devlieghere LLDB_RECORD_CONSTRUCTOR(SBQueue, (const lldb::SBQueue &), rhs); 229baf5664fSJonas Devlieghere 230c8064ac6SJason Molenda if (&rhs == this) 231c8064ac6SJason Molenda return; 232c8064ac6SJason Molenda 233c8064ac6SJason Molenda m_opaque_sp = rhs.m_opaque_sp; 234c8064ac6SJason Molenda } 235c8064ac6SJason Molenda 236b9c1b51eSKate Stone const lldb::SBQueue &SBQueue::operator=(const lldb::SBQueue &rhs) { 237baf5664fSJonas Devlieghere LLDB_RECORD_METHOD(const lldb::SBQueue &, 238baf5664fSJonas Devlieghere SBQueue, operator=,(const lldb::SBQueue &), rhs); 239baf5664fSJonas Devlieghere 240c8064ac6SJason Molenda m_opaque_sp = rhs.m_opaque_sp; 241*d232abc3SJonas Devlieghere return *this; 242c8064ac6SJason Molenda } 243c8064ac6SJason Molenda 244866b7a65SJonas Devlieghere SBQueue::~SBQueue() = default; 245c8064ac6SJason Molenda 246b9c1b51eSKate Stone bool SBQueue::IsValid() const { 247baf5664fSJonas Devlieghere LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBQueue, IsValid); 2487f5237bcSPavel Labath return this->operator bool(); 2497f5237bcSPavel Labath } 2507f5237bcSPavel Labath SBQueue::operator bool() const { 2517f5237bcSPavel Labath LLDB_RECORD_METHOD_CONST_NO_ARGS(bool, SBQueue, operator bool); 252baf5664fSJonas Devlieghere 253581af8b0SJonas Devlieghere return m_opaque_sp->IsValid(); 254c8064ac6SJason Molenda } 255c8064ac6SJason Molenda 256b9c1b51eSKate Stone void SBQueue::Clear() { 257baf5664fSJonas Devlieghere LLDB_RECORD_METHOD_NO_ARGS(void, SBQueue, Clear); 258baf5664fSJonas Devlieghere 259c8064ac6SJason Molenda m_opaque_sp->Clear(); 260c8064ac6SJason Molenda } 261c8064ac6SJason Molenda 262b9c1b51eSKate Stone void SBQueue::SetQueue(const QueueSP &queue_sp) { 263c8064ac6SJason Molenda m_opaque_sp->SetQueue(queue_sp); 264c8064ac6SJason Molenda } 265c8064ac6SJason Molenda 266b9c1b51eSKate Stone lldb::queue_id_t SBQueue::GetQueueID() const { 267baf5664fSJonas Devlieghere LLDB_RECORD_METHOD_CONST_NO_ARGS(lldb::queue_id_t, SBQueue, GetQueueID); 268baf5664fSJonas Devlieghere 269581af8b0SJonas Devlieghere return m_opaque_sp->GetQueueID(); 270c8064ac6SJason Molenda } 271c8064ac6SJason Molenda 272b9c1b51eSKate Stone uint32_t SBQueue::GetIndexID() const { 273baf5664fSJonas Devlieghere LLDB_RECORD_METHOD_CONST_NO_ARGS(uint32_t, SBQueue, GetIndexID); 274baf5664fSJonas Devlieghere 275ac605f4aSJason Molenda uint32_t index_id = m_opaque_sp->GetIndexID(); 276ac605f4aSJason Molenda return index_id; 277c8064ac6SJason Molenda } 278c8064ac6SJason Molenda 279b9c1b51eSKate Stone const char *SBQueue::GetName() const { 280baf5664fSJonas Devlieghere LLDB_RECORD_METHOD_CONST_NO_ARGS(const char *, SBQueue, GetName); 281baf5664fSJonas Devlieghere 282581af8b0SJonas Devlieghere return m_opaque_sp->GetName(); 283c8064ac6SJason Molenda } 284c8064ac6SJason Molenda 285b9c1b51eSKate Stone uint32_t SBQueue::GetNumThreads() { 286baf5664fSJonas Devlieghere LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBQueue, GetNumThreads); 287baf5664fSJonas Devlieghere 288581af8b0SJonas Devlieghere return m_opaque_sp->GetNumThreads(); 289c8064ac6SJason Molenda } 290c8064ac6SJason Molenda 291b9c1b51eSKate Stone SBThread SBQueue::GetThreadAtIndex(uint32_t idx) { 292baf5664fSJonas Devlieghere LLDB_RECORD_METHOD(lldb::SBThread, SBQueue, GetThreadAtIndex, (uint32_t), 293baf5664fSJonas Devlieghere idx); 294baf5664fSJonas Devlieghere 295ac605f4aSJason Molenda SBThread th = m_opaque_sp->GetThreadAtIndex(idx); 296*d232abc3SJonas Devlieghere return th; 297c8064ac6SJason Molenda } 298c8064ac6SJason Molenda 299b9c1b51eSKate Stone uint32_t SBQueue::GetNumPendingItems() { 300baf5664fSJonas Devlieghere LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBQueue, GetNumPendingItems); 301baf5664fSJonas Devlieghere 302581af8b0SJonas Devlieghere return m_opaque_sp->GetNumPendingItems(); 303c8064ac6SJason Molenda } 304c8064ac6SJason Molenda 305b9c1b51eSKate Stone SBQueueItem SBQueue::GetPendingItemAtIndex(uint32_t idx) { 306baf5664fSJonas Devlieghere LLDB_RECORD_METHOD(lldb::SBQueueItem, SBQueue, GetPendingItemAtIndex, 307baf5664fSJonas Devlieghere (uint32_t), idx); 308baf5664fSJonas Devlieghere 309*d232abc3SJonas Devlieghere return m_opaque_sp->GetPendingItemAtIndex(idx); 310c8064ac6SJason Molenda } 311c8064ac6SJason Molenda 312b9c1b51eSKate Stone uint32_t SBQueue::GetNumRunningItems() { 313baf5664fSJonas Devlieghere LLDB_RECORD_METHOD_NO_ARGS(uint32_t, SBQueue, GetNumRunningItems); 314baf5664fSJonas Devlieghere 315581af8b0SJonas Devlieghere return m_opaque_sp->GetNumRunningItems(); 316fe95dc95SJason Molenda } 317fe95dc95SJason Molenda 318baf5664fSJonas Devlieghere SBProcess SBQueue::GetProcess() { 319baf5664fSJonas Devlieghere LLDB_RECORD_METHOD_NO_ARGS(lldb::SBProcess, SBQueue, GetProcess); 320aac16e0fSJason Molenda 321*d232abc3SJonas Devlieghere return m_opaque_sp->GetProcess(); 322baf5664fSJonas Devlieghere } 323baf5664fSJonas Devlieghere 324baf5664fSJonas Devlieghere lldb::QueueKind SBQueue::GetKind() { 325baf5664fSJonas Devlieghere LLDB_RECORD_METHOD_NO_ARGS(lldb::QueueKind, SBQueue, GetKind); 326baf5664fSJonas Devlieghere 327baf5664fSJonas Devlieghere return m_opaque_sp->GetKind(); 328baf5664fSJonas Devlieghere } 329