blob: 4971d6c963f6490dd146fa3df8dafe57ce1119dc [file] [log] [blame]
Chris Lattner30fdc8d2010-06-08 16:52:24 +00001//===-- 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
Greg Clayton2cad65a2010-09-03 17:10:42 +000013#include "lldb/Core/Log.h"
14#include "lldb/Target/RegisterContext.h"
Chris Lattner30fdc8d2010-06-08 16:52:24 +000015#include "lldb/Target/ThreadList.h"
16#include "lldb/Target/Thread.h"
17#include "lldb/Target/ThreadPlan.h"
18#include "lldb/Target/Process.h"
19
20using namespace lldb;
21using namespace lldb_private;
22
23ThreadList::ThreadList (Process *process) :
24 m_process (process),
25 m_stop_id (0),
26 m_threads(),
Jim Ingham2976d002010-08-26 21:32:51 +000027 m_selected_tid (LLDB_INVALID_THREAD_ID)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000028{
29}
30
31ThreadList::ThreadList (const ThreadList &rhs) :
Andrew Kaylorba4e61d2013-05-07 18:35:34 +000032 m_process (rhs.m_process),
33 m_stop_id (rhs.m_stop_id),
Chris Lattner30fdc8d2010-06-08 16:52:24 +000034 m_threads (),
Jim Ingham2976d002010-08-26 21:32:51 +000035 m_selected_tid ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +000036{
37 // Use the assignment operator since it uses the mutex
38 *this = rhs;
39}
40
41const ThreadList&
42ThreadList::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
Andrew Kaylorba4e61d2013-05-07 18:35:34 +000048 Mutex::Locker locker(GetMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000049 m_process = rhs.m_process;
50 m_stop_id = rhs.m_stop_id;
51 m_threads = rhs.m_threads;
Jim Ingham2976d002010-08-26 21:32:51 +000052 m_selected_tid = rhs.m_selected_tid;
Chris Lattner30fdc8d2010-06-08 16:52:24 +000053 }
54 return *this;
55}
56
57
58ThreadList::~ThreadList()
59{
Greg Claytonac358da2013-03-28 18:33:53 +000060 // Clear the thread list. Clear will take the mutex lock
61 // which will ensure that if anyone is using the list
62 // they won't get it removed while using it.
63 Clear();
Chris Lattner30fdc8d2010-06-08 16:52:24 +000064}
65
66
67uint32_t
68ThreadList::GetStopID () const
69{
70 return m_stop_id;
71}
72
73void
74ThreadList::SetStopID (uint32_t stop_id)
75{
76 m_stop_id = stop_id;
77}
78
79
80void
Greg Claytonc3776bf2012-02-09 06:16:32 +000081ThreadList::AddThread (const ThreadSP &thread_sp)
Chris Lattner30fdc8d2010-06-08 16:52:24 +000082{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +000083 Mutex::Locker locker(GetMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000084 m_threads.push_back(thread_sp);
85}
86
87uint32_t
88ThreadList::GetSize (bool can_update)
89{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +000090 Mutex::Locker locker(GetMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +000091 if (can_update)
92 m_process->UpdateThreadListIfNeeded();
93 return m_threads.size();
94}
95
96ThreadSP
97ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update)
98{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +000099 Mutex::Locker locker(GetMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000100 if (can_update)
101 m_process->UpdateThreadListIfNeeded();
102
103 ThreadSP thread_sp;
104 if (idx < m_threads.size())
105 thread_sp = m_threads[idx];
106 return thread_sp;
107}
108
109ThreadSP
110ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update)
111{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000112 Mutex::Locker locker(GetMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000113
114 if (can_update)
115 m_process->UpdateThreadListIfNeeded();
116
117 ThreadSP thread_sp;
118 uint32_t idx = 0;
119 const uint32_t num_threads = m_threads.size();
120 for (idx = 0; idx < num_threads; ++idx)
121 {
122 if (m_threads[idx]->GetID() == tid)
123 {
124 thread_sp = m_threads[idx];
125 break;
126 }
127 }
128 return thread_sp;
129}
130
131ThreadSP
Greg Clayton160c9d82013-05-01 21:54:04 +0000132ThreadList::FindThreadByProtocolID (lldb::tid_t tid, bool can_update)
133{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000134 Mutex::Locker locker(GetMutex());
Greg Clayton160c9d82013-05-01 21:54:04 +0000135
136 if (can_update)
137 m_process->UpdateThreadListIfNeeded();
138
139 ThreadSP thread_sp;
140 uint32_t idx = 0;
141 const uint32_t num_threads = m_threads.size();
142 for (idx = 0; idx < num_threads; ++idx)
143 {
144 if (m_threads[idx]->GetProtocolID() == tid)
145 {
146 thread_sp = m_threads[idx];
147 break;
148 }
149 }
150 return thread_sp;
151}
152
153
154ThreadSP
Han Ming Ongc2c423e2013-01-08 22:10:01 +0000155ThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update)
156{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000157 Mutex::Locker locker(GetMutex());
Han Ming Ongc2c423e2013-01-08 22:10:01 +0000158
159 if (can_update)
160 m_process->UpdateThreadListIfNeeded();
161
162 ThreadSP thread_sp;
163 uint32_t idx = 0;
164 const uint32_t num_threads = m_threads.size();
165 for (idx = 0; idx < num_threads; ++idx)
166 {
167 if (m_threads[idx]->GetID() == tid)
168 {
169 thread_sp = m_threads[idx];
170 m_threads.erase(m_threads.begin()+idx);
171 break;
172 }
173 }
174 return thread_sp;
175}
176
177ThreadSP
Greg Clayton160c9d82013-05-01 21:54:04 +0000178ThreadList::RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update)
179{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000180 Mutex::Locker locker(GetMutex());
Greg Clayton160c9d82013-05-01 21:54:04 +0000181
182 if (can_update)
183 m_process->UpdateThreadListIfNeeded();
184
185 ThreadSP thread_sp;
186 uint32_t idx = 0;
187 const uint32_t num_threads = m_threads.size();
188 for (idx = 0; idx < num_threads; ++idx)
189 {
190 if (m_threads[idx]->GetProtocolID() == tid)
191 {
192 thread_sp = m_threads[idx];
193 m_threads.erase(m_threads.begin()+idx);
194 break;
195 }
196 }
197 return thread_sp;
198}
199
200ThreadSP
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000201ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr)
202{
203 ThreadSP thread_sp;
204 if (thread_ptr)
205 {
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000206 Mutex::Locker locker(GetMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000207
208 uint32_t idx = 0;
209 const uint32_t num_threads = m_threads.size();
210 for (idx = 0; idx < num_threads; ++idx)
211 {
212 if (m_threads[idx].get() == thread_ptr)
213 {
214 thread_sp = m_threads[idx];
215 break;
216 }
217 }
218 }
219 return thread_sp;
220}
221
222
223
224ThreadSP
225ThreadList::FindThreadByIndexID (uint32_t index_id, bool can_update)
226{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000227 Mutex::Locker locker(GetMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000228
229 if (can_update)
230 m_process->UpdateThreadListIfNeeded();
231
232 ThreadSP thread_sp;
233 const uint32_t num_threads = m_threads.size();
234 for (uint32_t idx = 0; idx < num_threads; ++idx)
235 {
236 if (m_threads[idx]->GetIndexID() == index_id)
237 {
238 thread_sp = m_threads[idx];
239 break;
240 }
241 }
242 return thread_sp;
243}
244
245bool
246ThreadList::ShouldStop (Event *event_ptr)
247{
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000248 // Running events should never stop, obviously...
249
Greg Clayton5160ce52013-03-27 23:08:40 +0000250 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000251
Jim Inghamb42f3af2012-11-15 22:44:04 +0000252 // The ShouldStop method of the threads can do a whole lot of work,
253 // running breakpoint commands & conditions, etc. So we don't want
254 // to keep the ThreadList locked the whole time we are doing this.
255 // FIXME: It is possible that running code could cause new threads
256 // to be created. If that happens we will miss asking them whether
257 // then should stop. This is not a big deal, since we haven't had
258 // a chance to hang any interesting operations on those threads yet.
259
260 collection threads_copy;
261 {
262 // Scope for locker
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000263 Mutex::Locker locker(GetMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000264
Jim Inghamb42f3af2012-11-15 22:44:04 +0000265 m_process->UpdateThreadListIfNeeded();
266 threads_copy = m_threads;
267 }
268
269 collection::iterator pos, end = threads_copy.end();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000270
Greg Clayton2cad65a2010-09-03 17:10:42 +0000271 if (log)
Jim Ingham10c4b242011-10-15 00:23:43 +0000272 {
273 log->PutCString("");
Daniel Malead01b2952012-11-29 21:49:15 +0000274 log->Printf ("ThreadList::%s: %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size());
Jim Ingham10c4b242011-10-15 00:23:43 +0000275 }
Greg Clayton2cad65a2010-09-03 17:10:42 +0000276
Jim Inghama0079042013-03-21 21:46:56 +0000277 bool did_anybody_stop_for_a_reason = false;
Jim Ingham7bc34652013-04-16 22:53:24 +0000278 bool should_stop = false;
279
280 // Now we run through all the threads and get their stop info's. We want to make sure to do this first before
281 // we start running the ShouldStop, because one thread's ShouldStop could destroy information (like deleting a
282 // thread specific breakpoint another thread had stopped at) which could lead us to compute the StopInfo incorrectly.
283 // We don't need to use it here, we just want to make sure it gets computed.
284
285 for (pos = threads_copy.begin(); pos != end; ++pos)
286 {
287 ThreadSP thread_sp(*pos);
288 thread_sp->GetStopInfo();
289 }
Jim Inghama0079042013-03-21 21:46:56 +0000290
Jim Inghamb42f3af2012-11-15 22:44:04 +0000291 for (pos = threads_copy.begin(); pos != end; ++pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000292 {
293 ThreadSP thread_sp(*pos);
Greg Clayton2cad65a2010-09-03 17:10:42 +0000294
Jim Inghama0079042013-03-21 21:46:56 +0000295 did_anybody_stop_for_a_reason |= thread_sp->ThreadStoppedForAReason();
296
Jim Ingham10c4b242011-10-15 00:23:43 +0000297 const bool thread_should_stop = thread_sp->ShouldStop(event_ptr);
Greg Clayton2cad65a2010-09-03 17:10:42 +0000298 if (thread_should_stop)
299 should_stop |= true;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000300 }
Jim Inghamb01e7422010-06-19 04:45:32 +0000301
Jim Inghama0079042013-03-21 21:46:56 +0000302 // We should never get a stop for which no thread had a stop reason, but sometimes we do see this -
303 // for instance when we first connect to a remote stub. In that case we should stop, since we can't figure out
304 // the right thing to do and stopping gives the user control over what to do in this instance.
305
306 if (!should_stop && !did_anybody_stop_for_a_reason)
307 {
308 should_stop = true;
309 if (log)
310 log->Printf ("ThreadList::%s we stopped but no threads had a stop reason, overriding should_stop and stopping.", __FUNCTION__);
311 }
312
Greg Clayton2cad65a2010-09-03 17:10:42 +0000313 if (log)
Jim Ingham10c4b242011-10-15 00:23:43 +0000314 log->Printf ("ThreadList::%s overall should_stop = %i", __FUNCTION__, should_stop);
Greg Clayton2cad65a2010-09-03 17:10:42 +0000315
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000316 if (should_stop)
317 {
Jim Inghamb42f3af2012-11-15 22:44:04 +0000318 for (pos = threads_copy.begin(); pos != end; ++pos)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000319 {
320 ThreadSP thread_sp(*pos);
321 thread_sp->WillStop ();
322 }
323 }
324
325 return should_stop;
326}
327
328Vote
329ThreadList::ShouldReportStop (Event *event_ptr)
330{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000331 Mutex::Locker locker(GetMutex());
Greg Clayton2cad65a2010-09-03 17:10:42 +0000332
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000333 Vote result = eVoteNoOpinion;
334 m_process->UpdateThreadListIfNeeded();
335 collection::iterator pos, end = m_threads.end();
336
Greg Clayton5160ce52013-03-27 23:08:40 +0000337 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Greg Clayton2cad65a2010-09-03 17:10:42 +0000338
339 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000340 log->Printf ("ThreadList::%s %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size());
Greg Clayton2cad65a2010-09-03 17:10:42 +0000341
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000342 // Run through the threads and ask whether we should report this event.
343 // For stopping, a YES vote wins over everything. A NO vote wins over NO opinion.
344 for (pos = m_threads.begin(); pos != end; ++pos)
345 {
346 ThreadSP thread_sp(*pos);
Jim Ingham92087d82012-01-31 23:09:20 +0000347 const Vote vote = thread_sp->ShouldReportStop (event_ptr);
348 switch (vote)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000349 {
Jim Ingham92087d82012-01-31 23:09:20 +0000350 case eVoteNoOpinion:
351 continue;
352
353 case eVoteYes:
354 result = eVoteYes;
355 break;
356
357 case eVoteNo:
358 if (result == eVoteNoOpinion)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000359 {
Jim Ingham92087d82012-01-31 23:09:20 +0000360 result = eVoteNo;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000361 }
Jim Ingham92087d82012-01-31 23:09:20 +0000362 else
363 {
364 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000365 log->Printf ("ThreadList::%s thread 0x%4.4" PRIx64 ": voted %s, but lost out because result was %s",
Jim Ingham92087d82012-01-31 23:09:20 +0000366 __FUNCTION__,
367 thread_sp->GetID (),
368 GetVoteAsCString (vote),
369 GetVoteAsCString (result));
370 }
371 break;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000372 }
373 }
Greg Clayton2cad65a2010-09-03 17:10:42 +0000374 if (log)
Jim Ingham10c4b242011-10-15 00:23:43 +0000375 log->Printf ("ThreadList::%s returning %s", __FUNCTION__, GetVoteAsCString (result));
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000376 return result;
377}
378
Jim Ingham221d51c2013-05-08 00:35:16 +0000379void
380ThreadList::SetShouldReportStop (Vote vote)
381{
382 Mutex::Locker locker(GetMutex());
383 m_process->UpdateThreadListIfNeeded();
384 collection::iterator pos, end = m_threads.end();
385 for (pos = m_threads.begin(); pos != end; ++pos)
386 {
387 ThreadSP thread_sp(*pos);
388 thread_sp->SetShouldReportStop (vote);
389 }
390}
391
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000392Vote
393ThreadList::ShouldReportRun (Event *event_ptr)
394{
Greg Clayton2cad65a2010-09-03 17:10:42 +0000395
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000396 Mutex::Locker locker(GetMutex());
Greg Clayton2cad65a2010-09-03 17:10:42 +0000397
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000398 Vote result = eVoteNoOpinion;
399 m_process->UpdateThreadListIfNeeded();
400 collection::iterator pos, end = m_threads.end();
401
402 // Run through the threads and ask whether we should report this event.
403 // The rule is NO vote wins over everything, a YES vote wins over no opinion.
404
Greg Clayton5160ce52013-03-27 23:08:40 +0000405 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Jim Inghamce579832011-01-24 04:11:25 +0000406
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000407 for (pos = m_threads.begin(); pos != end; ++pos)
408 {
Jim Inghamce579832011-01-24 04:11:25 +0000409 if ((*pos)->GetResumeState () != eStateSuspended)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000410 {
Jim Inghamce579832011-01-24 04:11:25 +0000411 switch ((*pos)->ShouldReportRun (event_ptr))
412 {
413 case eVoteNoOpinion:
414 continue;
415 case eVoteYes:
416 if (result == eVoteNoOpinion)
417 result = eVoteYes;
418 break;
419 case eVoteNo:
Greg Claytonabcbc8a2011-01-24 05:36:47 +0000420 if (log)
Daniel Malead01b2952012-11-29 21:49:15 +0000421 log->Printf ("ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64 ") says don't report.",
Greg Claytonabcbc8a2011-01-24 05:36:47 +0000422 (*pos)->GetIndexID(),
423 (*pos)->GetID());
Jim Inghamce579832011-01-24 04:11:25 +0000424 result = eVoteNo;
425 break;
426 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000427 }
428 }
429 return result;
430}
431
432void
433ThreadList::Clear()
434{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000435 Mutex::Locker locker(GetMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000436 m_stop_id = 0;
437 m_threads.clear();
Jim Ingham2976d002010-08-26 21:32:51 +0000438 m_selected_tid = LLDB_INVALID_THREAD_ID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000439}
440
441void
Greg Claytone1cd1be2012-01-29 20:56:30 +0000442ThreadList::Destroy()
443{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000444 Mutex::Locker locker(GetMutex());
Greg Claytone1cd1be2012-01-29 20:56:30 +0000445 const uint32_t num_threads = m_threads.size();
446 for (uint32_t idx = 0; idx < num_threads; ++idx)
447 {
448 m_threads[idx]->DestroyThread();
449 }
450}
451
452void
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000453ThreadList::RefreshStateAfterStop ()
454{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000455 Mutex::Locker locker(GetMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000456
457 m_process->UpdateThreadListIfNeeded();
Jim Ingham1c823b42011-01-22 01:33:44 +0000458
Greg Clayton5160ce52013-03-27 23:08:40 +0000459 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Jim Ingham10c4b242011-10-15 00:23:43 +0000460 if (log && log->GetVerbose())
Jim Ingham1c823b42011-01-22 01:33:44 +0000461 log->Printf ("Turning off notification of new threads while single stepping a thread.");
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000462
463 collection::iterator pos, end = m_threads.end();
464 for (pos = m_threads.begin(); pos != end; ++pos)
465 (*pos)->RefreshStateAfterStop ();
466}
467
468void
469ThreadList::DiscardThreadPlans ()
470{
471 // You don't need to update the thread list here, because only threads
472 // that you currently know about have any thread plans.
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000473 Mutex::Locker locker(GetMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000474
475 collection::iterator pos, end = m_threads.end();
476 for (pos = m_threads.begin(); pos != end; ++pos)
477 (*pos)->DiscardThreadPlans (true);
478
479}
480
481bool
482ThreadList::WillResume ()
483{
484 // Run through the threads and perform their momentary actions.
485 // But we only do this for threads that are running, user suspended
486 // threads stay where they are.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000487
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000488 Mutex::Locker locker(GetMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000489 m_process->UpdateThreadListIfNeeded();
490
491 collection::iterator pos, end = m_threads.end();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000492
Jim Inghama3241c12010-07-14 02:27:20 +0000493 // See if any thread wants to run stopping others. If it does, then we won't
494 // setup the other threads for resume, since they aren't going to get a chance
495 // to run. This is necessary because the SetupForResume might add "StopOthers"
496 // plans which would then get to be part of the who-gets-to-run negotiation, but
497 // they're coming in after the fact, and the threads that are already set up should
498 // take priority.
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000499
Jim Inghama3241c12010-07-14 02:27:20 +0000500 bool wants_solo_run = false;
501
502 for (pos = m_threads.begin(); pos != end; ++pos)
503 {
504 if ((*pos)->GetResumeState() != eStateSuspended &&
505 (*pos)->GetCurrentPlan()->StopOthers())
506 {
507 wants_solo_run = true;
508 break;
509 }
510 }
511
Jim Ingham1c823b42011-01-22 01:33:44 +0000512 if (wants_solo_run)
513 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000514 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Jim Ingham10c4b242011-10-15 00:23:43 +0000515 if (log && log->GetVerbose())
Jim Ingham1c823b42011-01-22 01:33:44 +0000516 log->Printf ("Turning on notification of new threads while single stepping a thread.");
517 m_process->StartNoticingNewThreads();
518 }
519 else
520 {
Greg Clayton5160ce52013-03-27 23:08:40 +0000521 Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
Jim Ingham10c4b242011-10-15 00:23:43 +0000522 if (log && log->GetVerbose())
Jim Ingham1c823b42011-01-22 01:33:44 +0000523 log->Printf ("Turning off notification of new threads while single stepping a thread.");
524 m_process->StopNoticingNewThreads();
525 }
Jim Inghama3241c12010-07-14 02:27:20 +0000526
527 // Give all the threads that are likely to run a last chance to set up their state before we
528 // negotiate who is actually going to get a chance to run...
529 // Don't set to resume suspended threads, and if any thread wanted to stop others, only
530 // call setup on the threads that request StopOthers...
531
532 for (pos = m_threads.begin(); pos != end; ++pos)
533 {
534 if ((*pos)->GetResumeState() != eStateSuspended
535 && (!wants_solo_run || (*pos)->GetCurrentPlan()->StopOthers()))
536 {
537 (*pos)->SetupForResume ();
538 }
539 }
540
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000541 // Now go through the threads and see if any thread wants to run just itself.
542 // if so then pick one and run it.
Jim Inghama3241c12010-07-14 02:27:20 +0000543
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000544 ThreadList run_me_only_list (m_process);
545
546 run_me_only_list.SetStopID(m_process->GetStopID());
547
548 ThreadSP immediate_thread_sp;
549 bool run_only_current_thread = false;
550
551 for (pos = m_threads.begin(); pos != end; ++pos)
552 {
553 ThreadSP thread_sp(*pos);
Jim Inghamb15bfc72010-10-20 00:39:53 +0000554 if (thread_sp->GetResumeState() != eStateSuspended &&
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000555 thread_sp->GetCurrentPlan()->StopOthers())
556 {
557 // You can't say "stop others" and also want yourself to be suspended.
558 assert (thread_sp->GetCurrentPlan()->RunState() != eStateSuspended);
559
Jim Ingham2976d002010-08-26 21:32:51 +0000560 if (thread_sp == GetSelectedThread())
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000561 {
562 run_only_current_thread = true;
563 run_me_only_list.Clear();
564 run_me_only_list.AddThread (thread_sp);
565 break;
566 }
567
568 run_me_only_list.AddThread (thread_sp);
569 }
570
571 }
572
Jim Ingham513c6bb2012-09-01 01:02:41 +0000573 bool need_to_resume = true;
574
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000575 if (immediate_thread_sp)
576 {
577 for (pos = m_threads.begin(); pos != end; ++pos)
578 {
579 ThreadSP thread_sp(*pos);
580 if (thread_sp.get() == immediate_thread_sp.get())
Greg Clayton160c9d82013-05-01 21:54:04 +0000581 thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000582 else
Greg Clayton160c9d82013-05-01 21:54:04 +0000583 thread_sp->ShouldResume (eStateSuspended);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000584 }
585 }
586 else if (run_me_only_list.GetSize (false) == 0)
587 {
588 // Everybody runs as they wish:
589 for (pos = m_threads.begin(); pos != end; ++pos)
590 {
591 ThreadSP thread_sp(*pos);
Jim Inghamcb5d5a52012-05-31 20:47:56 +0000592 StateType run_state;
593 if (thread_sp->GetResumeState() != eStateSuspended)
594 run_state = thread_sp->GetCurrentPlan()->RunState();
595 else
596 run_state = eStateSuspended;
Greg Clayton160c9d82013-05-01 21:54:04 +0000597 if (!thread_sp->ShouldResume(run_state))
Jim Ingham513c6bb2012-09-01 01:02:41 +0000598 need_to_resume = false;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000599 }
600 }
601 else
602 {
603 ThreadSP thread_to_run;
604
605 if (run_only_current_thread)
606 {
Jim Ingham2976d002010-08-26 21:32:51 +0000607 thread_to_run = GetSelectedThread();
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000608 }
609 else if (run_me_only_list.GetSize (false) == 1)
610 {
611 thread_to_run = run_me_only_list.GetThreadAtIndex (0);
612 }
613 else
614 {
615 int random_thread = (int)
616 ((run_me_only_list.GetSize (false) * (double) rand ()) / (RAND_MAX + 1.0));
617 thread_to_run = run_me_only_list.GetThreadAtIndex (random_thread);
618 }
619
620 for (pos = m_threads.begin(); pos != end; ++pos)
621 {
622 ThreadSP thread_sp(*pos);
623 if (thread_sp == thread_to_run)
Jim Ingham513c6bb2012-09-01 01:02:41 +0000624 {
Greg Clayton160c9d82013-05-01 21:54:04 +0000625 if (!thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState()))
Jim Ingham513c6bb2012-09-01 01:02:41 +0000626 need_to_resume = false;
627 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000628 else
Greg Clayton160c9d82013-05-01 21:54:04 +0000629 thread_sp->ShouldResume (eStateSuspended);
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000630 }
631 }
632
Jim Ingham513c6bb2012-09-01 01:02:41 +0000633 return need_to_resume;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000634}
635
636void
637ThreadList::DidResume ()
638{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000639 Mutex::Locker locker(GetMutex());
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000640 collection::iterator pos, end = m_threads.end();
641 for (pos = m_threads.begin(); pos != end; ++pos)
642 {
643 // Don't clear out threads that aren't going to get a chance to run, rather
644 // leave their state for the next time around.
645 ThreadSP thread_sp(*pos);
646 if (thread_sp->GetResumeState() != eStateSuspended)
647 thread_sp->DidResume ();
648 }
649}
650
651ThreadSP
Jim Ingham2976d002010-08-26 21:32:51 +0000652ThreadList::GetSelectedThread ()
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000653{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000654 Mutex::Locker locker(GetMutex());
Johnny Chen943ddb72011-08-25 21:59:59 +0000655 ThreadSP thread_sp = FindThreadByID(m_selected_tid);
656 if (!thread_sp.get())
657 {
Jason Molenda354b9a62011-09-13 01:13:16 +0000658 if (m_threads.size() == 0)
659 return thread_sp;
Johnny Chen943ddb72011-08-25 21:59:59 +0000660 m_selected_tid = m_threads[0]->GetID();
661 thread_sp = m_threads[0];
662 }
663 return thread_sp;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000664}
665
666bool
Jim Inghamc3faa192012-12-11 02:31:48 +0000667ThreadList::SetSelectedThreadByID (lldb::tid_t tid, bool notify)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000668{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000669 Mutex::Locker locker(GetMutex());
Jim Inghamb7f6b2f2011-09-08 22:13:49 +0000670 ThreadSP selected_thread_sp(FindThreadByID(tid));
671 if (selected_thread_sp)
672 {
Jim Ingham2976d002010-08-26 21:32:51 +0000673 m_selected_tid = tid;
Jim Inghamb7f6b2f2011-09-08 22:13:49 +0000674 selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
675 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000676 else
Jim Ingham2976d002010-08-26 21:32:51 +0000677 m_selected_tid = LLDB_INVALID_THREAD_ID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000678
Jim Inghamc3faa192012-12-11 02:31:48 +0000679 if (notify)
680 NotifySelectedThreadChanged(m_selected_tid);
681
Jim Ingham2976d002010-08-26 21:32:51 +0000682 return m_selected_tid != LLDB_INVALID_THREAD_ID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000683}
684
685bool
Jim Inghamc3faa192012-12-11 02:31:48 +0000686ThreadList::SetSelectedThreadByIndexID (uint32_t index_id, bool notify)
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000687{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000688 Mutex::Locker locker(GetMutex());
Jim Inghamb7f6b2f2011-09-08 22:13:49 +0000689 ThreadSP selected_thread_sp (FindThreadByIndexID(index_id));
690 if (selected_thread_sp.get())
691 {
692 m_selected_tid = selected_thread_sp->GetID();
693 selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
694 }
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000695 else
Jim Ingham2976d002010-08-26 21:32:51 +0000696 m_selected_tid = LLDB_INVALID_THREAD_ID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000697
Jim Inghamc3faa192012-12-11 02:31:48 +0000698 if (notify)
699 NotifySelectedThreadChanged(m_selected_tid);
700
Jim Ingham2976d002010-08-26 21:32:51 +0000701 return m_selected_tid != LLDB_INVALID_THREAD_ID;
Chris Lattner30fdc8d2010-06-08 16:52:24 +0000702}
703
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000704void
Jim Inghamc3faa192012-12-11 02:31:48 +0000705ThreadList::NotifySelectedThreadChanged (lldb::tid_t tid)
706{
707 ThreadSP selected_thread_sp (FindThreadByID(tid));
708 if (selected_thread_sp->EventTypeHasListeners(Thread::eBroadcastBitThreadSelected))
709 selected_thread_sp->BroadcastEvent(Thread::eBroadcastBitThreadSelected,
710 new Thread::ThreadEventData(selected_thread_sp));
711}
712
713void
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000714ThreadList::Update (ThreadList &rhs)
715{
716 if (this != &rhs)
717 {
718 // Lock both mutexes to make sure neither side changes anyone on us
719 // while the assignement occurs
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000720 Mutex::Locker locker(GetMutex());
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000721 m_process = rhs.m_process;
722 m_stop_id = rhs.m_stop_id;
723 m_threads.swap(rhs.m_threads);
724 m_selected_tid = rhs.m_selected_tid;
Greg Claytone1cd1be2012-01-29 20:56:30 +0000725
726
727 // Now we look for threads that we are done with and
728 // make sure to clear them up as much as possible so
729 // anyone with a shared pointer will still have a reference,
730 // but the thread won't be of much use. Using std::weak_ptr
731 // for all backward references (such as a thread to a process)
732 // will eventually solve this issue for us, but for now, we
733 // need to work around the issue
734 collection::iterator rhs_pos, rhs_end = rhs.m_threads.end();
735 for (rhs_pos = rhs.m_threads.begin(); rhs_pos != rhs_end; ++rhs_pos)
736 {
737 const lldb::tid_t tid = (*rhs_pos)->GetID();
738 bool thread_is_alive = false;
739 const uint32_t num_threads = m_threads.size();
740 for (uint32_t idx = 0; idx < num_threads; ++idx)
741 {
742 if (m_threads[idx]->GetID() == tid)
743 {
744 thread_is_alive = true;
745 break;
746 }
747 }
748 if (!thread_is_alive)
749 (*rhs_pos)->DestroyThread();
750 }
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000751 }
752}
753
Greg Claytonfa559e52012-05-18 02:38:05 +0000754void
755ThreadList::Flush ()
756{
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000757 Mutex::Locker locker(GetMutex());
Greg Claytonfa559e52012-05-18 02:38:05 +0000758 collection::iterator pos, end = m_threads.end();
759 for (pos = m_threads.begin(); pos != end; ++pos)
760 (*pos)->Flush ();
761}
Greg Clayton56d9a1b2011-08-22 02:49:39 +0000762
Andrew Kaylorba4e61d2013-05-07 18:35:34 +0000763Mutex &
764ThreadList::GetMutex ()
765{
766 return m_process->m_thread_mutex;
767}
768