1*30fdc8d8SChris Lattner //===-- ThreadList.cpp ------------------------------------------*- C++ -*-===//
2*30fdc8d8SChris Lattner //
3*30fdc8d8SChris Lattner //                     The LLVM Compiler Infrastructure
4*30fdc8d8SChris Lattner //
5*30fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source
6*30fdc8d8SChris Lattner // License. See LICENSE.TXT for details.
7*30fdc8d8SChris Lattner //
8*30fdc8d8SChris Lattner //===----------------------------------------------------------------------===//
9*30fdc8d8SChris Lattner #include <stdlib.h>
10*30fdc8d8SChris Lattner 
11*30fdc8d8SChris Lattner #include <algorithm>
12*30fdc8d8SChris Lattner 
13*30fdc8d8SChris Lattner #include "lldb/Target/ThreadList.h"
14*30fdc8d8SChris Lattner #include "lldb/Target/Thread.h"
15*30fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h"
16*30fdc8d8SChris Lattner #include "lldb/Target/Process.h"
17*30fdc8d8SChris Lattner 
18*30fdc8d8SChris Lattner using namespace lldb;
19*30fdc8d8SChris Lattner using namespace lldb_private;
20*30fdc8d8SChris Lattner 
21*30fdc8d8SChris Lattner ThreadList::ThreadList (Process *process) :
22*30fdc8d8SChris Lattner     m_process (process),
23*30fdc8d8SChris Lattner     m_stop_id (0),
24*30fdc8d8SChris Lattner     m_threads(),
25*30fdc8d8SChris Lattner     m_threads_mutex (Mutex::eMutexTypeRecursive),
26*30fdc8d8SChris Lattner     m_current_tid (LLDB_INVALID_THREAD_ID)
27*30fdc8d8SChris Lattner {
28*30fdc8d8SChris Lattner }
29*30fdc8d8SChris Lattner 
30*30fdc8d8SChris Lattner ThreadList::ThreadList (const ThreadList &rhs) :
31*30fdc8d8SChris Lattner     m_process (),
32*30fdc8d8SChris Lattner     m_stop_id (),
33*30fdc8d8SChris Lattner     m_threads (),
34*30fdc8d8SChris Lattner     m_threads_mutex (Mutex::eMutexTypeRecursive),
35*30fdc8d8SChris Lattner     m_current_tid ()
36*30fdc8d8SChris Lattner {
37*30fdc8d8SChris Lattner     // Use the assignment operator since it uses the mutex
38*30fdc8d8SChris Lattner     *this = rhs;
39*30fdc8d8SChris Lattner }
40*30fdc8d8SChris Lattner 
41*30fdc8d8SChris Lattner const ThreadList&
42*30fdc8d8SChris Lattner ThreadList::operator = (const ThreadList& rhs)
43*30fdc8d8SChris Lattner {
44*30fdc8d8SChris Lattner     if (this != &rhs)
45*30fdc8d8SChris Lattner     {
46*30fdc8d8SChris Lattner         // Lock both mutexes to make sure neither side changes anyone on us
47*30fdc8d8SChris Lattner         // while the assignement occurs
48*30fdc8d8SChris Lattner         Mutex::Locker locker_this(m_threads_mutex);
49*30fdc8d8SChris Lattner         Mutex::Locker locker_rhs(rhs.m_threads_mutex);
50*30fdc8d8SChris Lattner         m_process = rhs.m_process;
51*30fdc8d8SChris Lattner         m_stop_id = rhs.m_stop_id;
52*30fdc8d8SChris Lattner         m_threads = rhs.m_threads;
53*30fdc8d8SChris Lattner         m_current_tid = rhs.m_current_tid;
54*30fdc8d8SChris Lattner     }
55*30fdc8d8SChris Lattner     return *this;
56*30fdc8d8SChris Lattner }
57*30fdc8d8SChris Lattner 
58*30fdc8d8SChris Lattner 
59*30fdc8d8SChris Lattner ThreadList::~ThreadList()
60*30fdc8d8SChris Lattner {
61*30fdc8d8SChris Lattner }
62*30fdc8d8SChris Lattner 
63*30fdc8d8SChris Lattner 
64*30fdc8d8SChris Lattner uint32_t
65*30fdc8d8SChris Lattner ThreadList::GetStopID () const
66*30fdc8d8SChris Lattner {
67*30fdc8d8SChris Lattner     return m_stop_id;
68*30fdc8d8SChris Lattner }
69*30fdc8d8SChris Lattner 
70*30fdc8d8SChris Lattner void
71*30fdc8d8SChris Lattner ThreadList::SetStopID (uint32_t stop_id)
72*30fdc8d8SChris Lattner {
73*30fdc8d8SChris Lattner     m_stop_id = stop_id;
74*30fdc8d8SChris Lattner }
75*30fdc8d8SChris Lattner 
76*30fdc8d8SChris Lattner 
77*30fdc8d8SChris Lattner void
78*30fdc8d8SChris Lattner ThreadList::AddThread (ThreadSP &thread_sp)
79*30fdc8d8SChris Lattner {
80*30fdc8d8SChris Lattner     Mutex::Locker locker(m_threads_mutex);
81*30fdc8d8SChris Lattner     m_threads.push_back(thread_sp);
82*30fdc8d8SChris Lattner }
83*30fdc8d8SChris Lattner 
84*30fdc8d8SChris Lattner uint32_t
85*30fdc8d8SChris Lattner ThreadList::GetSize (bool can_update)
86*30fdc8d8SChris Lattner {
87*30fdc8d8SChris Lattner     Mutex::Locker locker(m_threads_mutex);
88*30fdc8d8SChris Lattner     if (can_update)
89*30fdc8d8SChris Lattner         m_process->UpdateThreadListIfNeeded();
90*30fdc8d8SChris Lattner     return m_threads.size();
91*30fdc8d8SChris Lattner }
92*30fdc8d8SChris Lattner 
93*30fdc8d8SChris Lattner ThreadSP
94*30fdc8d8SChris Lattner ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update)
95*30fdc8d8SChris Lattner {
96*30fdc8d8SChris Lattner     Mutex::Locker locker(m_threads_mutex);
97*30fdc8d8SChris Lattner     if (can_update)
98*30fdc8d8SChris Lattner         m_process->UpdateThreadListIfNeeded();
99*30fdc8d8SChris Lattner 
100*30fdc8d8SChris Lattner     ThreadSP thread_sp;
101*30fdc8d8SChris Lattner     if (idx < m_threads.size())
102*30fdc8d8SChris Lattner         thread_sp = m_threads[idx];
103*30fdc8d8SChris Lattner     return thread_sp;
104*30fdc8d8SChris Lattner }
105*30fdc8d8SChris Lattner 
106*30fdc8d8SChris Lattner ThreadSP
107*30fdc8d8SChris Lattner ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update)
108*30fdc8d8SChris Lattner {
109*30fdc8d8SChris Lattner     Mutex::Locker locker(m_threads_mutex);
110*30fdc8d8SChris Lattner 
111*30fdc8d8SChris Lattner     if (can_update)
112*30fdc8d8SChris Lattner         m_process->UpdateThreadListIfNeeded();
113*30fdc8d8SChris Lattner 
114*30fdc8d8SChris Lattner     ThreadSP thread_sp;
115*30fdc8d8SChris Lattner     uint32_t idx = 0;
116*30fdc8d8SChris Lattner     const uint32_t num_threads = m_threads.size();
117*30fdc8d8SChris Lattner     for (idx = 0; idx < num_threads; ++idx)
118*30fdc8d8SChris Lattner     {
119*30fdc8d8SChris Lattner         if (m_threads[idx]->GetID() == tid)
120*30fdc8d8SChris Lattner         {
121*30fdc8d8SChris Lattner             thread_sp = m_threads[idx];
122*30fdc8d8SChris Lattner             break;
123*30fdc8d8SChris Lattner         }
124*30fdc8d8SChris Lattner     }
125*30fdc8d8SChris Lattner     return thread_sp;
126*30fdc8d8SChris Lattner }
127*30fdc8d8SChris Lattner 
128*30fdc8d8SChris Lattner ThreadSP
129*30fdc8d8SChris Lattner ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr)
130*30fdc8d8SChris Lattner {
131*30fdc8d8SChris Lattner     ThreadSP thread_sp;
132*30fdc8d8SChris Lattner     if (thread_ptr)
133*30fdc8d8SChris Lattner     {
134*30fdc8d8SChris Lattner         Mutex::Locker locker(m_threads_mutex);
135*30fdc8d8SChris Lattner 
136*30fdc8d8SChris Lattner         uint32_t idx = 0;
137*30fdc8d8SChris Lattner         const uint32_t num_threads = m_threads.size();
138*30fdc8d8SChris Lattner         for (idx = 0; idx < num_threads; ++idx)
139*30fdc8d8SChris Lattner         {
140*30fdc8d8SChris Lattner             if (m_threads[idx].get() == thread_ptr)
141*30fdc8d8SChris Lattner             {
142*30fdc8d8SChris Lattner                 thread_sp = m_threads[idx];
143*30fdc8d8SChris Lattner                 break;
144*30fdc8d8SChris Lattner             }
145*30fdc8d8SChris Lattner         }
146*30fdc8d8SChris Lattner     }
147*30fdc8d8SChris Lattner     return thread_sp;
148*30fdc8d8SChris Lattner }
149*30fdc8d8SChris Lattner 
150*30fdc8d8SChris Lattner 
151*30fdc8d8SChris Lattner 
152*30fdc8d8SChris Lattner ThreadSP
153*30fdc8d8SChris Lattner ThreadList::FindThreadByIndexID (uint32_t index_id, bool can_update)
154*30fdc8d8SChris Lattner {
155*30fdc8d8SChris Lattner     Mutex::Locker locker(m_threads_mutex);
156*30fdc8d8SChris Lattner 
157*30fdc8d8SChris Lattner     if (can_update)
158*30fdc8d8SChris Lattner         m_process->UpdateThreadListIfNeeded();
159*30fdc8d8SChris Lattner 
160*30fdc8d8SChris Lattner     ThreadSP thread_sp;
161*30fdc8d8SChris Lattner     const uint32_t num_threads = m_threads.size();
162*30fdc8d8SChris Lattner     for (uint32_t idx = 0; idx < num_threads; ++idx)
163*30fdc8d8SChris Lattner     {
164*30fdc8d8SChris Lattner         if (m_threads[idx]->GetIndexID() == index_id)
165*30fdc8d8SChris Lattner         {
166*30fdc8d8SChris Lattner             thread_sp = m_threads[idx];
167*30fdc8d8SChris Lattner             break;
168*30fdc8d8SChris Lattner         }
169*30fdc8d8SChris Lattner     }
170*30fdc8d8SChris Lattner     return thread_sp;
171*30fdc8d8SChris Lattner }
172*30fdc8d8SChris Lattner 
173*30fdc8d8SChris Lattner bool
174*30fdc8d8SChris Lattner ThreadList::ShouldStop (Event *event_ptr)
175*30fdc8d8SChris Lattner {
176*30fdc8d8SChris Lattner     Mutex::Locker locker(m_threads_mutex);
177*30fdc8d8SChris Lattner 
178*30fdc8d8SChris Lattner     // Running events should never stop, obviously...
179*30fdc8d8SChris Lattner 
180*30fdc8d8SChris Lattner 
181*30fdc8d8SChris Lattner     bool should_stop = false;
182*30fdc8d8SChris Lattner     m_process->UpdateThreadListIfNeeded();
183*30fdc8d8SChris Lattner 
184*30fdc8d8SChris Lattner     collection::iterator pos, end = m_threads.end();
185*30fdc8d8SChris Lattner 
186*30fdc8d8SChris Lattner     // Run through the threads and ask whether we should stop.  Don't ask
187*30fdc8d8SChris Lattner     // suspended threads, however, it makes more sense for them to preserve their
188*30fdc8d8SChris Lattner     // state across the times the process runs but they don't get a chance to.
189*30fdc8d8SChris Lattner     for (pos = m_threads.begin(); pos != end; ++pos)
190*30fdc8d8SChris Lattner     {
191*30fdc8d8SChris Lattner         ThreadSP thread_sp(*pos);
192*30fdc8d8SChris Lattner         if ((thread_sp->ThreadStoppedForAReason())
193*30fdc8d8SChris Lattner             && (thread_sp->GetResumeState () != eStateSuspended))
194*30fdc8d8SChris Lattner         {
195*30fdc8d8SChris Lattner             should_stop |= thread_sp->ShouldStop(event_ptr);
196*30fdc8d8SChris Lattner         }
197*30fdc8d8SChris Lattner     }
198*30fdc8d8SChris Lattner     if (should_stop)
199*30fdc8d8SChris Lattner     {
200*30fdc8d8SChris Lattner         for (pos = m_threads.begin(); pos != end; ++pos)
201*30fdc8d8SChris Lattner         {
202*30fdc8d8SChris Lattner             ThreadSP thread_sp(*pos);
203*30fdc8d8SChris Lattner             thread_sp->WillStop ();
204*30fdc8d8SChris Lattner         }
205*30fdc8d8SChris Lattner     }
206*30fdc8d8SChris Lattner 
207*30fdc8d8SChris Lattner     return should_stop;
208*30fdc8d8SChris Lattner }
209*30fdc8d8SChris Lattner 
210*30fdc8d8SChris Lattner Vote
211*30fdc8d8SChris Lattner ThreadList::ShouldReportStop (Event *event_ptr)
212*30fdc8d8SChris Lattner {
213*30fdc8d8SChris Lattner     Vote result = eVoteNoOpinion;
214*30fdc8d8SChris Lattner     m_process->UpdateThreadListIfNeeded();
215*30fdc8d8SChris Lattner     collection::iterator pos, end = m_threads.end();
216*30fdc8d8SChris Lattner 
217*30fdc8d8SChris Lattner     // Run through the threads and ask whether we should report this event.
218*30fdc8d8SChris Lattner     // For stopping, a YES vote wins over everything.  A NO vote wins over NO opinion.
219*30fdc8d8SChris Lattner     for (pos = m_threads.begin(); pos != end; ++pos)
220*30fdc8d8SChris Lattner     {
221*30fdc8d8SChris Lattner         ThreadSP thread_sp(*pos);
222*30fdc8d8SChris Lattner         if (thread_sp->ThreadStoppedForAReason() && (thread_sp->GetResumeState () != eStateSuspended))
223*30fdc8d8SChris Lattner         {
224*30fdc8d8SChris Lattner             switch (thread_sp->ShouldReportStop (event_ptr))
225*30fdc8d8SChris Lattner             {
226*30fdc8d8SChris Lattner                 case eVoteNoOpinion:
227*30fdc8d8SChris Lattner                     continue;
228*30fdc8d8SChris Lattner                 case eVoteYes:
229*30fdc8d8SChris Lattner                     result = eVoteYes;
230*30fdc8d8SChris Lattner                     break;
231*30fdc8d8SChris Lattner                 case eVoteNo:
232*30fdc8d8SChris Lattner                     if (result == eVoteNoOpinion)
233*30fdc8d8SChris Lattner                         result = eVoteNo;
234*30fdc8d8SChris Lattner                     break;
235*30fdc8d8SChris Lattner             }
236*30fdc8d8SChris Lattner         }
237*30fdc8d8SChris Lattner     }
238*30fdc8d8SChris Lattner     return result;
239*30fdc8d8SChris Lattner }
240*30fdc8d8SChris Lattner 
241*30fdc8d8SChris Lattner Vote
242*30fdc8d8SChris Lattner ThreadList::ShouldReportRun (Event *event_ptr)
243*30fdc8d8SChris Lattner {
244*30fdc8d8SChris Lattner     Vote result = eVoteNoOpinion;
245*30fdc8d8SChris Lattner     m_process->UpdateThreadListIfNeeded();
246*30fdc8d8SChris Lattner     collection::iterator pos, end = m_threads.end();
247*30fdc8d8SChris Lattner 
248*30fdc8d8SChris Lattner     // Run through the threads and ask whether we should report this event.
249*30fdc8d8SChris Lattner     // The rule is NO vote wins over everything, a YES vote wins over no opinion.
250*30fdc8d8SChris Lattner 
251*30fdc8d8SChris Lattner     for (pos = m_threads.begin(); pos != end; ++pos)
252*30fdc8d8SChris Lattner     {
253*30fdc8d8SChris Lattner         ThreadSP thread_sp(*pos);
254*30fdc8d8SChris Lattner         if (thread_sp->GetResumeState () != eStateSuspended)
255*30fdc8d8SChris Lattner 
256*30fdc8d8SChris Lattner         switch (thread_sp->ShouldReportRun (event_ptr))
257*30fdc8d8SChris Lattner         {
258*30fdc8d8SChris Lattner             case eVoteNoOpinion:
259*30fdc8d8SChris Lattner                 continue;
260*30fdc8d8SChris Lattner             case eVoteYes:
261*30fdc8d8SChris Lattner                 if (result == eVoteNoOpinion)
262*30fdc8d8SChris Lattner                     result = eVoteYes;
263*30fdc8d8SChris Lattner                 break;
264*30fdc8d8SChris Lattner             case eVoteNo:
265*30fdc8d8SChris Lattner                 result = eVoteNo;
266*30fdc8d8SChris Lattner                 break;
267*30fdc8d8SChris Lattner         }
268*30fdc8d8SChris Lattner     }
269*30fdc8d8SChris Lattner     return result;
270*30fdc8d8SChris Lattner }
271*30fdc8d8SChris Lattner 
272*30fdc8d8SChris Lattner void
273*30fdc8d8SChris Lattner ThreadList::Clear()
274*30fdc8d8SChris Lattner {
275*30fdc8d8SChris Lattner     m_stop_id = 0;
276*30fdc8d8SChris Lattner     m_threads.clear();
277*30fdc8d8SChris Lattner     m_current_tid = LLDB_INVALID_THREAD_ID;
278*30fdc8d8SChris Lattner }
279*30fdc8d8SChris Lattner 
280*30fdc8d8SChris Lattner void
281*30fdc8d8SChris Lattner ThreadList::RefreshStateAfterStop ()
282*30fdc8d8SChris Lattner {
283*30fdc8d8SChris Lattner     Mutex::Locker locker(m_threads_mutex);
284*30fdc8d8SChris Lattner 
285*30fdc8d8SChris Lattner     m_process->UpdateThreadListIfNeeded();
286*30fdc8d8SChris Lattner 
287*30fdc8d8SChris Lattner     collection::iterator pos, end = m_threads.end();
288*30fdc8d8SChris Lattner     for (pos = m_threads.begin(); pos != end; ++pos)
289*30fdc8d8SChris Lattner         (*pos)->RefreshStateAfterStop ();
290*30fdc8d8SChris Lattner }
291*30fdc8d8SChris Lattner 
292*30fdc8d8SChris Lattner void
293*30fdc8d8SChris Lattner ThreadList::DiscardThreadPlans ()
294*30fdc8d8SChris Lattner {
295*30fdc8d8SChris Lattner     // You don't need to update the thread list here, because only threads
296*30fdc8d8SChris Lattner     // that you currently know about have any thread plans.
297*30fdc8d8SChris Lattner     Mutex::Locker locker(m_threads_mutex);
298*30fdc8d8SChris Lattner 
299*30fdc8d8SChris Lattner     collection::iterator pos, end = m_threads.end();
300*30fdc8d8SChris Lattner     for (pos = m_threads.begin(); pos != end; ++pos)
301*30fdc8d8SChris Lattner         (*pos)->DiscardThreadPlans (true);
302*30fdc8d8SChris Lattner 
303*30fdc8d8SChris Lattner }
304*30fdc8d8SChris Lattner 
305*30fdc8d8SChris Lattner bool
306*30fdc8d8SChris Lattner ThreadList::WillResume ()
307*30fdc8d8SChris Lattner {
308*30fdc8d8SChris Lattner     // Run through the threads and perform their momentary actions.
309*30fdc8d8SChris Lattner     // But we only do this for threads that are running, user suspended
310*30fdc8d8SChris Lattner     // threads stay where they are.
311*30fdc8d8SChris Lattner     bool success = true;
312*30fdc8d8SChris Lattner 
313*30fdc8d8SChris Lattner     Mutex::Locker locker(m_threads_mutex);
314*30fdc8d8SChris Lattner     m_process->UpdateThreadListIfNeeded();
315*30fdc8d8SChris Lattner 
316*30fdc8d8SChris Lattner     collection::iterator pos, end = m_threads.end();
317*30fdc8d8SChris Lattner 
318*30fdc8d8SChris Lattner     // Give all the threads a last chance to set up their state before we
319*30fdc8d8SChris Lattner     // negotiate who is actually going to get a chance to run...
320*30fdc8d8SChris Lattner 
321*30fdc8d8SChris Lattner     for (pos = m_threads.begin(); pos != end; ++pos)
322*30fdc8d8SChris Lattner         (*pos)->SetupForResume ();
323*30fdc8d8SChris Lattner 
324*30fdc8d8SChris Lattner     // Now go through the threads and see if any thread wants to run just itself.
325*30fdc8d8SChris Lattner     // if so then pick one and run it.
326*30fdc8d8SChris Lattner     ThreadList run_me_only_list (m_process);
327*30fdc8d8SChris Lattner 
328*30fdc8d8SChris Lattner     run_me_only_list.SetStopID(m_process->GetStopID());
329*30fdc8d8SChris Lattner 
330*30fdc8d8SChris Lattner     ThreadSP immediate_thread_sp;
331*30fdc8d8SChris Lattner     bool run_only_current_thread = false;
332*30fdc8d8SChris Lattner 
333*30fdc8d8SChris Lattner     for (pos = m_threads.begin(); pos != end; ++pos)
334*30fdc8d8SChris Lattner     {
335*30fdc8d8SChris Lattner         ThreadSP thread_sp(*pos);
336*30fdc8d8SChris Lattner         if (thread_sp->GetCurrentPlan()->IsImmediate())
337*30fdc8d8SChris Lattner         {
338*30fdc8d8SChris Lattner             // We first do all the immediate plans, so if we find one, set
339*30fdc8d8SChris Lattner             // immediate_thread_sp and break out, and we'll pick it up first thing
340*30fdc8d8SChris Lattner             // when we're negotiating which threads get to run.
341*30fdc8d8SChris Lattner             immediate_thread_sp = thread_sp;
342*30fdc8d8SChris Lattner             break;
343*30fdc8d8SChris Lattner         }
344*30fdc8d8SChris Lattner         else if (thread_sp->GetResumeState() != eStateSuspended &&
345*30fdc8d8SChris Lattner                  thread_sp->GetCurrentPlan()->StopOthers())
346*30fdc8d8SChris Lattner         {
347*30fdc8d8SChris Lattner             // You can't say "stop others" and also want yourself to be suspended.
348*30fdc8d8SChris Lattner             assert (thread_sp->GetCurrentPlan()->RunState() != eStateSuspended);
349*30fdc8d8SChris Lattner 
350*30fdc8d8SChris Lattner             if (thread_sp == GetCurrentThread())
351*30fdc8d8SChris Lattner             {
352*30fdc8d8SChris Lattner                 run_only_current_thread = true;
353*30fdc8d8SChris Lattner                 run_me_only_list.Clear();
354*30fdc8d8SChris Lattner                 run_me_only_list.AddThread (thread_sp);
355*30fdc8d8SChris Lattner                 break;
356*30fdc8d8SChris Lattner             }
357*30fdc8d8SChris Lattner 
358*30fdc8d8SChris Lattner             run_me_only_list.AddThread (thread_sp);
359*30fdc8d8SChris Lattner         }
360*30fdc8d8SChris Lattner 
361*30fdc8d8SChris Lattner     }
362*30fdc8d8SChris Lattner 
363*30fdc8d8SChris Lattner     if (immediate_thread_sp)
364*30fdc8d8SChris Lattner     {
365*30fdc8d8SChris Lattner         for (pos = m_threads.begin(); pos != end; ++pos)
366*30fdc8d8SChris Lattner         {
367*30fdc8d8SChris Lattner             ThreadSP thread_sp(*pos);
368*30fdc8d8SChris Lattner             if (thread_sp.get() == immediate_thread_sp.get())
369*30fdc8d8SChris Lattner                 thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState());
370*30fdc8d8SChris Lattner             else
371*30fdc8d8SChris Lattner                 thread_sp->WillResume (eStateSuspended);
372*30fdc8d8SChris Lattner         }
373*30fdc8d8SChris Lattner     }
374*30fdc8d8SChris Lattner     else if (run_me_only_list.GetSize (false) == 0)
375*30fdc8d8SChris Lattner     {
376*30fdc8d8SChris Lattner         // Everybody runs as they wish:
377*30fdc8d8SChris Lattner         for (pos = m_threads.begin(); pos != end; ++pos)
378*30fdc8d8SChris Lattner         {
379*30fdc8d8SChris Lattner             ThreadSP thread_sp(*pos);
380*30fdc8d8SChris Lattner             thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState());
381*30fdc8d8SChris Lattner         }
382*30fdc8d8SChris Lattner     }
383*30fdc8d8SChris Lattner     else
384*30fdc8d8SChris Lattner     {
385*30fdc8d8SChris Lattner         ThreadSP thread_to_run;
386*30fdc8d8SChris Lattner 
387*30fdc8d8SChris Lattner         if (run_only_current_thread)
388*30fdc8d8SChris Lattner         {
389*30fdc8d8SChris Lattner             thread_to_run = GetCurrentThread();
390*30fdc8d8SChris Lattner         }
391*30fdc8d8SChris Lattner         else if (run_me_only_list.GetSize (false) == 1)
392*30fdc8d8SChris Lattner         {
393*30fdc8d8SChris Lattner             thread_to_run = run_me_only_list.GetThreadAtIndex (0);
394*30fdc8d8SChris Lattner         }
395*30fdc8d8SChris Lattner         else
396*30fdc8d8SChris Lattner         {
397*30fdc8d8SChris Lattner             int random_thread = (int)
398*30fdc8d8SChris Lattner                     ((run_me_only_list.GetSize (false) * (double) rand ()) / (RAND_MAX + 1.0));
399*30fdc8d8SChris Lattner             thread_to_run = run_me_only_list.GetThreadAtIndex (random_thread);
400*30fdc8d8SChris Lattner         }
401*30fdc8d8SChris Lattner 
402*30fdc8d8SChris Lattner         for (pos = m_threads.begin(); pos != end; ++pos)
403*30fdc8d8SChris Lattner         {
404*30fdc8d8SChris Lattner             ThreadSP thread_sp(*pos);
405*30fdc8d8SChris Lattner             if (thread_sp == thread_to_run)
406*30fdc8d8SChris Lattner                 thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState());
407*30fdc8d8SChris Lattner             else
408*30fdc8d8SChris Lattner                 thread_sp->WillResume (eStateSuspended);
409*30fdc8d8SChris Lattner         }
410*30fdc8d8SChris Lattner     }
411*30fdc8d8SChris Lattner 
412*30fdc8d8SChris Lattner     return success;
413*30fdc8d8SChris Lattner }
414*30fdc8d8SChris Lattner 
415*30fdc8d8SChris Lattner void
416*30fdc8d8SChris Lattner ThreadList::DidResume ()
417*30fdc8d8SChris Lattner {
418*30fdc8d8SChris Lattner     collection::iterator pos, end = m_threads.end();
419*30fdc8d8SChris Lattner     for (pos = m_threads.begin(); pos != end; ++pos)
420*30fdc8d8SChris Lattner     {
421*30fdc8d8SChris Lattner         // Don't clear out threads that aren't going to get a chance to run, rather
422*30fdc8d8SChris Lattner         // leave their state for the next time around.
423*30fdc8d8SChris Lattner         ThreadSP thread_sp(*pos);
424*30fdc8d8SChris Lattner         if (thread_sp->GetResumeState() != eStateSuspended)
425*30fdc8d8SChris Lattner             thread_sp->DidResume ();
426*30fdc8d8SChris Lattner     }
427*30fdc8d8SChris Lattner }
428*30fdc8d8SChris Lattner 
429*30fdc8d8SChris Lattner ThreadSP
430*30fdc8d8SChris Lattner ThreadList::GetCurrentThread ()
431*30fdc8d8SChris Lattner {
432*30fdc8d8SChris Lattner     Mutex::Locker locker(m_threads_mutex);
433*30fdc8d8SChris Lattner     return FindThreadByID(m_current_tid);
434*30fdc8d8SChris Lattner }
435*30fdc8d8SChris Lattner 
436*30fdc8d8SChris Lattner bool
437*30fdc8d8SChris Lattner ThreadList::SetCurrentThreadByID (lldb::tid_t tid)
438*30fdc8d8SChris Lattner {
439*30fdc8d8SChris Lattner     Mutex::Locker locker(m_threads_mutex);
440*30fdc8d8SChris Lattner     if  (FindThreadByID(tid).get())
441*30fdc8d8SChris Lattner         m_current_tid = tid;
442*30fdc8d8SChris Lattner     else
443*30fdc8d8SChris Lattner         m_current_tid = LLDB_INVALID_THREAD_ID;
444*30fdc8d8SChris Lattner 
445*30fdc8d8SChris Lattner     return m_current_tid != LLDB_INVALID_THREAD_ID;
446*30fdc8d8SChris Lattner }
447*30fdc8d8SChris Lattner 
448*30fdc8d8SChris Lattner bool
449*30fdc8d8SChris Lattner ThreadList::SetCurrentThreadByIndexID (uint32_t index_id)
450*30fdc8d8SChris Lattner {
451*30fdc8d8SChris Lattner     Mutex::Locker locker(m_threads_mutex);
452*30fdc8d8SChris Lattner     ThreadSP thread_sp (FindThreadByIndexID(index_id));
453*30fdc8d8SChris Lattner     if  (thread_sp.get())
454*30fdc8d8SChris Lattner         m_current_tid = thread_sp->GetID();
455*30fdc8d8SChris Lattner     else
456*30fdc8d8SChris Lattner         m_current_tid = LLDB_INVALID_THREAD_ID;
457*30fdc8d8SChris Lattner 
458*30fdc8d8SChris Lattner     return m_current_tid != LLDB_INVALID_THREAD_ID;
459*30fdc8d8SChris Lattner }
460*30fdc8d8SChris Lattner 
461