10b57cec5SDimitry Andric //===-- QueueItem.h ---------------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric 9*5ffd83dbSDimitry Andric #ifndef LLDB_TARGET_QUEUEITEM_H 10*5ffd83dbSDimitry Andric #define LLDB_TARGET_QUEUEITEM_H 110b57cec5SDimitry Andric 120b57cec5SDimitry Andric #include <memory> 130b57cec5SDimitry Andric #include <string> 140b57cec5SDimitry Andric #include <vector> 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "lldb/lldb-enumerations.h" 170b57cec5SDimitry Andric #include "lldb/lldb-forward.h" 180b57cec5SDimitry Andric #include "lldb/lldb-private.h" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric #include "lldb/Core/Address.h" 210b57cec5SDimitry Andric #include "lldb/Utility/ConstString.h" 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric namespace lldb_private { 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric // QueueItem: 260b57cec5SDimitry Andric // This class represents a work item enqueued on a libdispatch aka Grand 270b57cec5SDimitry Andric // Central Dispatch (GCD) queue. Most often, this will be a function or block. 280b57cec5SDimitry Andric // "enqueued" here means that the work item has been added to a queue but it 290b57cec5SDimitry Andric // has not yet started executing. When it is "dequeued", execution of the item 300b57cec5SDimitry Andric // begins. 310b57cec5SDimitry Andric 320b57cec5SDimitry Andric class QueueItem : public std::enable_shared_from_this<QueueItem> { 330b57cec5SDimitry Andric public: 340b57cec5SDimitry Andric QueueItem(lldb::QueueSP queue_sp, lldb::ProcessSP process_sp, 350b57cec5SDimitry Andric lldb::addr_t item_ref, lldb_private::Address address); 360b57cec5SDimitry Andric 370b57cec5SDimitry Andric ~QueueItem(); 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric /// Get the kind of work item this is 400b57cec5SDimitry Andric /// 410b57cec5SDimitry Andric /// \return 420b57cec5SDimitry Andric /// The type of work item that this QueueItem object 430b57cec5SDimitry Andric /// represents. eQueueItemKindUnknown may be returned. 440b57cec5SDimitry Andric lldb::QueueItemKind GetKind(); 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric /// Set the type of work item this is 470b57cec5SDimitry Andric /// 480b57cec5SDimitry Andric /// \param [in] item_kind 490b57cec5SDimitry Andric /// Set the kind of this work item object. 500b57cec5SDimitry Andric void SetKind(lldb::QueueItemKind item_kind); 510b57cec5SDimitry Andric 520b57cec5SDimitry Andric /// Get the code address that will be executed when this work item 530b57cec5SDimitry Andric /// is executed. 540b57cec5SDimitry Andric /// 550b57cec5SDimitry Andric /// \return 560b57cec5SDimitry Andric /// The address that will be invoked when this work item is 570b57cec5SDimitry Andric /// executed. Not all types of QueueItems will have an 580b57cec5SDimitry Andric /// address associated with them; check that the returned 590b57cec5SDimitry Andric /// Address is valid, or check that the WorkItemKind is a 600b57cec5SDimitry Andric /// kind that involves an address, such as eQueueItemKindFunction 610b57cec5SDimitry Andric /// or eQueueItemKindBlock. 620b57cec5SDimitry Andric lldb_private::Address &GetAddress(); 630b57cec5SDimitry Andric 640b57cec5SDimitry Andric /// Set the work item address for this object 650b57cec5SDimitry Andric /// 660b57cec5SDimitry Andric /// \param [in] addr 670b57cec5SDimitry Andric /// The address that will be invoked when this work item 680b57cec5SDimitry Andric /// is executed. 690b57cec5SDimitry Andric void SetAddress(lldb_private::Address addr); 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric /// Check if this QueueItem object is valid 720b57cec5SDimitry Andric /// 730b57cec5SDimitry Andric /// If the weak pointer to the parent Queue cannot be revivified, 740b57cec5SDimitry Andric /// it is invalid. 750b57cec5SDimitry Andric /// 760b57cec5SDimitry Andric /// \return 770b57cec5SDimitry Andric /// True if this object is valid. IsValid()780b57cec5SDimitry Andric bool IsValid() { return m_queue_wp.lock() != nullptr; } 790b57cec5SDimitry Andric 800b57cec5SDimitry Andric /// Get an extended backtrace thread for this queue item, if available 810b57cec5SDimitry Andric /// 820b57cec5SDimitry Andric /// If the backtrace/thread information was collected when this item 830b57cec5SDimitry Andric /// was enqueued, this call will provide it. 840b57cec5SDimitry Andric /// 850b57cec5SDimitry Andric /// \param [in] type 860b57cec5SDimitry Andric /// The type of extended backtrace being requested, e.g. "libdispatch" 870b57cec5SDimitry Andric /// or "pthread". 880b57cec5SDimitry Andric /// 890b57cec5SDimitry Andric /// \return 900b57cec5SDimitry Andric /// A thread shared pointer which will have a reference to an extended 910b57cec5SDimitry Andric /// thread if one was available. 920b57cec5SDimitry Andric lldb::ThreadSP GetExtendedBacktraceThread(ConstString type); 930b57cec5SDimitry Andric SetItemThatEnqueuedThis(lldb::addr_t address_of_item)940b57cec5SDimitry Andric void SetItemThatEnqueuedThis(lldb::addr_t address_of_item) { 950b57cec5SDimitry Andric m_item_that_enqueued_this_ref = address_of_item; 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric 980b57cec5SDimitry Andric lldb::addr_t GetItemThatEnqueuedThis(); 990b57cec5SDimitry Andric SetEnqueueingThreadID(lldb::tid_t tid)1000b57cec5SDimitry Andric void SetEnqueueingThreadID(lldb::tid_t tid) { m_enqueueing_thread_id = tid; } 1010b57cec5SDimitry Andric 1020b57cec5SDimitry Andric lldb::tid_t GetEnqueueingThreadID(); 1030b57cec5SDimitry Andric SetEnqueueingQueueID(lldb::queue_id_t qid)1040b57cec5SDimitry Andric void SetEnqueueingQueueID(lldb::queue_id_t qid) { 1050b57cec5SDimitry Andric m_enqueueing_queue_id = qid; 1060b57cec5SDimitry Andric } 1070b57cec5SDimitry Andric 1080b57cec5SDimitry Andric lldb::queue_id_t GetEnqueueingQueueID(); 1090b57cec5SDimitry Andric SetTargetQueueID(lldb::queue_id_t qid)1100b57cec5SDimitry Andric void SetTargetQueueID(lldb::queue_id_t qid) { m_target_queue_id = qid; } 1110b57cec5SDimitry Andric SetStopID(uint32_t stop_id)1120b57cec5SDimitry Andric void SetStopID(uint32_t stop_id) { m_stop_id = stop_id; } 1130b57cec5SDimitry Andric 1140b57cec5SDimitry Andric uint32_t GetStopID(); 1150b57cec5SDimitry Andric SetEnqueueingBacktrace(std::vector<lldb::addr_t> backtrace)1160b57cec5SDimitry Andric void SetEnqueueingBacktrace(std::vector<lldb::addr_t> backtrace) { 1170b57cec5SDimitry Andric m_backtrace = backtrace; 1180b57cec5SDimitry Andric } 1190b57cec5SDimitry Andric 1200b57cec5SDimitry Andric std::vector<lldb::addr_t> &GetEnqueueingBacktrace(); 1210b57cec5SDimitry Andric SetThreadLabel(std::string thread_name)1220b57cec5SDimitry Andric void SetThreadLabel(std::string thread_name) { m_thread_label = thread_name; } 1230b57cec5SDimitry Andric 1240b57cec5SDimitry Andric std::string GetThreadLabel(); 1250b57cec5SDimitry Andric SetQueueLabel(std::string queue_name)1260b57cec5SDimitry Andric void SetQueueLabel(std::string queue_name) { m_queue_label = queue_name; } 1270b57cec5SDimitry Andric 1280b57cec5SDimitry Andric std::string GetQueueLabel(); 1290b57cec5SDimitry Andric SetTargetQueueLabel(std::string queue_name)1300b57cec5SDimitry Andric void SetTargetQueueLabel(std::string queue_name) { 1310b57cec5SDimitry Andric m_target_queue_label = queue_name; 1320b57cec5SDimitry Andric } 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric lldb::ProcessSP GetProcessSP(); 1350b57cec5SDimitry Andric 1360b57cec5SDimitry Andric protected: 1370b57cec5SDimitry Andric void FetchEntireItem(); 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric lldb::QueueWP m_queue_wp; 1400b57cec5SDimitry Andric lldb::ProcessWP m_process_wp; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric lldb::addr_t m_item_ref; // the token we can be used to fetch more information 1430b57cec5SDimitry Andric // about this queue item 1440b57cec5SDimitry Andric lldb_private::Address m_address; 1450b57cec5SDimitry Andric bool m_have_fetched_entire_item; 1460b57cec5SDimitry Andric 1470b57cec5SDimitry Andric lldb::QueueItemKind m_kind; 1480b57cec5SDimitry Andric lldb::addr_t m_item_that_enqueued_this_ref; // a handle that we can pass into 1490b57cec5SDimitry Andric // libBacktraceRecording 1500b57cec5SDimitry Andric // to get the QueueItem that enqueued this item 1510b57cec5SDimitry Andric lldb::tid_t m_enqueueing_thread_id; // thread that enqueued this item 1520b57cec5SDimitry Andric lldb::queue_id_t 1530b57cec5SDimitry Andric m_enqueueing_queue_id; // Queue that enqueued this item, if it was a queue 1540b57cec5SDimitry Andric lldb::queue_id_t m_target_queue_id; 1550b57cec5SDimitry Andric uint32_t m_stop_id; // indicates when this backtrace was recorded in time 1560b57cec5SDimitry Andric std::vector<lldb::addr_t> m_backtrace; 1570b57cec5SDimitry Andric std::string m_thread_label; 1580b57cec5SDimitry Andric std::string m_queue_label; 1590b57cec5SDimitry Andric std::string m_target_queue_label; 1600b57cec5SDimitry Andric 1610b57cec5SDimitry Andric private: 162*5ffd83dbSDimitry Andric QueueItem(const QueueItem &) = delete; 163*5ffd83dbSDimitry Andric const QueueItem &operator=(const QueueItem &) = delete; 1640b57cec5SDimitry Andric }; 1650b57cec5SDimitry Andric 1660b57cec5SDimitry Andric } // namespace lldb_private 1670b57cec5SDimitry Andric 168*5ffd83dbSDimitry Andric #endif // LLDB_TARGET_QUEUEITEM_H 169