xref: /src/contrib/llvm-project/lldb/source/Target/ThreadList.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1cfca06d7SDimitry Andric //===-- ThreadList.cpp ----------------------------------------------------===//
2f034231aSEd Maste //
35f29bb8aSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
45f29bb8aSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
55f29bb8aSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6f034231aSEd Maste //
7f034231aSEd Maste //===----------------------------------------------------------------------===//
8e81d9d49SDimitry Andric 
9344a3780SDimitry Andric #include <cstdlib>
10f034231aSEd Maste 
11f034231aSEd Maste #include <algorithm>
12f034231aSEd Maste 
13f034231aSEd Maste #include "lldb/Target/Process.h"
1414f1b3e8SDimitry Andric #include "lldb/Target/RegisterContext.h"
1514f1b3e8SDimitry Andric #include "lldb/Target/Thread.h"
1614f1b3e8SDimitry Andric #include "lldb/Target/ThreadList.h"
1714f1b3e8SDimitry Andric #include "lldb/Target/ThreadPlan.h"
18e81d9d49SDimitry Andric #include "lldb/Utility/LLDBAssert.h"
19145449b1SDimitry Andric #include "lldb/Utility/LLDBLog.h"
2074a628f7SDimitry Andric #include "lldb/Utility/Log.h"
2194994d37SDimitry Andric #include "lldb/Utility/State.h"
22f034231aSEd Maste 
23f034231aSEd Maste using namespace lldb;
24f034231aSEd Maste using namespace lldb_private;
25f034231aSEd Maste 
ThreadList(Process & process)26ac9a064cSDimitry Andric ThreadList::ThreadList(Process &process)
2714f1b3e8SDimitry Andric     : ThreadCollection(), m_process(process), m_stop_id(0),
2814f1b3e8SDimitry Andric       m_selected_tid(LLDB_INVALID_THREAD_ID) {}
29f034231aSEd Maste 
ThreadList(const ThreadList & rhs)3014f1b3e8SDimitry Andric ThreadList::ThreadList(const ThreadList &rhs)
3114f1b3e8SDimitry Andric     : ThreadCollection(), m_process(rhs.m_process), m_stop_id(rhs.m_stop_id),
3214f1b3e8SDimitry Andric       m_selected_tid() {
33f034231aSEd Maste   // Use the assignment operator since it uses the mutex
34f034231aSEd Maste   *this = rhs;
35f034231aSEd Maste }
36f034231aSEd Maste 
operator =(const ThreadList & rhs)3714f1b3e8SDimitry Andric const ThreadList &ThreadList::operator=(const ThreadList &rhs) {
3814f1b3e8SDimitry Andric   if (this != &rhs) {
39ac9a064cSDimitry Andric     // We only allow assignments between thread lists describing the same
40ac9a064cSDimitry Andric     // process. Same process implies same mutex, which means it's enough to lock
41ac9a064cSDimitry Andric     // just the current object.
42ac9a064cSDimitry Andric     assert(&m_process == &rhs.m_process);
43ac9a064cSDimitry Andric     assert(&GetMutex() == &rhs.GetMutex());
44ac9a064cSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(GetMutex());
45f3fbd1c0SDimitry Andric 
46f034231aSEd Maste     m_stop_id = rhs.m_stop_id;
47f034231aSEd Maste     m_threads = rhs.m_threads;
48f034231aSEd Maste     m_selected_tid = rhs.m_selected_tid;
49f034231aSEd Maste   }
50f034231aSEd Maste   return *this;
51f034231aSEd Maste }
52f034231aSEd Maste 
~ThreadList()5314f1b3e8SDimitry Andric ThreadList::~ThreadList() {
54f73363f1SDimitry Andric   // Clear the thread list. Clear will take the mutex lock which will ensure
55f73363f1SDimitry Andric   // that if anyone is using the list they won't get it removed while using it.
56f034231aSEd Maste   Clear();
57f034231aSEd Maste }
58f034231aSEd Maste 
GetExpressionExecutionThread()5914f1b3e8SDimitry Andric lldb::ThreadSP ThreadList::GetExpressionExecutionThread() {
60f3fbd1c0SDimitry Andric   if (m_expression_tid_stack.empty())
61f3fbd1c0SDimitry Andric     return GetSelectedThread();
62f3fbd1c0SDimitry Andric   ThreadSP expr_thread_sp = FindThreadByID(m_expression_tid_stack.back());
63f3fbd1c0SDimitry Andric   if (expr_thread_sp)
64f3fbd1c0SDimitry Andric     return expr_thread_sp;
65f3fbd1c0SDimitry Andric   else
66f3fbd1c0SDimitry Andric     return GetSelectedThread();
67f3fbd1c0SDimitry Andric }
68f3fbd1c0SDimitry Andric 
PushExpressionExecutionThread(lldb::tid_t tid)6914f1b3e8SDimitry Andric void ThreadList::PushExpressionExecutionThread(lldb::tid_t tid) {
70f3fbd1c0SDimitry Andric   m_expression_tid_stack.push_back(tid);
71f3fbd1c0SDimitry Andric }
72f3fbd1c0SDimitry Andric 
PopExpressionExecutionThread(lldb::tid_t tid)7314f1b3e8SDimitry Andric void ThreadList::PopExpressionExecutionThread(lldb::tid_t tid) {
74f3fbd1c0SDimitry Andric   assert(m_expression_tid_stack.back() == tid);
75f3fbd1c0SDimitry Andric   m_expression_tid_stack.pop_back();
76f3fbd1c0SDimitry Andric }
77f034231aSEd Maste 
GetStopID() const7814f1b3e8SDimitry Andric uint32_t ThreadList::GetStopID() const { return m_stop_id; }
79f034231aSEd Maste 
SetStopID(uint32_t stop_id)8014f1b3e8SDimitry Andric void ThreadList::SetStopID(uint32_t stop_id) { m_stop_id = stop_id; }
81f034231aSEd Maste 
GetSize(bool can_update)8214f1b3e8SDimitry Andric uint32_t ThreadList::GetSize(bool can_update) {
83f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
84f3fbd1c0SDimitry Andric 
85f034231aSEd Maste   if (can_update)
86ac9a064cSDimitry Andric     m_process.UpdateThreadListIfNeeded();
87f034231aSEd Maste   return m_threads.size();
88f034231aSEd Maste }
89f034231aSEd Maste 
GetThreadAtIndex(uint32_t idx,bool can_update)9014f1b3e8SDimitry Andric ThreadSP ThreadList::GetThreadAtIndex(uint32_t idx, bool can_update) {
91f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
92f3fbd1c0SDimitry Andric 
93f034231aSEd Maste   if (can_update)
94ac9a064cSDimitry Andric     m_process.UpdateThreadListIfNeeded();
95f034231aSEd Maste 
96f034231aSEd Maste   ThreadSP thread_sp;
97f034231aSEd Maste   if (idx < m_threads.size())
98f034231aSEd Maste     thread_sp = m_threads[idx];
99f034231aSEd Maste   return thread_sp;
100f034231aSEd Maste }
101f034231aSEd Maste 
FindThreadByID(lldb::tid_t tid,bool can_update)10214f1b3e8SDimitry Andric ThreadSP ThreadList::FindThreadByID(lldb::tid_t tid, bool can_update) {
103f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
104f034231aSEd Maste 
105f034231aSEd Maste   if (can_update)
106ac9a064cSDimitry Andric     m_process.UpdateThreadListIfNeeded();
107f034231aSEd Maste 
108f034231aSEd Maste   ThreadSP thread_sp;
109f034231aSEd Maste   uint32_t idx = 0;
110f034231aSEd Maste   const uint32_t num_threads = m_threads.size();
11114f1b3e8SDimitry Andric   for (idx = 0; idx < num_threads; ++idx) {
11214f1b3e8SDimitry Andric     if (m_threads[idx]->GetID() == tid) {
113f034231aSEd Maste       thread_sp = m_threads[idx];
114f034231aSEd Maste       break;
115f034231aSEd Maste     }
116f034231aSEd Maste   }
117f034231aSEd Maste   return thread_sp;
118f034231aSEd Maste }
119f034231aSEd Maste 
FindThreadByProtocolID(lldb::tid_t tid,bool can_update)12014f1b3e8SDimitry Andric ThreadSP ThreadList::FindThreadByProtocolID(lldb::tid_t tid, bool can_update) {
121f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
122f034231aSEd Maste 
123f034231aSEd Maste   if (can_update)
124ac9a064cSDimitry Andric     m_process.UpdateThreadListIfNeeded();
125f034231aSEd Maste 
126f034231aSEd Maste   ThreadSP thread_sp;
127f034231aSEd Maste   uint32_t idx = 0;
128f034231aSEd Maste   const uint32_t num_threads = m_threads.size();
12914f1b3e8SDimitry Andric   for (idx = 0; idx < num_threads; ++idx) {
13014f1b3e8SDimitry Andric     if (m_threads[idx]->GetProtocolID() == tid) {
131f034231aSEd Maste       thread_sp = m_threads[idx];
132f034231aSEd Maste       break;
133f034231aSEd Maste     }
134f034231aSEd Maste   }
135f034231aSEd Maste   return thread_sp;
136f034231aSEd Maste }
137f034231aSEd Maste 
RemoveThreadByID(lldb::tid_t tid,bool can_update)13814f1b3e8SDimitry Andric ThreadSP ThreadList::RemoveThreadByID(lldb::tid_t tid, bool can_update) {
139f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
140f034231aSEd Maste 
141f034231aSEd Maste   if (can_update)
142ac9a064cSDimitry Andric     m_process.UpdateThreadListIfNeeded();
143f034231aSEd Maste 
144f034231aSEd Maste   ThreadSP thread_sp;
145f034231aSEd Maste   uint32_t idx = 0;
146f034231aSEd Maste   const uint32_t num_threads = m_threads.size();
14714f1b3e8SDimitry Andric   for (idx = 0; idx < num_threads; ++idx) {
14814f1b3e8SDimitry Andric     if (m_threads[idx]->GetID() == tid) {
149f034231aSEd Maste       thread_sp = m_threads[idx];
150f034231aSEd Maste       m_threads.erase(m_threads.begin() + idx);
151f034231aSEd Maste       break;
152f034231aSEd Maste     }
153f034231aSEd Maste   }
154f034231aSEd Maste   return thread_sp;
155f034231aSEd Maste }
156f034231aSEd Maste 
RemoveThreadByProtocolID(lldb::tid_t tid,bool can_update)15714f1b3e8SDimitry Andric ThreadSP ThreadList::RemoveThreadByProtocolID(lldb::tid_t tid,
15814f1b3e8SDimitry Andric                                               bool can_update) {
159f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
160f034231aSEd Maste 
161f034231aSEd Maste   if (can_update)
162ac9a064cSDimitry Andric     m_process.UpdateThreadListIfNeeded();
163f034231aSEd Maste 
164f034231aSEd Maste   ThreadSP thread_sp;
165f034231aSEd Maste   uint32_t idx = 0;
166f034231aSEd Maste   const uint32_t num_threads = m_threads.size();
16714f1b3e8SDimitry Andric   for (idx = 0; idx < num_threads; ++idx) {
16814f1b3e8SDimitry Andric     if (m_threads[idx]->GetProtocolID() == tid) {
169f034231aSEd Maste       thread_sp = m_threads[idx];
170f034231aSEd Maste       m_threads.erase(m_threads.begin() + idx);
171f034231aSEd Maste       break;
172f034231aSEd Maste     }
173f034231aSEd Maste   }
174f034231aSEd Maste   return thread_sp;
175f034231aSEd Maste }
176f034231aSEd Maste 
GetThreadSPForThreadPtr(Thread * thread_ptr)17714f1b3e8SDimitry Andric ThreadSP ThreadList::GetThreadSPForThreadPtr(Thread *thread_ptr) {
178f034231aSEd Maste   ThreadSP thread_sp;
17914f1b3e8SDimitry Andric   if (thread_ptr) {
180f3fbd1c0SDimitry Andric     std::lock_guard<std::recursive_mutex> guard(GetMutex());
181f034231aSEd Maste 
182f034231aSEd Maste     uint32_t idx = 0;
183f034231aSEd Maste     const uint32_t num_threads = m_threads.size();
18414f1b3e8SDimitry Andric     for (idx = 0; idx < num_threads; ++idx) {
18514f1b3e8SDimitry Andric       if (m_threads[idx].get() == thread_ptr) {
186f034231aSEd Maste         thread_sp = m_threads[idx];
187f034231aSEd Maste         break;
188f034231aSEd Maste       }
189f034231aSEd Maste     }
190f034231aSEd Maste   }
191f034231aSEd Maste   return thread_sp;
192f034231aSEd Maste }
193f034231aSEd Maste 
GetBackingThread(const ThreadSP & real_thread)194f73363f1SDimitry Andric ThreadSP ThreadList::GetBackingThread(const ThreadSP &real_thread) {
195f73363f1SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
196f73363f1SDimitry Andric 
197f73363f1SDimitry Andric   ThreadSP thread_sp;
198f73363f1SDimitry Andric   const uint32_t num_threads = m_threads.size();
199f73363f1SDimitry Andric   for (uint32_t idx = 0; idx < num_threads; ++idx) {
200f73363f1SDimitry Andric     if (m_threads[idx]->GetBackingThread() == real_thread) {
201f73363f1SDimitry Andric       thread_sp = m_threads[idx];
202f73363f1SDimitry Andric       break;
203f73363f1SDimitry Andric     }
204f73363f1SDimitry Andric   }
205f73363f1SDimitry Andric   return thread_sp;
206f73363f1SDimitry Andric }
207f73363f1SDimitry Andric 
FindThreadByIndexID(uint32_t index_id,bool can_update)20814f1b3e8SDimitry Andric ThreadSP ThreadList::FindThreadByIndexID(uint32_t index_id, bool can_update) {
209f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
210f034231aSEd Maste 
211f034231aSEd Maste   if (can_update)
212ac9a064cSDimitry Andric     m_process.UpdateThreadListIfNeeded();
213f034231aSEd Maste 
214f034231aSEd Maste   ThreadSP thread_sp;
215f034231aSEd Maste   const uint32_t num_threads = m_threads.size();
21614f1b3e8SDimitry Andric   for (uint32_t idx = 0; idx < num_threads; ++idx) {
21714f1b3e8SDimitry Andric     if (m_threads[idx]->GetIndexID() == index_id) {
218f034231aSEd Maste       thread_sp = m_threads[idx];
219f034231aSEd Maste       break;
220f034231aSEd Maste     }
221f034231aSEd Maste   }
222f034231aSEd Maste   return thread_sp;
223f034231aSEd Maste }
224f034231aSEd Maste 
ShouldStop(Event * event_ptr)22514f1b3e8SDimitry Andric bool ThreadList::ShouldStop(Event *event_ptr) {
226f034231aSEd Maste   // Running events should never stop, obviously...
227f034231aSEd Maste 
228145449b1SDimitry Andric   Log *log = GetLog(LLDBLog::Step);
229f034231aSEd Maste 
230f73363f1SDimitry Andric   // The ShouldStop method of the threads can do a whole lot of work, figuring
231f73363f1SDimitry Andric   // out whether the thread plan conditions are met.  So we don't want to keep
232f73363f1SDimitry Andric   // the ThreadList locked the whole time we are doing this.
233f034231aSEd Maste   // FIXME: It is possible that running code could cause new threads
234f73363f1SDimitry Andric   // to be created.  If that happens, we will miss asking them whether they
235f73363f1SDimitry Andric   // should stop.  This is not a big deal since we haven't had a chance to hang
236f73363f1SDimitry Andric   // any interesting operations on those threads yet.
237f034231aSEd Maste 
238f034231aSEd Maste   collection threads_copy;
239f034231aSEd Maste   {
240f034231aSEd Maste     // Scope for locker
241f3fbd1c0SDimitry Andric     std::lock_guard<std::recursive_mutex> guard(GetMutex());
242f034231aSEd Maste 
243ac9a064cSDimitry Andric     m_process.UpdateThreadListIfNeeded();
24414f1b3e8SDimitry Andric     for (lldb::ThreadSP thread_sp : m_threads) {
24514f1b3e8SDimitry Andric       // This is an optimization...  If we didn't let a thread run in between
246f73363f1SDimitry Andric       // the previous stop and this one, we shouldn't have to consult it for
247e3b55780SDimitry Andric       // ShouldStop.  So just leave it off the list we are going to inspect.
248e3b55780SDimitry Andric       // If the thread didn't run but had work to do before declaring a public
249e3b55780SDimitry Andric       // stop, then also include it.
250e3b55780SDimitry Andric       // On Linux, if a thread-specific conditional breakpoint was hit, it won't
251f73363f1SDimitry Andric       // necessarily be the thread that hit the breakpoint itself that
252f73363f1SDimitry Andric       // evaluates the conditional expression, so the thread that hit the
253f73363f1SDimitry Andric       // breakpoint could still be asked to stop, even though it hasn't been
254f73363f1SDimitry Andric       // allowed to run since the previous stop.
25514f1b3e8SDimitry Andric       if (thread_sp->GetTemporaryResumeState() != eStateSuspended ||
256e3b55780SDimitry Andric           thread_sp->IsStillAtLastBreakpointHit()
257e3b55780SDimitry Andric           || thread_sp->ShouldRunBeforePublicStop())
258e81d9d49SDimitry Andric         threads_copy.push_back(thread_sp);
259e81d9d49SDimitry Andric     }
260e81d9d49SDimitry Andric 
26114f1b3e8SDimitry Andric     // It is possible the threads we were allowing to run all exited and then
262f73363f1SDimitry Andric     // maybe the user interrupted or something, then fall back on looking at
263f73363f1SDimitry Andric     // all threads:
264e81d9d49SDimitry Andric 
265e81d9d49SDimitry Andric     if (threads_copy.size() == 0)
266f034231aSEd Maste       threads_copy = m_threads;
267f034231aSEd Maste   }
268f034231aSEd Maste 
269f034231aSEd Maste   collection::iterator pos, end = threads_copy.end();
270f034231aSEd Maste 
27114f1b3e8SDimitry Andric   if (log) {
272f034231aSEd Maste     log->PutCString("");
273ead24645SDimitry Andric     LLDB_LOGF(log,
274ead24645SDimitry Andric               "ThreadList::%s: %" PRIu64 " threads, %" PRIu64
27514f1b3e8SDimitry Andric               " unsuspended threads",
27614f1b3e8SDimitry Andric               __FUNCTION__, (uint64_t)m_threads.size(),
277e81d9d49SDimitry Andric               (uint64_t)threads_copy.size());
278f034231aSEd Maste   }
279f034231aSEd Maste 
280f034231aSEd Maste   bool did_anybody_stop_for_a_reason = false;
2810cac4ca3SEd Maste 
28214f1b3e8SDimitry Andric   // If the event is an Interrupt event, then we're going to stop no matter
28314f1b3e8SDimitry Andric   // what.  Otherwise, presume we won't stop.
284f034231aSEd Maste   bool should_stop = false;
28514f1b3e8SDimitry Andric   if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr)) {
286ead24645SDimitry Andric     LLDB_LOGF(
287ead24645SDimitry Andric         log, "ThreadList::%s handling interrupt event, should stop set to true",
28814f1b3e8SDimitry Andric         __FUNCTION__);
2890cac4ca3SEd Maste 
2900cac4ca3SEd Maste     should_stop = true;
2910cac4ca3SEd Maste   }
292f034231aSEd Maste 
29314f1b3e8SDimitry Andric   // Now we run through all the threads and get their stop info's.  We want to
294f73363f1SDimitry Andric   // make sure to do this first before we start running the ShouldStop, because
295f73363f1SDimitry Andric   // one thread's ShouldStop could destroy information (like deleting a thread
296f73363f1SDimitry Andric   // specific breakpoint another thread had stopped at) which could lead us to
297f73363f1SDimitry Andric   // compute the StopInfo incorrectly. We don't need to use it here, we just
298f73363f1SDimitry Andric   // want to make sure it gets computed.
299f034231aSEd Maste 
30014f1b3e8SDimitry Andric   for (pos = threads_copy.begin(); pos != end; ++pos) {
301f034231aSEd Maste     ThreadSP thread_sp(*pos);
302f034231aSEd Maste     thread_sp->GetStopInfo();
303f034231aSEd Maste   }
304f034231aSEd Maste 
305e3b55780SDimitry Andric   // If a thread needs to finish some job that can be done just on this thread
306e3b55780SDimitry Andric   // before broadcastion the stop, it will signal that by returning true for
307e3b55780SDimitry Andric   // ShouldRunBeforePublicStop.  This variable gathers the results from that.
308e3b55780SDimitry Andric   bool a_thread_needs_to_run = false;
30914f1b3e8SDimitry Andric   for (pos = threads_copy.begin(); pos != end; ++pos) {
310f034231aSEd Maste     ThreadSP thread_sp(*pos);
311f034231aSEd Maste 
31214f1b3e8SDimitry Andric     // We should never get a stop for which no thread had a stop reason, but
313f73363f1SDimitry Andric     // sometimes we do see this - for instance when we first connect to a
314f73363f1SDimitry Andric     // remote stub.  In that case we should stop, since we can't figure out the
315f73363f1SDimitry Andric     // right thing to do and stopping gives the user control over what to do in
316f73363f1SDimitry Andric     // this instance.
317866dcdacSEd Maste     //
31814f1b3e8SDimitry Andric     // Note, this causes a problem when you have a thread specific breakpoint,
319f73363f1SDimitry Andric     // and a bunch of threads hit the breakpoint, but not the thread which we
320f73363f1SDimitry Andric     // are waiting for.  All the threads that are not "supposed" to hit the
321f73363f1SDimitry Andric     // breakpoint are marked as having no stop reason, which is right, they
322f73363f1SDimitry Andric     // should not show a stop reason.  But that triggers this code and causes
323f73363f1SDimitry Andric     // us to stop seemingly for no reason.
324866dcdacSEd Maste     //
32514f1b3e8SDimitry Andric     // Since the only way we ever saw this error was on first attach, I'm only
326f73363f1SDimitry Andric     // going to trigger set did_anybody_stop_for_a_reason to true unless this
327f73363f1SDimitry Andric     // is the first stop.
328866dcdacSEd Maste     //
32914f1b3e8SDimitry Andric     // If this becomes a problem, we'll have to have another StopReason like
330f73363f1SDimitry Andric     // "StopInfoHidden" which will look invalid everywhere but at this check.
331866dcdacSEd Maste 
332866dcdacSEd Maste     if (thread_sp->GetProcess()->GetStopID() > 1)
333866dcdacSEd Maste       did_anybody_stop_for_a_reason = true;
334866dcdacSEd Maste     else
335f034231aSEd Maste       did_anybody_stop_for_a_reason |= thread_sp->ThreadStoppedForAReason();
336f034231aSEd Maste 
337f034231aSEd Maste     const bool thread_should_stop = thread_sp->ShouldStop(event_ptr);
338e3b55780SDimitry Andric 
339f034231aSEd Maste     if (thread_should_stop)
340f034231aSEd Maste       should_stop |= true;
341e3b55780SDimitry Andric     else {
342e3b55780SDimitry Andric       bool this_thread_forces_run = thread_sp->ShouldRunBeforePublicStop();
343e3b55780SDimitry Andric       a_thread_needs_to_run |= this_thread_forces_run;
344e3b55780SDimitry Andric       if (this_thread_forces_run)
345e3b55780SDimitry Andric         LLDB_LOG(log,
346e3b55780SDimitry Andric                  "ThreadList::{0} thread: {1:x}, "
347e3b55780SDimitry Andric                  "says it needs to run before public stop.",
348e3b55780SDimitry Andric                  __FUNCTION__, thread_sp->GetID());
349e3b55780SDimitry Andric     }
350f034231aSEd Maste   }
351f034231aSEd Maste 
352e3b55780SDimitry Andric   if (a_thread_needs_to_run) {
353e3b55780SDimitry Andric     should_stop = false;
354e3b55780SDimitry Andric   } else if (!should_stop && !did_anybody_stop_for_a_reason) {
355f034231aSEd Maste     should_stop = true;
356ead24645SDimitry Andric     LLDB_LOGF(log,
357ead24645SDimitry Andric               "ThreadList::%s we stopped but no threads had a stop reason, "
35814f1b3e8SDimitry Andric               "overriding should_stop and stopping.",
35914f1b3e8SDimitry Andric               __FUNCTION__);
360f034231aSEd Maste   }
361f034231aSEd Maste 
362ead24645SDimitry Andric   LLDB_LOGF(log, "ThreadList::%s overall should_stop = %i", __FUNCTION__,
36314f1b3e8SDimitry Andric             should_stop);
364f034231aSEd Maste 
36514f1b3e8SDimitry Andric   if (should_stop) {
36614f1b3e8SDimitry Andric     for (pos = threads_copy.begin(); pos != end; ++pos) {
367f034231aSEd Maste       ThreadSP thread_sp(*pos);
368f034231aSEd Maste       thread_sp->WillStop();
369f034231aSEd Maste     }
370f034231aSEd Maste   }
371f034231aSEd Maste 
372f034231aSEd Maste   return should_stop;
373f034231aSEd Maste }
374f034231aSEd Maste 
ShouldReportStop(Event * event_ptr)37514f1b3e8SDimitry Andric Vote ThreadList::ShouldReportStop(Event *event_ptr) {
376f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
377f034231aSEd Maste 
378f034231aSEd Maste   Vote result = eVoteNoOpinion;
379ac9a064cSDimitry Andric   m_process.UpdateThreadListIfNeeded();
380f034231aSEd Maste   collection::iterator pos, end = m_threads.end();
381f034231aSEd Maste 
382145449b1SDimitry Andric   Log *log = GetLog(LLDBLog::Step);
383f034231aSEd Maste 
384ead24645SDimitry Andric   LLDB_LOGF(log, "ThreadList::%s %" PRIu64 " threads", __FUNCTION__,
38514f1b3e8SDimitry Andric             (uint64_t)m_threads.size());
386f034231aSEd Maste 
387f73363f1SDimitry Andric   // Run through the threads and ask whether we should report this event. For
388f73363f1SDimitry Andric   // stopping, a YES vote wins over everything.  A NO vote wins over NO
389e3b55780SDimitry Andric   // opinion.  The exception is if a thread has work it needs to force before
390e3b55780SDimitry Andric   // a public stop, which overrides everyone else's opinion:
39114f1b3e8SDimitry Andric   for (pos = m_threads.begin(); pos != end; ++pos) {
392f034231aSEd Maste     ThreadSP thread_sp(*pos);
393e3b55780SDimitry Andric     if (thread_sp->ShouldRunBeforePublicStop()) {
394e3b55780SDimitry Andric       LLDB_LOG(log, "Thread {0:x} has private business to complete, overrode "
395e3b55780SDimitry Andric                "the should report stop.", thread_sp->GetID());
396e3b55780SDimitry Andric       result = eVoteNo;
397e3b55780SDimitry Andric       break;
398e3b55780SDimitry Andric     }
399e3b55780SDimitry Andric 
400f034231aSEd Maste     const Vote vote = thread_sp->ShouldReportStop(event_ptr);
40114f1b3e8SDimitry Andric     switch (vote) {
402f034231aSEd Maste     case eVoteNoOpinion:
403f034231aSEd Maste       continue;
404f034231aSEd Maste 
405f034231aSEd Maste     case eVoteYes:
406f034231aSEd Maste       result = eVoteYes;
407f034231aSEd Maste       break;
408f034231aSEd Maste 
409f034231aSEd Maste     case eVoteNo:
41014f1b3e8SDimitry Andric       if (result == eVoteNoOpinion) {
411f034231aSEd Maste         result = eVoteNo;
41214f1b3e8SDimitry Andric       } else {
41374a628f7SDimitry Andric         LLDB_LOG(log,
41474a628f7SDimitry Andric           "Thread {0:x} voted {1}, but lost out because result was {2}",
41574a628f7SDimitry Andric           thread_sp->GetID(), vote, result);
416f034231aSEd Maste       }
417f034231aSEd Maste       break;
418f034231aSEd Maste     }
419f034231aSEd Maste   }
42074a628f7SDimitry Andric   LLDB_LOG(log, "Returning {0}", result);
421f034231aSEd Maste   return result;
422f034231aSEd Maste }
423f034231aSEd Maste 
SetShouldReportStop(Vote vote)42414f1b3e8SDimitry Andric void ThreadList::SetShouldReportStop(Vote vote) {
425f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
426f3fbd1c0SDimitry Andric 
427ac9a064cSDimitry Andric   m_process.UpdateThreadListIfNeeded();
428f034231aSEd Maste   collection::iterator pos, end = m_threads.end();
42914f1b3e8SDimitry Andric   for (pos = m_threads.begin(); pos != end; ++pos) {
430f034231aSEd Maste     ThreadSP thread_sp(*pos);
431f034231aSEd Maste     thread_sp->SetShouldReportStop(vote);
432f034231aSEd Maste   }
433f034231aSEd Maste }
434f034231aSEd Maste 
ShouldReportRun(Event * event_ptr)43514f1b3e8SDimitry Andric Vote ThreadList::ShouldReportRun(Event *event_ptr) {
436f034231aSEd Maste 
437f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
438f034231aSEd Maste 
439f034231aSEd Maste   Vote result = eVoteNoOpinion;
440ac9a064cSDimitry Andric   m_process.UpdateThreadListIfNeeded();
441f034231aSEd Maste   collection::iterator pos, end = m_threads.end();
442f034231aSEd Maste 
443f73363f1SDimitry Andric   // Run through the threads and ask whether we should report this event. The
444f73363f1SDimitry Andric   // rule is NO vote wins over everything, a YES vote wins over no opinion.
445f034231aSEd Maste 
446145449b1SDimitry Andric   Log *log = GetLog(LLDBLog::Step);
447f034231aSEd Maste 
44814f1b3e8SDimitry Andric   for (pos = m_threads.begin(); pos != end; ++pos) {
44914f1b3e8SDimitry Andric     if ((*pos)->GetResumeState() != eStateSuspended) {
45014f1b3e8SDimitry Andric       switch ((*pos)->ShouldReportRun(event_ptr)) {
451f034231aSEd Maste       case eVoteNoOpinion:
452f034231aSEd Maste         continue;
453f034231aSEd Maste       case eVoteYes:
454f034231aSEd Maste         if (result == eVoteNoOpinion)
455f034231aSEd Maste           result = eVoteYes;
456f034231aSEd Maste         break;
457f034231aSEd Maste       case eVoteNo:
458ead24645SDimitry Andric         LLDB_LOGF(log,
459ead24645SDimitry Andric                   "ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64
46014f1b3e8SDimitry Andric                   ") says don't report.",
46114f1b3e8SDimitry Andric                   (*pos)->GetIndexID(), (*pos)->GetID());
462f034231aSEd Maste         result = eVoteNo;
463f034231aSEd Maste         break;
464f034231aSEd Maste       }
465f034231aSEd Maste     }
466f034231aSEd Maste   }
467f034231aSEd Maste   return result;
468f034231aSEd Maste }
469f034231aSEd Maste 
Clear()47014f1b3e8SDimitry Andric void ThreadList::Clear() {
471f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
472f034231aSEd Maste   m_stop_id = 0;
473f034231aSEd Maste   m_threads.clear();
474f034231aSEd Maste   m_selected_tid = LLDB_INVALID_THREAD_ID;
475f034231aSEd Maste }
476f034231aSEd Maste 
Destroy()47714f1b3e8SDimitry Andric void ThreadList::Destroy() {
478f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
479f034231aSEd Maste   const uint32_t num_threads = m_threads.size();
48014f1b3e8SDimitry Andric   for (uint32_t idx = 0; idx < num_threads; ++idx) {
481f034231aSEd Maste     m_threads[idx]->DestroyThread();
482f034231aSEd Maste   }
483f034231aSEd Maste }
484f034231aSEd Maste 
RefreshStateAfterStop()48514f1b3e8SDimitry Andric void ThreadList::RefreshStateAfterStop() {
486f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
487f034231aSEd Maste 
488ac9a064cSDimitry Andric   m_process.UpdateThreadListIfNeeded();
489f034231aSEd Maste 
490145449b1SDimitry Andric   Log *log = GetLog(LLDBLog::Step);
491f034231aSEd Maste   if (log && log->GetVerbose())
492ead24645SDimitry Andric     LLDB_LOGF(log,
493ead24645SDimitry Andric               "Turning off notification of new threads while single stepping "
49414f1b3e8SDimitry Andric               "a thread.");
495f034231aSEd Maste 
496f034231aSEd Maste   collection::iterator pos, end = m_threads.end();
497f034231aSEd Maste   for (pos = m_threads.begin(); pos != end; ++pos)
498f034231aSEd Maste     (*pos)->RefreshStateAfterStop();
499f034231aSEd Maste }
500f034231aSEd Maste 
DiscardThreadPlans()50114f1b3e8SDimitry Andric void ThreadList::DiscardThreadPlans() {
502f73363f1SDimitry Andric   // You don't need to update the thread list here, because only threads that
503f73363f1SDimitry Andric   // you currently know about have any thread plans.
504f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
505f034231aSEd Maste 
506f034231aSEd Maste   collection::iterator pos, end = m_threads.end();
507f034231aSEd Maste   for (pos = m_threads.begin(); pos != end; ++pos)
508f034231aSEd Maste     (*pos)->DiscardThreadPlans(true);
509f034231aSEd Maste }
510f034231aSEd Maste 
WillResume()51114f1b3e8SDimitry Andric bool ThreadList::WillResume() {
512f73363f1SDimitry Andric   // Run through the threads and perform their momentary actions. But we only
513f73363f1SDimitry Andric   // do this for threads that are running, user suspended threads stay where
514f73363f1SDimitry Andric   // they are.
515f034231aSEd Maste 
516f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
517ac9a064cSDimitry Andric   m_process.UpdateThreadListIfNeeded();
518f034231aSEd Maste 
519f034231aSEd Maste   collection::iterator pos, end = m_threads.end();
520f034231aSEd Maste 
521f034231aSEd Maste   // See if any thread wants to run stopping others.  If it does, then we won't
522f73363f1SDimitry Andric   // setup the other threads for resume, since they aren't going to get a
523f73363f1SDimitry Andric   // chance to run.  This is necessary because the SetupForResume might add
524f73363f1SDimitry Andric   // "StopOthers" plans which would then get to be part of the who-gets-to-run
525f73363f1SDimitry Andric   // negotiation, but they're coming in after the fact, and the threads that
526f73363f1SDimitry Andric   // are already set up should take priority.
527f034231aSEd Maste 
528f034231aSEd Maste   bool wants_solo_run = false;
529f034231aSEd Maste 
53014f1b3e8SDimitry Andric   for (pos = m_threads.begin(); pos != end; ++pos) {
53114f1b3e8SDimitry Andric     lldbassert((*pos)->GetCurrentPlan() &&
53214f1b3e8SDimitry Andric                "thread should not have null thread plan");
533f034231aSEd Maste     if ((*pos)->GetResumeState() != eStateSuspended &&
53414f1b3e8SDimitry Andric         (*pos)->GetCurrentPlan()->StopOthers()) {
53514f1b3e8SDimitry Andric       if ((*pos)->IsOperatingSystemPluginThread() &&
53614f1b3e8SDimitry Andric           !(*pos)->GetBackingThread())
537f034231aSEd Maste         continue;
538f034231aSEd Maste       wants_solo_run = true;
539f034231aSEd Maste       break;
540f034231aSEd Maste     }
541f034231aSEd Maste   }
542f034231aSEd Maste 
54314f1b3e8SDimitry Andric   if (wants_solo_run) {
544145449b1SDimitry Andric     Log *log = GetLog(LLDBLog::Step);
545f034231aSEd Maste     if (log && log->GetVerbose())
546ead24645SDimitry Andric       LLDB_LOGF(log, "Turning on notification of new threads while single "
54714f1b3e8SDimitry Andric                      "stepping a thread.");
548ac9a064cSDimitry Andric     m_process.StartNoticingNewThreads();
54914f1b3e8SDimitry Andric   } else {
550145449b1SDimitry Andric     Log *log = GetLog(LLDBLog::Step);
551f034231aSEd Maste     if (log && log->GetVerbose())
552ead24645SDimitry Andric       LLDB_LOGF(log, "Turning off notification of new threads while single "
55314f1b3e8SDimitry Andric                      "stepping a thread.");
554ac9a064cSDimitry Andric     m_process.StopNoticingNewThreads();
555f034231aSEd Maste   }
556f034231aSEd Maste 
55714f1b3e8SDimitry Andric   // Give all the threads that are likely to run a last chance to set up their
558f73363f1SDimitry Andric   // state before we negotiate who is actually going to get a chance to run...
55914f1b3e8SDimitry Andric   // Don't set to resume suspended threads, and if any thread wanted to stop
560f73363f1SDimitry Andric   // others, only call setup on the threads that request StopOthers...
561f034231aSEd Maste 
56214f1b3e8SDimitry Andric   for (pos = m_threads.begin(); pos != end; ++pos) {
56314f1b3e8SDimitry Andric     if ((*pos)->GetResumeState() != eStateSuspended &&
56414f1b3e8SDimitry Andric         (!wants_solo_run || (*pos)->GetCurrentPlan()->StopOthers())) {
56514f1b3e8SDimitry Andric       if ((*pos)->IsOperatingSystemPluginThread() &&
56614f1b3e8SDimitry Andric           !(*pos)->GetBackingThread())
567f034231aSEd Maste         continue;
568f034231aSEd Maste       (*pos)->SetupForResume();
569f034231aSEd Maste     }
570f034231aSEd Maste   }
571f034231aSEd Maste 
572f034231aSEd Maste   // Now go through the threads and see if any thread wants to run just itself.
573f034231aSEd Maste   // if so then pick one and run it.
574f034231aSEd Maste 
575f034231aSEd Maste   ThreadList run_me_only_list(m_process);
576f034231aSEd Maste 
577ac9a064cSDimitry Andric   run_me_only_list.SetStopID(m_process.GetStopID());
578f034231aSEd Maste 
579e3b55780SDimitry Andric   // One or more threads might want to "Stop Others".  We want to handle all
580e3b55780SDimitry Andric   // those requests first.  And if there is a thread that wanted to "resume
581e3b55780SDimitry Andric   // before a public stop", let it get the first crack:
582e3b55780SDimitry Andric   // There are two special kinds of thread that have priority for "StopOthers":
583e3b55780SDimitry Andric   // a "ShouldRunBeforePublicStop thread, or the currently selected thread.  If
584e3b55780SDimitry Andric   // we find one satisfying that critereon, put it here.
585e3b55780SDimitry Andric   ThreadSP stop_others_thread_sp;
586f034231aSEd Maste 
58714f1b3e8SDimitry Andric   for (pos = m_threads.begin(); pos != end; ++pos) {
588f034231aSEd Maste     ThreadSP thread_sp(*pos);
589f034231aSEd Maste     if (thread_sp->GetResumeState() != eStateSuspended &&
59014f1b3e8SDimitry Andric         thread_sp->GetCurrentPlan()->StopOthers()) {
59114f1b3e8SDimitry Andric       if ((*pos)->IsOperatingSystemPluginThread() &&
59214f1b3e8SDimitry Andric           !(*pos)->GetBackingThread())
593f034231aSEd Maste         continue;
594f034231aSEd Maste 
595f034231aSEd Maste       // You can't say "stop others" and also want yourself to be suspended.
596f034231aSEd Maste       assert(thread_sp->GetCurrentPlan()->RunState() != eStateSuspended);
597f034231aSEd Maste       run_me_only_list.AddThread(thread_sp);
598e3b55780SDimitry Andric 
599e3b55780SDimitry Andric       if (thread_sp == GetSelectedThread())
600e3b55780SDimitry Andric         stop_others_thread_sp = thread_sp;
601e3b55780SDimitry Andric 
602e3b55780SDimitry Andric       if (thread_sp->ShouldRunBeforePublicStop()) {
603e3b55780SDimitry Andric         // This takes precedence, so if we find one of these, service it:
604e3b55780SDimitry Andric         stop_others_thread_sp = thread_sp;
605f034231aSEd Maste         break;
606f034231aSEd Maste       }
607f034231aSEd Maste     }
608f034231aSEd Maste   }
609f034231aSEd Maste 
610f034231aSEd Maste   bool need_to_resume = true;
611f034231aSEd Maste 
61214f1b3e8SDimitry Andric   if (run_me_only_list.GetSize(false) == 0) {
613f034231aSEd Maste     // Everybody runs as they wish:
61414f1b3e8SDimitry Andric     for (pos = m_threads.begin(); pos != end; ++pos) {
615f034231aSEd Maste       ThreadSP thread_sp(*pos);
616f034231aSEd Maste       StateType run_state;
617f034231aSEd Maste       if (thread_sp->GetResumeState() != eStateSuspended)
618f034231aSEd Maste         run_state = thread_sp->GetCurrentPlan()->RunState();
619f034231aSEd Maste       else
620f034231aSEd Maste         run_state = eStateSuspended;
621f034231aSEd Maste       if (!thread_sp->ShouldResume(run_state))
622f034231aSEd Maste         need_to_resume = false;
623f034231aSEd Maste     }
62414f1b3e8SDimitry Andric   } else {
625f034231aSEd Maste     ThreadSP thread_to_run;
626f034231aSEd Maste 
627e3b55780SDimitry Andric     if (stop_others_thread_sp) {
628e3b55780SDimitry Andric       thread_to_run = stop_others_thread_sp;
62914f1b3e8SDimitry Andric     } else if (run_me_only_list.GetSize(false) == 1) {
630f034231aSEd Maste       thread_to_run = run_me_only_list.GetThreadAtIndex(0);
63114f1b3e8SDimitry Andric     } else {
63214f1b3e8SDimitry Andric       int random_thread =
63314f1b3e8SDimitry Andric           (int)((run_me_only_list.GetSize(false) * (double)rand()) /
63414f1b3e8SDimitry Andric                 (RAND_MAX + 1.0));
635f034231aSEd Maste       thread_to_run = run_me_only_list.GetThreadAtIndex(random_thread);
636f034231aSEd Maste     }
637f034231aSEd Maste 
63814f1b3e8SDimitry Andric     for (pos = m_threads.begin(); pos != end; ++pos) {
639f034231aSEd Maste       ThreadSP thread_sp(*pos);
64014f1b3e8SDimitry Andric       if (thread_sp == thread_to_run) {
641e3b55780SDimitry Andric         // Note, a thread might be able to fulfil it's plan w/o actually
642e3b55780SDimitry Andric         // resuming.  An example of this is a step that changes the current
643e3b55780SDimitry Andric         // inlined function depth w/o moving the PC.  Check that here:
644f034231aSEd Maste         if (!thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState()))
645f034231aSEd Maste           need_to_resume = false;
64614f1b3e8SDimitry Andric       } else
647f034231aSEd Maste         thread_sp->ShouldResume(eStateSuspended);
648f034231aSEd Maste     }
649f034231aSEd Maste   }
650f034231aSEd Maste 
651f034231aSEd Maste   return need_to_resume;
652f034231aSEd Maste }
653f034231aSEd Maste 
DidResume()65414f1b3e8SDimitry Andric void ThreadList::DidResume() {
655f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
656f034231aSEd Maste   collection::iterator pos, end = m_threads.end();
65714f1b3e8SDimitry Andric   for (pos = m_threads.begin(); pos != end; ++pos) {
658f034231aSEd Maste     // Don't clear out threads that aren't going to get a chance to run, rather
659f034231aSEd Maste     // leave their state for the next time around.
660f034231aSEd Maste     ThreadSP thread_sp(*pos);
661e3b55780SDimitry Andric     if (thread_sp->GetTemporaryResumeState() != eStateSuspended)
662f034231aSEd Maste       thread_sp->DidResume();
663f034231aSEd Maste   }
664f034231aSEd Maste }
665f034231aSEd Maste 
DidStop()66614f1b3e8SDimitry Andric void ThreadList::DidStop() {
667f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
668f034231aSEd Maste   collection::iterator pos, end = m_threads.end();
66914f1b3e8SDimitry Andric   for (pos = m_threads.begin(); pos != end; ++pos) {
670f73363f1SDimitry Andric     // Notify threads that the process just stopped. Note, this currently
671f73363f1SDimitry Andric     // assumes that all threads in the list stop when the process stops.  In
672f73363f1SDimitry Andric     // the future we will want to support a debugging model where some threads
673f73363f1SDimitry Andric     // continue to run while others are stopped.  We either need to handle that
674f73363f1SDimitry Andric     // somehow here or create a special thread list containing only threads
675f73363f1SDimitry Andric     // which will stop in the code that calls this method (currently
676f034231aSEd Maste     // Process::SetPrivateState).
677f034231aSEd Maste     ThreadSP thread_sp(*pos);
678f034231aSEd Maste     if (StateIsRunningState(thread_sp->GetState()))
679f034231aSEd Maste       thread_sp->DidStop();
680f034231aSEd Maste   }
681f034231aSEd Maste }
682f034231aSEd Maste 
GetSelectedThread()68314f1b3e8SDimitry Andric ThreadSP ThreadList::GetSelectedThread() {
684f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
685f034231aSEd Maste   ThreadSP thread_sp = FindThreadByID(m_selected_tid);
68614f1b3e8SDimitry Andric   if (!thread_sp.get()) {
687f034231aSEd Maste     if (m_threads.size() == 0)
688f034231aSEd Maste       return thread_sp;
689f034231aSEd Maste     m_selected_tid = m_threads[0]->GetID();
690f034231aSEd Maste     thread_sp = m_threads[0];
691f034231aSEd Maste   }
692f034231aSEd Maste   return thread_sp;
693f034231aSEd Maste }
694f034231aSEd Maste 
SetSelectedThreadByID(lldb::tid_t tid,bool notify)69514f1b3e8SDimitry Andric bool ThreadList::SetSelectedThreadByID(lldb::tid_t tid, bool notify) {
696f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
697f034231aSEd Maste   ThreadSP selected_thread_sp(FindThreadByID(tid));
69814f1b3e8SDimitry Andric   if (selected_thread_sp) {
699f034231aSEd Maste     m_selected_tid = tid;
700f034231aSEd Maste     selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
70114f1b3e8SDimitry Andric   } else
702f034231aSEd Maste     m_selected_tid = LLDB_INVALID_THREAD_ID;
703f034231aSEd Maste 
704f034231aSEd Maste   if (notify)
705f034231aSEd Maste     NotifySelectedThreadChanged(m_selected_tid);
706f034231aSEd Maste 
707f034231aSEd Maste   return m_selected_tid != LLDB_INVALID_THREAD_ID;
708f034231aSEd Maste }
709f034231aSEd Maste 
SetSelectedThreadByIndexID(uint32_t index_id,bool notify)71014f1b3e8SDimitry Andric bool ThreadList::SetSelectedThreadByIndexID(uint32_t index_id, bool notify) {
711f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
712f034231aSEd Maste   ThreadSP selected_thread_sp(FindThreadByIndexID(index_id));
71314f1b3e8SDimitry Andric   if (selected_thread_sp.get()) {
714f034231aSEd Maste     m_selected_tid = selected_thread_sp->GetID();
715f034231aSEd Maste     selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
71614f1b3e8SDimitry Andric   } else
717f034231aSEd Maste     m_selected_tid = LLDB_INVALID_THREAD_ID;
718f034231aSEd Maste 
719f034231aSEd Maste   if (notify)
720f034231aSEd Maste     NotifySelectedThreadChanged(m_selected_tid);
721f034231aSEd Maste 
722f034231aSEd Maste   return m_selected_tid != LLDB_INVALID_THREAD_ID;
723f034231aSEd Maste }
724f034231aSEd Maste 
NotifySelectedThreadChanged(lldb::tid_t tid)72514f1b3e8SDimitry Andric void ThreadList::NotifySelectedThreadChanged(lldb::tid_t tid) {
726f034231aSEd Maste   ThreadSP selected_thread_sp(FindThreadByID(tid));
72714f1b3e8SDimitry Andric   if (selected_thread_sp->EventTypeHasListeners(
7284df029ccSDimitry Andric           Thread::eBroadcastBitThreadSelected)) {
7294df029ccSDimitry Andric     auto data_sp =
7304df029ccSDimitry Andric         std::make_shared<Thread::ThreadEventData>(selected_thread_sp);
7314df029ccSDimitry Andric     selected_thread_sp->BroadcastEvent(Thread::eBroadcastBitThreadSelected,
7324df029ccSDimitry Andric                                        data_sp);
7334df029ccSDimitry Andric   }
734f034231aSEd Maste }
735f034231aSEd Maste 
Update(ThreadList & rhs)73614f1b3e8SDimitry Andric void ThreadList::Update(ThreadList &rhs) {
73714f1b3e8SDimitry Andric   if (this != &rhs) {
738ac9a064cSDimitry Andric     // We only allow assignments between thread lists describing the same
739ac9a064cSDimitry Andric     // process. Same process implies same mutex, which means it's enough to lock
740ac9a064cSDimitry Andric     // just the current object.
741ac9a064cSDimitry Andric     assert(&m_process == &rhs.m_process);
742ac9a064cSDimitry Andric     assert(&GetMutex() == &rhs.GetMutex());
743ac9a064cSDimitry Andric     std::lock_guard<std::recursive_mutex> guard(GetMutex());
744f3fbd1c0SDimitry Andric 
745f034231aSEd Maste     m_stop_id = rhs.m_stop_id;
746f034231aSEd Maste     m_threads.swap(rhs.m_threads);
747f034231aSEd Maste     m_selected_tid = rhs.m_selected_tid;
748f034231aSEd Maste 
749f73363f1SDimitry Andric     // Now we look for threads that we are done with and make sure to clear
750f73363f1SDimitry Andric     // them up as much as possible so anyone with a shared pointer will still
751f73363f1SDimitry Andric     // have a reference, but the thread won't be of much use. Using
752f73363f1SDimitry Andric     // std::weak_ptr for all backward references (such as a thread to a
753f73363f1SDimitry Andric     // process) will eventually solve this issue for us, but for now, we need
754f73363f1SDimitry Andric     // to work around the issue
755f034231aSEd Maste     collection::iterator rhs_pos, rhs_end = rhs.m_threads.end();
75614f1b3e8SDimitry Andric     for (rhs_pos = rhs.m_threads.begin(); rhs_pos != rhs_end; ++rhs_pos) {
757cfca06d7SDimitry Andric       // If this thread has already been destroyed, we don't need to look for
758cfca06d7SDimitry Andric       // it to destroy it again.
759cfca06d7SDimitry Andric       if (!(*rhs_pos)->IsValid())
760cfca06d7SDimitry Andric         continue;
761cfca06d7SDimitry Andric 
762f034231aSEd Maste       const lldb::tid_t tid = (*rhs_pos)->GetID();
763f034231aSEd Maste       bool thread_is_alive = false;
764f034231aSEd Maste       const uint32_t num_threads = m_threads.size();
76514f1b3e8SDimitry Andric       for (uint32_t idx = 0; idx < num_threads; ++idx) {
766e81d9d49SDimitry Andric         ThreadSP backing_thread = m_threads[idx]->GetBackingThread();
76714f1b3e8SDimitry Andric         if (m_threads[idx]->GetID() == tid ||
76814f1b3e8SDimitry Andric             (backing_thread && backing_thread->GetID() == tid)) {
769f034231aSEd Maste           thread_is_alive = true;
770f034231aSEd Maste           break;
771f034231aSEd Maste         }
772f034231aSEd Maste       }
773cfca06d7SDimitry Andric       if (!thread_is_alive) {
774f034231aSEd Maste         (*rhs_pos)->DestroyThread();
775f034231aSEd Maste       }
776f034231aSEd Maste     }
777f034231aSEd Maste   }
778cfca06d7SDimitry Andric }
779f034231aSEd Maste 
Flush()78014f1b3e8SDimitry Andric void ThreadList::Flush() {
781f3fbd1c0SDimitry Andric   std::lock_guard<std::recursive_mutex> guard(GetMutex());
782f034231aSEd Maste   collection::iterator pos, end = m_threads.end();
783f034231aSEd Maste   for (pos = m_threads.begin(); pos != end; ++pos)
784f034231aSEd Maste     (*pos)->Flush();
785f034231aSEd Maste }
786f034231aSEd Maste 
GetMutex() const78714f1b3e8SDimitry Andric std::recursive_mutex &ThreadList::GetMutex() const {
788ac9a064cSDimitry Andric   return m_process.m_thread_mutex;
789f034231aSEd Maste }
790f034231aSEd Maste 
ExpressionExecutionThreadPusher(lldb::ThreadSP thread_sp)79114f1b3e8SDimitry Andric ThreadList::ExpressionExecutionThreadPusher::ExpressionExecutionThreadPusher(
79214f1b3e8SDimitry Andric     lldb::ThreadSP thread_sp)
79314f1b3e8SDimitry Andric     : m_thread_list(nullptr), m_tid(LLDB_INVALID_THREAD_ID) {
79414f1b3e8SDimitry Andric   if (thread_sp) {
795f3fbd1c0SDimitry Andric     m_tid = thread_sp->GetID();
796f3fbd1c0SDimitry Andric     m_thread_list = &thread_sp->GetProcess()->GetThreadList();
797f3fbd1c0SDimitry Andric     m_thread_list->PushExpressionExecutionThread(m_tid);
798f3fbd1c0SDimitry Andric   }
799f3fbd1c0SDimitry Andric }
800