| 1 | //===-- Queue.h ------------------------------------------------*- C++ -*-===// |
| 2 | // |
| 3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| 4 | // See https://llvm.org/LICENSE.txt for license information. |
| 5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| 6 | // |
| 7 | //===----------------------------------------------------------------------===// |
| 8 | |
| 9 | #ifndef LLDB_TARGET_QUEUE_H |
| 10 | #define LLDB_TARGET_QUEUE_H |
| 11 | |
| 12 | #include <string> |
| 13 | #include <vector> |
| 14 | |
| 15 | #include "lldb/Target/QueueItem.h" |
| 16 | #include "lldb/lldb-enumerations.h" |
| 17 | #include "lldb/lldb-forward.h" |
| 18 | #include "lldb/lldb-private.h" |
| 19 | |
| 20 | namespace lldb_private { |
| 21 | |
| 22 | // Queue: |
| 23 | // This class represents a libdispatch aka Grand Central Dispatch queue in the |
| 24 | // process. |
| 25 | // |
| 26 | // A program using libdispatch will create queues, put work items |
| 27 | // (functions, blocks) on the queues. The system will create / reassign |
| 28 | // pthreads to execute the work items for the queues. A serial queue will be |
| 29 | // associated with a single thread (or possibly no thread, if it is not doing |
| 30 | // any work). A concurrent queue may be associated with multiple threads. |
| 31 | |
| 32 | class Queue : public std::enable_shared_from_this<Queue> { |
| 33 | public: |
| 34 | Queue(lldb::ProcessSP process_sp, lldb::queue_id_t queue_id, |
| 35 | const char *queue_name); |
| 36 | |
| 37 | ~Queue(); |
| 38 | |
| 39 | /// Get the QueueID for this Queue |
| 40 | /// |
| 41 | /// A 64-bit ID number that uniquely identifies a queue at this particular |
| 42 | /// stop_id. Currently the libdispatch serialnum is used for the QueueID; |
| 43 | /// it is a number that starts at 1 for each process and increments with |
| 44 | /// each queue. A serialnum is not reused for a different queue in the |
| 45 | /// lifetime of that process execution. |
| 46 | /// |
| 47 | /// \return |
| 48 | /// The QueueID for this Queue. |
| 49 | lldb::queue_id_t GetID(); |
| 50 | |
| 51 | /// Get the name of this Queue |
| 52 | /// |
| 53 | /// \return |
| 54 | /// The name of the queue, if one is available. |
| 55 | /// A NULL pointer is returned if none is available. |
| 56 | const char *GetName(); |
| 57 | |
| 58 | /// Get the IndexID for this Queue |
| 59 | /// |
| 60 | /// This is currently the same as GetID(). If it changes in the future, |
| 61 | /// it will be a small integer value (starting with 1) assigned to |
| 62 | /// each queue that is seen during a Process lifetime. |
| 63 | /// |
| 64 | /// Both the GetID and GetIndexID are being retained for Queues to |
| 65 | /// maintain similar API to the Thread class, and allow for the |
| 66 | /// possibility of GetID changing to a different source in the future. |
| 67 | /// |
| 68 | /// \return |
| 69 | /// The IndexID for this queue. |
| 70 | uint32_t GetIndexID(); |
| 71 | |
| 72 | /// Return the threads currently associated with this queue |
| 73 | /// |
| 74 | /// Zero, one, or many threads may be executing code for a queue at |
| 75 | /// a given point in time. This call returns the list of threads |
| 76 | /// that are currently executing work for this queue. |
| 77 | /// |
| 78 | /// \return |
| 79 | /// The threads currently performing work for this queue |
| 80 | std::vector<lldb::ThreadSP> GetThreads(); |
| 81 | |
| 82 | /// Return the items that are currently enqueued |
| 83 | /// |
| 84 | /// "Enqueued" means that the item has been added to the queue to |
| 85 | /// be done, but has not yet been done. When the item is going to |
| 86 | /// be processed it is "dequeued". |
| 87 | /// |
| 88 | /// \return |
| 89 | /// The vector of enqueued items for this queue |
| 90 | const std::vector<lldb::QueueItemSP> &GetPendingItems(); |
| 91 | |
| 92 | lldb::ProcessSP GetProcess() const { return m_process_wp.lock(); } |
| 93 | |
| 94 | /// Get the number of work items that this queue is currently running |
| 95 | /// |
| 96 | /// \return |
| 97 | /// The number of work items currently executing. For a serial |
| 98 | /// queue, this will be 0 or 1. For a concurrent queue, this |
| 99 | /// may be any number. |
| 100 | uint32_t GetNumRunningWorkItems() const; |
| 101 | |
| 102 | /// Get the number of work items enqueued on this queue |
| 103 | /// |
| 104 | /// \return |
| 105 | /// The number of work items currently enqueued, waiting to |
| 106 | /// execute. |
| 107 | uint32_t GetNumPendingWorkItems() const; |
| 108 | |
| 109 | /// Get the dispatch_queue_t structure address for this Queue |
| 110 | /// |
| 111 | /// Get the address in the inferior process' memory of this Queue's |
| 112 | /// dispatch_queue_t structure. |
| 113 | /// |
| 114 | /// \return |
| 115 | /// The address of the dispatch_queue_t structure, if known. |
| 116 | /// LLDB_INVALID_ADDRESS will be returned if it is unavailable. |
| 117 | lldb::addr_t GetLibdispatchQueueAddress() const; |
| 118 | |
| 119 | void SetNumRunningWorkItems(uint32_t count); |
| 120 | |
| 121 | void SetNumPendingWorkItems(uint32_t count); |
| 122 | |
| 123 | void SetLibdispatchQueueAddress(lldb::addr_t dispatch_queue_t_addr); |
| 124 | |
| 125 | void PushPendingQueueItem(lldb::QueueItemSP item) { |
| 126 | m_pending_items.push_back(x: item); |
| 127 | } |
| 128 | |
| 129 | /// Return the kind (serial, concurrent) of this queue. |
| 130 | lldb::QueueKind GetKind(); |
| 131 | |
| 132 | void SetKind(lldb::QueueKind kind); |
| 133 | |
| 134 | private: |
| 135 | // For Queue only |
| 136 | |
| 137 | lldb::ProcessWP m_process_wp; |
| 138 | lldb::queue_id_t m_queue_id; |
| 139 | std::string m_queue_name; |
| 140 | uint32_t m_running_work_items_count; |
| 141 | uint32_t m_pending_work_items_count; |
| 142 | std::vector<lldb::QueueItemSP> m_pending_items; |
| 143 | lldb::addr_t m_dispatch_queue_t_addr; // address of libdispatch |
| 144 | // dispatch_queue_t for this Queue |
| 145 | lldb::QueueKind m_kind; |
| 146 | |
| 147 | Queue(const Queue &) = delete; |
| 148 | const Queue &operator=(const Queue &) = delete; |
| 149 | }; |
| 150 | |
| 151 | } // namespace lldb_private |
| 152 | |
| 153 | #endif // LLDB_TARGET_QUEUE_H |
| 154 | |