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