15e8dce4dSJason Molenda //===-- SBQueue.cpp ---------------------------------------------*- C++ -*-===// 25e8dce4dSJason Molenda // 3*2946cd70SChandler Carruth // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*2946cd70SChandler Carruth // See https://llvm.org/LICENSE.txt for license information. 5*2946cd70SChandler Carruth // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 65e8dce4dSJason Molenda // 75e8dce4dSJason Molenda //===----------------------------------------------------------------------===// 85e8dce4dSJason Molenda 9da0fc76eSVirgile Bello #include <inttypes.h> 10da0fc76eSVirgile Bello 115e8dce4dSJason Molenda #include "lldb/API/SBQueue.h" 125e8dce4dSJason Molenda 135e8dce4dSJason Molenda #include "lldb/API/SBProcess.h" 14b9ffa98cSJason Molenda #include "lldb/API/SBQueueItem.h" 15b9c1b51eSKate Stone #include "lldb/API/SBThread.h" 16b9ffa98cSJason Molenda 175e8dce4dSJason Molenda #include "lldb/Target/Process.h" 185e8dce4dSJason Molenda #include "lldb/Target/Queue.h" 195e8dce4dSJason Molenda #include "lldb/Target/QueueItem.h" 205e8dce4dSJason Molenda #include "lldb/Target/Thread.h" 216f9e6901SZachary Turner #include "lldb/Utility/Log.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: 30b9c1b51eSKate Stone QueueImpl() 31b9c1b51eSKate Stone : m_queue_wp(), m_threads(), m_thread_list_fetched(false), 32b9c1b51eSKate Stone m_pending_items(), m_pending_items_fetched(false) {} 335e8dce4dSJason Molenda 34b9c1b51eSKate Stone QueueImpl(const lldb::QueueSP &queue_sp) 35b9c1b51eSKate Stone : m_queue_wp(), m_threads(), m_thread_list_fetched(false), 36b9c1b51eSKate Stone m_pending_items(), m_pending_items_fetched(false) { 37b97f44d9SJason Molenda m_queue_wp = queue_sp; 385e8dce4dSJason Molenda } 395e8dce4dSJason Molenda 40b9c1b51eSKate Stone QueueImpl(const QueueImpl &rhs) { 41c8064ac6SJason Molenda if (&rhs == this) 42c8064ac6SJason Molenda return; 43c8064ac6SJason Molenda m_queue_wp = rhs.m_queue_wp; 44c8064ac6SJason Molenda m_threads = rhs.m_threads; 45c8064ac6SJason Molenda m_thread_list_fetched = rhs.m_thread_list_fetched; 462fd83355SJason Molenda m_pending_items = rhs.m_pending_items; 472fd83355SJason Molenda m_pending_items_fetched = rhs.m_pending_items_fetched; 48c8064ac6SJason Molenda } 49c8064ac6SJason Molenda 50b9c1b51eSKate Stone ~QueueImpl() {} 515e8dce4dSJason Molenda 52b9c1b51eSKate Stone bool IsValid() { return m_queue_wp.lock() != NULL; } 535e8dce4dSJason Molenda 54b9c1b51eSKate Stone void Clear() { 555e8dce4dSJason Molenda m_queue_wp.reset(); 565e8dce4dSJason Molenda m_thread_list_fetched = false; 575e8dce4dSJason Molenda m_threads.clear(); 582fd83355SJason Molenda m_pending_items_fetched = false; 592fd83355SJason Molenda m_pending_items.clear(); 605e8dce4dSJason Molenda } 615e8dce4dSJason Molenda 62b9c1b51eSKate Stone void SetQueue(const lldb::QueueSP &queue_sp) { 63c8064ac6SJason Molenda Clear(); 645e8dce4dSJason Molenda m_queue_wp = queue_sp; 655e8dce4dSJason Molenda } 665e8dce4dSJason Molenda 67b9c1b51eSKate Stone lldb::queue_id_t GetQueueID() const { 68c8064ac6SJason Molenda lldb::queue_id_t result = LLDB_INVALID_QUEUE_ID; 69c8064ac6SJason Molenda lldb::QueueSP queue_sp = m_queue_wp.lock(); 70b9c1b51eSKate Stone if (queue_sp) { 715e8dce4dSJason Molenda result = queue_sp->GetID(); 725e8dce4dSJason Molenda } 735e8dce4dSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 745e8dce4dSJason Molenda if (log) 75324a1036SSaleem Abdulrasool log->Printf("SBQueue(%p)::GetQueueID () => 0x%" PRIx64, 76324a1036SSaleem Abdulrasool static_cast<const void *>(this), result); 775e8dce4dSJason Molenda return result; 785e8dce4dSJason Molenda } 795e8dce4dSJason Molenda 80b9c1b51eSKate Stone uint32_t GetIndexID() const { 815e8dce4dSJason Molenda uint32_t result = LLDB_INVALID_INDEX32; 82c8064ac6SJason Molenda lldb::QueueSP queue_sp = m_queue_wp.lock(); 83b9c1b51eSKate Stone if (queue_sp) { 845e8dce4dSJason Molenda result = queue_sp->GetIndexID(); 855e8dce4dSJason Molenda } 865e8dce4dSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 875e8dce4dSJason Molenda if (log) 88324a1036SSaleem Abdulrasool log->Printf("SBQueueImpl(%p)::GetIndexID () => %d", 89324a1036SSaleem Abdulrasool static_cast<const void *>(this), result); 905e8dce4dSJason Molenda return result; 915e8dce4dSJason Molenda } 925e8dce4dSJason Molenda 93b9c1b51eSKate Stone const char *GetName() const { 945e8dce4dSJason Molenda const char *name = NULL; 95c8064ac6SJason Molenda lldb::QueueSP queue_sp = m_queue_wp.lock(); 96b9c1b51eSKate Stone if (queue_sp.get()) { 975e8dce4dSJason Molenda name = queue_sp->GetName(); 985e8dce4dSJason Molenda } 995e8dce4dSJason Molenda 1005e8dce4dSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 1015e8dce4dSJason Molenda if (log) 102324a1036SSaleem Abdulrasool log->Printf("SBQueueImpl(%p)::GetName () => %s", 103b9c1b51eSKate Stone static_cast<const void *>(this), name ? name : "NULL"); 1045e8dce4dSJason Molenda 1055e8dce4dSJason Molenda return name; 1065e8dce4dSJason Molenda } 1075e8dce4dSJason Molenda 108b9c1b51eSKate Stone void FetchThreads() { 109a6682a41SJonas Devlieghere if (!m_thread_list_fetched) { 110c8064ac6SJason Molenda lldb::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())) { 1145e8dce4dSJason Molenda const std::vector<ThreadSP> thread_list(queue_sp->GetThreads()); 1155e8dce4dSJason Molenda m_thread_list_fetched = true; 1165e8dce4dSJason Molenda const uint32_t num_threads = thread_list.size(); 117b9c1b51eSKate Stone for (uint32_t idx = 0; idx < num_threads; ++idx) { 1185e8dce4dSJason Molenda ThreadSP thread_sp = thread_list[idx]; 119b9c1b51eSKate Stone if (thread_sp && thread_sp->IsValid()) { 1205e8dce4dSJason Molenda m_threads.push_back(thread_sp); 1215e8dce4dSJason Molenda } 1225e8dce4dSJason Molenda } 1235e8dce4dSJason Molenda } 1245e8dce4dSJason Molenda } 1255e8dce4dSJason Molenda } 1265e8dce4dSJason Molenda } 1275e8dce4dSJason Molenda 128b9c1b51eSKate Stone void FetchItems() { 129a6682a41SJonas Devlieghere if (!m_pending_items_fetched) { 1305e8dce4dSJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 131b9c1b51eSKate Stone if (queue_sp) { 1325e8dce4dSJason Molenda Process::StopLocker stop_locker; 133b9c1b51eSKate Stone if (stop_locker.TryLock(&queue_sp->GetProcess()->GetRunLock())) { 134b9c1b51eSKate Stone const std::vector<QueueItemSP> queue_items( 135b9c1b51eSKate Stone queue_sp->GetPendingItems()); 1362fd83355SJason Molenda m_pending_items_fetched = true; 1372fd83355SJason Molenda const uint32_t num_pending_items = queue_items.size(); 138b9c1b51eSKate Stone for (uint32_t idx = 0; idx < num_pending_items; ++idx) { 1395e8dce4dSJason Molenda QueueItemSP item = queue_items[idx]; 140b9c1b51eSKate Stone if (item && item->IsValid()) { 1412fd83355SJason Molenda m_pending_items.push_back(item); 1425e8dce4dSJason Molenda } 1435e8dce4dSJason Molenda } 1445e8dce4dSJason Molenda } 1455e8dce4dSJason Molenda } 1465e8dce4dSJason Molenda } 1475e8dce4dSJason Molenda } 1485e8dce4dSJason Molenda 149b9c1b51eSKate Stone uint32_t GetNumThreads() { 1505e8dce4dSJason Molenda uint32_t result = 0; 1515e8dce4dSJason Molenda 1525e8dce4dSJason Molenda FetchThreads(); 153b9c1b51eSKate Stone if (m_thread_list_fetched) { 1545e8dce4dSJason Molenda result = m_threads.size(); 1555e8dce4dSJason Molenda } 1565e8dce4dSJason Molenda return result; 1575e8dce4dSJason Molenda } 1585e8dce4dSJason Molenda 159b9c1b51eSKate Stone lldb::SBThread GetThreadAtIndex(uint32_t idx) { 1605e8dce4dSJason Molenda FetchThreads(); 1615e8dce4dSJason Molenda 1625e8dce4dSJason Molenda SBThread sb_thread; 1635e8dce4dSJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 164b9c1b51eSKate Stone if (queue_sp && idx < m_threads.size()) { 1655e8dce4dSJason Molenda ProcessSP process_sp = queue_sp->GetProcess(); 166b9c1b51eSKate Stone if (process_sp) { 1675e8dce4dSJason Molenda ThreadSP thread_sp = m_threads[idx].lock(); 168b9c1b51eSKate Stone if (thread_sp) { 1695e8dce4dSJason Molenda sb_thread.SetThread(thread_sp); 1705e8dce4dSJason Molenda } 1715e8dce4dSJason Molenda } 1725e8dce4dSJason Molenda } 1735e8dce4dSJason Molenda return sb_thread; 1745e8dce4dSJason Molenda } 1755e8dce4dSJason Molenda 176b9c1b51eSKate Stone uint32_t GetNumPendingItems() { 1775e8dce4dSJason Molenda uint32_t result = 0; 1785e8dce4dSJason Molenda 179fe95dc95SJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 180a6682a41SJonas Devlieghere if (!m_pending_items_fetched && queue_sp) { 181fe95dc95SJason Molenda result = queue_sp->GetNumPendingWorkItems(); 182b9c1b51eSKate Stone } else { 1832fd83355SJason Molenda result = m_pending_items.size(); 1845e8dce4dSJason Molenda } 1855e8dce4dSJason Molenda return result; 1865e8dce4dSJason Molenda } 1875e8dce4dSJason Molenda 188b9c1b51eSKate Stone lldb::SBQueueItem GetPendingItemAtIndex(uint32_t idx) { 1895e8dce4dSJason Molenda SBQueueItem result; 1905e8dce4dSJason Molenda FetchItems(); 191b9c1b51eSKate Stone if (m_pending_items_fetched && idx < m_pending_items.size()) { 1922fd83355SJason Molenda result.SetQueueItem(m_pending_items[idx]); 1935e8dce4dSJason Molenda } 1945e8dce4dSJason Molenda return result; 1955e8dce4dSJason Molenda } 1965e8dce4dSJason Molenda 197b9c1b51eSKate Stone uint32_t GetNumRunningItems() { 198fe95dc95SJason Molenda uint32_t result = 0; 199fe95dc95SJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 200fe95dc95SJason Molenda if (queue_sp) 201fe95dc95SJason Molenda result = queue_sp->GetNumRunningWorkItems(); 202fe95dc95SJason Molenda return result; 203fe95dc95SJason Molenda } 204fe95dc95SJason Molenda 205b9c1b51eSKate Stone lldb::SBProcess GetProcess() { 2065e8dce4dSJason Molenda SBProcess result; 2075e8dce4dSJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 208b9c1b51eSKate Stone if (queue_sp) { 2095e8dce4dSJason Molenda result.SetSP(queue_sp->GetProcess()); 2105e8dce4dSJason Molenda } 2115e8dce4dSJason Molenda return result; 2125e8dce4dSJason Molenda } 213c8064ac6SJason Molenda 214b9c1b51eSKate Stone lldb::QueueKind GetKind() { 215aac16e0fSJason Molenda lldb::QueueKind kind = eQueueKindUnknown; 216aac16e0fSJason Molenda QueueSP queue_sp = m_queue_wp.lock(); 217aac16e0fSJason Molenda if (queue_sp) 218aac16e0fSJason Molenda kind = queue_sp->GetKind(); 219aac16e0fSJason Molenda 220aac16e0fSJason Molenda return kind; 221aac16e0fSJason Molenda } 222aac16e0fSJason Molenda 223c8064ac6SJason Molenda private: 224c8064ac6SJason Molenda lldb::QueueWP m_queue_wp; 225b9c1b51eSKate Stone std::vector<lldb::ThreadWP> 226b9c1b51eSKate Stone m_threads; // threads currently executing this queue's items 227b9c1b51eSKate Stone bool 228b9c1b51eSKate Stone m_thread_list_fetched; // have we tried to fetch the threads list already? 2292fd83355SJason Molenda std::vector<lldb::QueueItemSP> m_pending_items; // items currently enqueued 2302fd83355SJason Molenda bool m_pending_items_fetched; // have we tried to fetch the item list already? 231c8064ac6SJason Molenda }; 232c8064ac6SJason Molenda } 233c8064ac6SJason Molenda 234b9c1b51eSKate Stone SBQueue::SBQueue() : m_opaque_sp(new QueueImpl()) {} 235c8064ac6SJason Molenda 236b9c1b51eSKate Stone SBQueue::SBQueue(const QueueSP &queue_sp) 237b9c1b51eSKate Stone : m_opaque_sp(new QueueImpl(queue_sp)) {} 238c8064ac6SJason Molenda 239b9c1b51eSKate Stone SBQueue::SBQueue(const SBQueue &rhs) { 240c8064ac6SJason Molenda if (&rhs == this) 241c8064ac6SJason Molenda return; 242c8064ac6SJason Molenda 243c8064ac6SJason Molenda m_opaque_sp = rhs.m_opaque_sp; 244c8064ac6SJason Molenda } 245c8064ac6SJason Molenda 246b9c1b51eSKate Stone const lldb::SBQueue &SBQueue::operator=(const lldb::SBQueue &rhs) { 247c8064ac6SJason Molenda m_opaque_sp = rhs.m_opaque_sp; 248c8064ac6SJason Molenda return *this; 249c8064ac6SJason Molenda } 250c8064ac6SJason Molenda 251b9c1b51eSKate Stone SBQueue::~SBQueue() {} 252c8064ac6SJason Molenda 253b9c1b51eSKate Stone bool SBQueue::IsValid() const { 254ac605f4aSJason Molenda bool is_valid = m_opaque_sp->IsValid(); 255ac605f4aSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 256ac605f4aSJason Molenda if (log) 257b9c1b51eSKate Stone log->Printf("SBQueue(0x%" PRIx64 ")::IsValid() == %s", 258b9c1b51eSKate Stone m_opaque_sp->GetQueueID(), is_valid ? "true" : "false"); 259ac605f4aSJason Molenda return is_valid; 260c8064ac6SJason Molenda } 261c8064ac6SJason Molenda 262b9c1b51eSKate Stone void SBQueue::Clear() { 263ac605f4aSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 264ac605f4aSJason Molenda if (log) 265ac605f4aSJason Molenda log->Printf("SBQueue(0x%" PRIx64 ")::Clear()", m_opaque_sp->GetQueueID()); 266c8064ac6SJason Molenda m_opaque_sp->Clear(); 267c8064ac6SJason Molenda } 268c8064ac6SJason Molenda 269b9c1b51eSKate Stone void SBQueue::SetQueue(const QueueSP &queue_sp) { 270c8064ac6SJason Molenda m_opaque_sp->SetQueue(queue_sp); 271c8064ac6SJason Molenda } 272c8064ac6SJason Molenda 273b9c1b51eSKate Stone lldb::queue_id_t SBQueue::GetQueueID() const { 274ac605f4aSJason Molenda lldb::queue_id_t qid = m_opaque_sp->GetQueueID(); 275ac605f4aSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 276ac605f4aSJason Molenda if (log) 277b9c1b51eSKate Stone log->Printf("SBQueue(0x%" PRIx64 ")::GetQueueID() == 0x%" PRIx64, 278b9c1b51eSKate Stone m_opaque_sp->GetQueueID(), (uint64_t)qid); 279ac605f4aSJason Molenda return qid; 280c8064ac6SJason Molenda } 281c8064ac6SJason Molenda 282b9c1b51eSKate Stone uint32_t SBQueue::GetIndexID() const { 283ac605f4aSJason Molenda uint32_t index_id = m_opaque_sp->GetIndexID(); 284ac605f4aSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 285ac605f4aSJason Molenda if (log) 286b9c1b51eSKate Stone log->Printf("SBQueue(0x%" PRIx64 ")::GetIndexID() == 0x%" PRIx32, 287b9c1b51eSKate Stone m_opaque_sp->GetQueueID(), index_id); 288ac605f4aSJason Molenda return index_id; 289c8064ac6SJason Molenda } 290c8064ac6SJason Molenda 291b9c1b51eSKate Stone const char *SBQueue::GetName() const { 292ac605f4aSJason Molenda const char *name = m_opaque_sp->GetName(); 293ac605f4aSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 294ac605f4aSJason Molenda if (log) 295b9c1b51eSKate Stone log->Printf("SBQueue(0x%" PRIx64 ")::GetName() == %s", 296b9c1b51eSKate Stone m_opaque_sp->GetQueueID(), name ? name : ""); 297ac605f4aSJason Molenda return name; 298c8064ac6SJason Molenda } 299c8064ac6SJason Molenda 300b9c1b51eSKate Stone uint32_t SBQueue::GetNumThreads() { 301ac605f4aSJason Molenda uint32_t numthreads = m_opaque_sp->GetNumThreads(); 302ac605f4aSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 303ac605f4aSJason Molenda if (log) 304b9c1b51eSKate Stone log->Printf("SBQueue(0x%" PRIx64 ")::GetNumThreads() == %d", 305b9c1b51eSKate Stone m_opaque_sp->GetQueueID(), numthreads); 306ac605f4aSJason Molenda return numthreads; 307c8064ac6SJason Molenda } 308c8064ac6SJason Molenda 309b9c1b51eSKate Stone SBThread SBQueue::GetThreadAtIndex(uint32_t idx) { 310ac605f4aSJason Molenda SBThread th = m_opaque_sp->GetThreadAtIndex(idx); 311ac605f4aSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 312ac605f4aSJason Molenda if (log) 313b9c1b51eSKate Stone log->Printf("SBQueue(0x%" PRIx64 ")::GetThreadAtIndex(%d)", 314b9c1b51eSKate Stone m_opaque_sp->GetQueueID(), idx); 315ac605f4aSJason Molenda return th; 316c8064ac6SJason Molenda } 317c8064ac6SJason Molenda 318b9c1b51eSKate Stone uint32_t SBQueue::GetNumPendingItems() { 319ac605f4aSJason Molenda uint32_t pending_items = m_opaque_sp->GetNumPendingItems(); 320ac605f4aSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 321ac605f4aSJason Molenda if (log) 322b9c1b51eSKate Stone log->Printf("SBQueue(0x%" PRIx64 ")::GetNumPendingItems() == %d", 323b9c1b51eSKate Stone m_opaque_sp->GetQueueID(), pending_items); 324ac605f4aSJason Molenda return pending_items; 325c8064ac6SJason Molenda } 326c8064ac6SJason Molenda 327b9c1b51eSKate Stone SBQueueItem SBQueue::GetPendingItemAtIndex(uint32_t idx) { 328ac605f4aSJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 329ac605f4aSJason Molenda if (log) 330b9c1b51eSKate Stone log->Printf("SBQueue(0x%" PRIx64 ")::GetPendingItemAtIndex(%d)", 331b9c1b51eSKate Stone m_opaque_sp->GetQueueID(), idx); 3322fd83355SJason Molenda return m_opaque_sp->GetPendingItemAtIndex(idx); 333c8064ac6SJason Molenda } 334c8064ac6SJason Molenda 335b9c1b51eSKate Stone uint32_t SBQueue::GetNumRunningItems() { 336fe95dc95SJason Molenda uint32_t running_items = m_opaque_sp->GetNumRunningItems(); 337fe95dc95SJason Molenda Log *log(lldb_private::GetLogIfAllCategoriesSet(LIBLLDB_LOG_API)); 338fe95dc95SJason Molenda if (log) 339b9c1b51eSKate Stone log->Printf("SBQueue(0x%" PRIx64 ")::GetNumRunningItems() == %d", 340b9c1b51eSKate Stone m_opaque_sp->GetQueueID(), running_items); 341fe95dc95SJason Molenda return running_items; 342fe95dc95SJason Molenda } 343fe95dc95SJason Molenda 344b9c1b51eSKate Stone SBProcess SBQueue::GetProcess() { return m_opaque_sp->GetProcess(); } 345aac16e0fSJason Molenda 346b9c1b51eSKate Stone lldb::QueueKind SBQueue::GetKind() { return m_opaque_sp->GetKind(); } 347