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