1262182Semaste//===-- QueueItem.h ---------------------------------------------*- C++ -*-===//
2262182Semaste//
3353358Sdim// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim// See https://llvm.org/LICENSE.txt for license information.
5353358Sdim// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6262182Semaste//
7262182Semaste//===----------------------------------------------------------------------===//
8262182Semaste
9262182Semaste#ifndef liblldb_QueueItem_h_
10262182Semaste#define liblldb_QueueItem_h_
11262182Semaste
12296417Sdim#include <memory>
13296417Sdim#include <string>
14262182Semaste#include <vector>
15262182Semaste
16262182Semaste#include "lldb/lldb-enumerations.h"
17276479Sdim#include "lldb/lldb-forward.h"
18314564Sdim#include "lldb/lldb-private.h"
19262182Semaste
20262182Semaste#include "lldb/Core/Address.h"
21321369Sdim#include "lldb/Utility/ConstString.h"
22262182Semaste
23262182Semastenamespace lldb_private {
24262182Semaste
25262182Semaste// QueueItem:
26341825Sdim// This class represents a work item enqueued on a libdispatch aka Grand
27341825Sdim// Central Dispatch (GCD) queue.  Most often, this will be a function or block.
28341825Sdim// "enqueued" here means that the work item has been added to a queue but it
29341825Sdim// has not yet started executing.  When it is "dequeued", execution of the item
30341825Sdim// begins.
31262182Semaste
32314564Sdimclass QueueItem : public std::enable_shared_from_this<QueueItem> {
33262182Semastepublic:
34314564Sdim  QueueItem(lldb::QueueSP queue_sp, lldb::ProcessSP process_sp,
35314564Sdim            lldb::addr_t item_ref, lldb_private::Address address);
36262182Semaste
37314564Sdim  ~QueueItem();
38262182Semaste
39314564Sdim  /// Get the kind of work item this is
40314564Sdim  ///
41353358Sdim  /// \return
42314564Sdim  ///     The type of work item that this QueueItem object
43314564Sdim  ///     represents.  eQueueItemKindUnknown may be returned.
44314564Sdim  lldb::QueueItemKind GetKind();
45262182Semaste
46314564Sdim  /// Set the type of work item this is
47314564Sdim  ///
48353358Sdim  /// \param [in] item_kind
49314564Sdim  ///     Set the kind of this work item object.
50314564Sdim  void SetKind(lldb::QueueItemKind item_kind);
51262182Semaste
52314564Sdim  /// Get the code address that will be executed when this work item
53314564Sdim  /// is executed.
54314564Sdim  ///
55353358Sdim  /// \return
56314564Sdim  ///     The address that will be invoked when this work item is
57314564Sdim  ///     executed.  Not all types of QueueItems will have an
58314564Sdim  ///     address associated with them; check that the returned
59314564Sdim  ///     Address is valid, or check that the WorkItemKind is a
60314564Sdim  ///     kind that involves an address, such as eQueueItemKindFunction
61314564Sdim  ///     or eQueueItemKindBlock.
62314564Sdim  lldb_private::Address &GetAddress();
63262182Semaste
64314564Sdim  /// Set the work item address for this object
65314564Sdim  ///
66353358Sdim  /// \param [in] addr
67314564Sdim  ///     The address that will be invoked when this work item
68314564Sdim  ///     is executed.
69314564Sdim  void SetAddress(lldb_private::Address addr);
70262182Semaste
71314564Sdim  /// Check if this QueueItem object is valid
72314564Sdim  ///
73314564Sdim  /// If the weak pointer to the parent Queue cannot be revivified,
74314564Sdim  /// it is invalid.
75314564Sdim  ///
76353358Sdim  /// \return
77314564Sdim  ///     True if this object is valid.
78314564Sdim  bool IsValid() { return m_queue_wp.lock() != nullptr; }
79262182Semaste
80314564Sdim  /// Get an extended backtrace thread for this queue item, if available
81314564Sdim  ///
82314564Sdim  /// If the backtrace/thread information was collected when this item
83314564Sdim  /// was enqueued, this call will provide it.
84314564Sdim  ///
85353358Sdim  /// \param [in] type
86314564Sdim  ///     The type of extended backtrace being requested, e.g. "libdispatch"
87314564Sdim  ///     or "pthread".
88314564Sdim  ///
89353358Sdim  /// \return
90314564Sdim  ///     A thread shared pointer which will have a reference to an extended
91314564Sdim  ///     thread if one was available.
92314564Sdim  lldb::ThreadSP GetExtendedBacktraceThread(ConstString type);
93262182Semaste
94314564Sdim  void SetItemThatEnqueuedThis(lldb::addr_t address_of_item) {
95314564Sdim    m_item_that_enqueued_this_ref = address_of_item;
96314564Sdim  }
97262182Semaste
98314564Sdim  lldb::addr_t GetItemThatEnqueuedThis();
99262182Semaste
100314564Sdim  void SetEnqueueingThreadID(lldb::tid_t tid) { m_enqueueing_thread_id = tid; }
101262182Semaste
102314564Sdim  lldb::tid_t GetEnqueueingThreadID();
103262182Semaste
104314564Sdim  void SetEnqueueingQueueID(lldb::queue_id_t qid) {
105314564Sdim    m_enqueueing_queue_id = qid;
106314564Sdim  }
107262182Semaste
108314564Sdim  lldb::queue_id_t GetEnqueueingQueueID();
109262182Semaste
110314564Sdim  void SetTargetQueueID(lldb::queue_id_t qid) { m_target_queue_id = qid; }
111262182Semaste
112314564Sdim  void SetStopID(uint32_t stop_id) { m_stop_id = stop_id; }
113262182Semaste
114314564Sdim  uint32_t GetStopID();
115262182Semaste
116314564Sdim  void SetEnqueueingBacktrace(std::vector<lldb::addr_t> backtrace) {
117314564Sdim    m_backtrace = backtrace;
118314564Sdim  }
119262182Semaste
120314564Sdim  std::vector<lldb::addr_t> &GetEnqueueingBacktrace();
121262182Semaste
122314564Sdim  void SetThreadLabel(std::string thread_name) { m_thread_label = thread_name; }
123262182Semaste
124314564Sdim  std::string GetThreadLabel();
125262182Semaste
126314564Sdim  void SetQueueLabel(std::string queue_name) { m_queue_label = queue_name; }
127262182Semaste
128314564Sdim  std::string GetQueueLabel();
129262182Semaste
130314564Sdim  void SetTargetQueueLabel(std::string queue_name) {
131314564Sdim    m_target_queue_label = queue_name;
132314564Sdim  }
133262182Semaste
134314564Sdim  lldb::ProcessSP GetProcessSP();
135276479Sdim
136262182Semasteprotected:
137314564Sdim  void FetchEntireItem();
138276479Sdim
139314564Sdim  lldb::QueueWP m_queue_wp;
140314564Sdim  lldb::ProcessWP m_process_wp;
141276479Sdim
142314564Sdim  lldb::addr_t m_item_ref; // the token we can be used to fetch more information
143314564Sdim                           // about this queue item
144314564Sdim  lldb_private::Address m_address;
145314564Sdim  bool m_have_fetched_entire_item;
146262182Semaste
147314564Sdim  lldb::QueueItemKind m_kind;
148314564Sdim  lldb::addr_t m_item_that_enqueued_this_ref; // a handle that we can pass into
149314564Sdim                                              // libBacktraceRecording
150314564Sdim  // to get the QueueItem that enqueued this item
151314564Sdim  lldb::tid_t m_enqueueing_thread_id; // thread that enqueued this item
152314564Sdim  lldb::queue_id_t
153314564Sdim      m_enqueueing_queue_id; // Queue that enqueued this item, if it was a queue
154314564Sdim  lldb::queue_id_t m_target_queue_id;
155314564Sdim  uint32_t m_stop_id; // indicates when this backtrace was recorded in time
156314564Sdim  std::vector<lldb::addr_t> m_backtrace;
157314564Sdim  std::string m_thread_label;
158314564Sdim  std::string m_queue_label;
159314564Sdim  std::string m_target_queue_label;
160262182Semaste
161262182Semasteprivate:
162314564Sdim  DISALLOW_COPY_AND_ASSIGN(QueueItem);
163262182Semaste};
164262182Semaste
165262182Semaste} // namespace lldb_private
166262182Semaste
167296417Sdim#endif // liblldb_QueueItem_h_
168