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