xref: /freebsd/contrib/llvm-project/lldb/include/lldb/Target/ThreadList.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1 //===-- ThreadList.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_THREADLIST_H
10 #define LLDB_TARGET_THREADLIST_H
11 
12 #include <mutex>
13 #include <vector>
14 
15 #include "lldb/Target/Thread.h"
16 #include "lldb/Target/ThreadCollection.h"
17 #include "lldb/Utility/Iterable.h"
18 #include "lldb/Utility/UserID.h"
19 #include "lldb/lldb-private.h"
20 
21 namespace lldb_private {
22 
23 // This is a thread list with lots of functionality for use only by the process
24 // for which this is the thread list.  A generic container class with iterator
25 // functionality is ThreadCollection.
26 class ThreadList : public ThreadCollection {
27   friend class Process;
28 
29 public:
30   ThreadList(Process &process);
31 
32   ThreadList(const ThreadList &rhs);
33 
34   ~ThreadList() override;
35 
36   /// Precondition: both thread lists must be belong to the same process.
37   const ThreadList &operator=(const ThreadList &rhs);
38 
39   uint32_t GetSize(bool can_update = true);
40 
41   // Return the selected thread if there is one.  Otherwise, return the thread
42   // selected at index 0.
43   lldb::ThreadSP GetSelectedThread();
44 
45   // Manage the thread to use for running expressions.  This is usually the
46   // Selected thread, but sometimes (e.g. when evaluating breakpoint conditions
47   // & stop hooks) it isn't.
48   class ExpressionExecutionThreadPusher {
49   public:
ExpressionExecutionThreadPusher(ThreadList & thread_list,lldb::tid_t tid)50     ExpressionExecutionThreadPusher(ThreadList &thread_list, lldb::tid_t tid)
51         : m_thread_list(&thread_list), m_tid(tid) {
52       m_thread_list->PushExpressionExecutionThread(m_tid);
53     }
54 
55     ExpressionExecutionThreadPusher(lldb::ThreadSP thread_sp);
56 
~ExpressionExecutionThreadPusher()57     ~ExpressionExecutionThreadPusher() {
58       if (m_thread_list && m_tid != LLDB_INVALID_THREAD_ID)
59         m_thread_list->PopExpressionExecutionThread(m_tid);
60     }
61 
62   private:
63     ThreadList *m_thread_list;
64     lldb::tid_t m_tid;
65   };
66 
67   lldb::ThreadSP GetExpressionExecutionThread();
68 
69 protected:
70   void PushExpressionExecutionThread(lldb::tid_t tid);
71 
72   void PopExpressionExecutionThread(lldb::tid_t tid);
73 
74 public:
75   bool SetSelectedThreadByID(lldb::tid_t tid, bool notify = false);
76 
77   bool SetSelectedThreadByIndexID(uint32_t index_id, bool notify = false);
78 
79   void Clear();
80 
81   void Flush();
82 
83   void Destroy();
84 
85   // Note that "idx" is not the same as the "thread_index". It is a zero based
86   // index to accessing the current threads, whereas "thread_index" is a unique
87   // index assigned
88   lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update = true);
89 
90   lldb::ThreadSP FindThreadByID(lldb::tid_t tid, bool can_update = true);
91 
92   lldb::ThreadSP FindThreadByProtocolID(lldb::tid_t tid,
93                                         bool can_update = true);
94 
95   lldb::ThreadSP RemoveThreadByID(lldb::tid_t tid, bool can_update = true);
96 
97   lldb::ThreadSP RemoveThreadByProtocolID(lldb::tid_t tid,
98                                           bool can_update = true);
99 
100   lldb::ThreadSP FindThreadByIndexID(uint32_t index_id, bool can_update = true);
101 
102   lldb::ThreadSP GetThreadSPForThreadPtr(Thread *thread_ptr);
103 
104   lldb::ThreadSP GetBackingThread(const lldb::ThreadSP &real_thread);
105 
106   bool ShouldStop(Event *event_ptr);
107 
108   Vote ShouldReportStop(Event *event_ptr);
109 
110   Vote ShouldReportRun(Event *event_ptr);
111 
112   void RefreshStateAfterStop();
113 
114   /// The thread list asks tells all the threads it is about to resume.
115   /// If a thread can "resume" without having to resume the target, it
116   /// will return false for WillResume, and then the process will not be
117   /// restarted.
118   ///
119   /// \return
120   ///    \b true instructs the process to resume normally,
121   ///    \b false means start & stopped events will be generated, but
122   ///    the process will not actually run.  The thread must then return
123   ///    the correct StopInfo when asked.
124   ///
125   bool WillResume();
126 
127   void DidResume();
128 
129   void DidStop();
130 
131   void DiscardThreadPlans();
132 
133   uint32_t GetStopID() const;
134 
135   void SetStopID(uint32_t stop_id);
136 
137   std::recursive_mutex &GetMutex() const override;
138 
139   /// Precondition: both thread lists must be belong to the same process.
140   void Update(ThreadList &rhs);
141 
142 protected:
143   void SetShouldReportStop(Vote vote);
144 
145   void NotifySelectedThreadChanged(lldb::tid_t tid);
146 
147   // Classes that inherit from Process can see and modify these
148   Process &m_process; ///< The process that manages this thread list.
149   uint32_t
150       m_stop_id; ///< The process stop ID that this thread list is valid for.
151   lldb::tid_t
152       m_selected_tid; ///< For targets that need the notion of a current thread.
153   std::vector<lldb::tid_t> m_expression_tid_stack;
154 
155 private:
156   ThreadList() = delete;
157 };
158 
159 } // namespace lldb_private
160 
161 #endif // LLDB_TARGET_THREADLIST_H
162