130fdc8d8SChris Lattner //===-- ThreadList.cpp ------------------------------------------*- C++ -*-===// 230fdc8d8SChris Lattner // 330fdc8d8SChris Lattner // The LLVM Compiler Infrastructure 430fdc8d8SChris Lattner // 530fdc8d8SChris Lattner // This file is distributed under the University of Illinois Open Source 630fdc8d8SChris Lattner // License. See LICENSE.TXT for details. 730fdc8d8SChris Lattner // 830fdc8d8SChris Lattner //===----------------------------------------------------------------------===// 930fdc8d8SChris Lattner #include <stdlib.h> 1030fdc8d8SChris Lattner 1130fdc8d8SChris Lattner #include <algorithm> 1230fdc8d8SChris Lattner 132cad65a5SGreg Clayton #include "lldb/Core/Log.h" 142cad65a5SGreg Clayton #include "lldb/Target/RegisterContext.h" 1530fdc8d8SChris Lattner #include "lldb/Target/ThreadList.h" 1630fdc8d8SChris Lattner #include "lldb/Target/Thread.h" 1730fdc8d8SChris Lattner #include "lldb/Target/ThreadPlan.h" 1830fdc8d8SChris Lattner #include "lldb/Target/Process.h" 1930fdc8d8SChris Lattner 2030fdc8d8SChris Lattner using namespace lldb; 2130fdc8d8SChris Lattner using namespace lldb_private; 2230fdc8d8SChris Lattner 2330fdc8d8SChris Lattner ThreadList::ThreadList (Process *process) : 2430fdc8d8SChris Lattner m_process (process), 2530fdc8d8SChris Lattner m_stop_id (0), 2630fdc8d8SChris Lattner m_threads(), 2730fdc8d8SChris Lattner m_threads_mutex (Mutex::eMutexTypeRecursive), 282976d00aSJim Ingham m_selected_tid (LLDB_INVALID_THREAD_ID) 2930fdc8d8SChris Lattner { 3030fdc8d8SChris Lattner } 3130fdc8d8SChris Lattner 3230fdc8d8SChris Lattner ThreadList::ThreadList (const ThreadList &rhs) : 3330fdc8d8SChris Lattner m_process (), 3430fdc8d8SChris Lattner m_stop_id (), 3530fdc8d8SChris Lattner m_threads (), 3630fdc8d8SChris Lattner m_threads_mutex (Mutex::eMutexTypeRecursive), 372976d00aSJim Ingham m_selected_tid () 3830fdc8d8SChris Lattner { 3930fdc8d8SChris Lattner // Use the assignment operator since it uses the mutex 4030fdc8d8SChris Lattner *this = rhs; 4130fdc8d8SChris Lattner } 4230fdc8d8SChris Lattner 4330fdc8d8SChris Lattner const ThreadList& 4430fdc8d8SChris Lattner ThreadList::operator = (const ThreadList& rhs) 4530fdc8d8SChris Lattner { 4630fdc8d8SChris Lattner if (this != &rhs) 4730fdc8d8SChris Lattner { 4830fdc8d8SChris Lattner // Lock both mutexes to make sure neither side changes anyone on us 4930fdc8d8SChris Lattner // while the assignement occurs 50b132097bSGreg Clayton Mutex::Locker locker_lhs(m_threads_mutex); 5130fdc8d8SChris Lattner Mutex::Locker locker_rhs(rhs.m_threads_mutex); 5230fdc8d8SChris Lattner m_process = rhs.m_process; 5330fdc8d8SChris Lattner m_stop_id = rhs.m_stop_id; 5430fdc8d8SChris Lattner m_threads = rhs.m_threads; 552976d00aSJim Ingham m_selected_tid = rhs.m_selected_tid; 5630fdc8d8SChris Lattner } 5730fdc8d8SChris Lattner return *this; 5830fdc8d8SChris Lattner } 5930fdc8d8SChris Lattner 6030fdc8d8SChris Lattner 6130fdc8d8SChris Lattner ThreadList::~ThreadList() 6230fdc8d8SChris Lattner { 6330fdc8d8SChris Lattner } 6430fdc8d8SChris Lattner 6530fdc8d8SChris Lattner 6630fdc8d8SChris Lattner uint32_t 6730fdc8d8SChris Lattner ThreadList::GetStopID () const 6830fdc8d8SChris Lattner { 6930fdc8d8SChris Lattner return m_stop_id; 7030fdc8d8SChris Lattner } 7130fdc8d8SChris Lattner 7230fdc8d8SChris Lattner void 7330fdc8d8SChris Lattner ThreadList::SetStopID (uint32_t stop_id) 7430fdc8d8SChris Lattner { 7530fdc8d8SChris Lattner m_stop_id = stop_id; 7630fdc8d8SChris Lattner } 7730fdc8d8SChris Lattner 7830fdc8d8SChris Lattner 7930fdc8d8SChris Lattner void 8030fdc8d8SChris Lattner ThreadList::AddThread (ThreadSP &thread_sp) 8130fdc8d8SChris Lattner { 8230fdc8d8SChris Lattner Mutex::Locker locker(m_threads_mutex); 8330fdc8d8SChris Lattner m_threads.push_back(thread_sp); 8430fdc8d8SChris Lattner } 8530fdc8d8SChris Lattner 8630fdc8d8SChris Lattner uint32_t 8730fdc8d8SChris Lattner ThreadList::GetSize (bool can_update) 8830fdc8d8SChris Lattner { 8930fdc8d8SChris Lattner Mutex::Locker locker(m_threads_mutex); 9030fdc8d8SChris Lattner if (can_update) 9130fdc8d8SChris Lattner m_process->UpdateThreadListIfNeeded(); 9230fdc8d8SChris Lattner return m_threads.size(); 9330fdc8d8SChris Lattner } 9430fdc8d8SChris Lattner 9530fdc8d8SChris Lattner ThreadSP 9630fdc8d8SChris Lattner ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update) 9730fdc8d8SChris Lattner { 9830fdc8d8SChris Lattner Mutex::Locker locker(m_threads_mutex); 9930fdc8d8SChris Lattner if (can_update) 10030fdc8d8SChris Lattner m_process->UpdateThreadListIfNeeded(); 10130fdc8d8SChris Lattner 10230fdc8d8SChris Lattner ThreadSP thread_sp; 10330fdc8d8SChris Lattner if (idx < m_threads.size()) 10430fdc8d8SChris Lattner thread_sp = m_threads[idx]; 10530fdc8d8SChris Lattner return thread_sp; 10630fdc8d8SChris Lattner } 10730fdc8d8SChris Lattner 10830fdc8d8SChris Lattner ThreadSP 10930fdc8d8SChris Lattner ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update) 11030fdc8d8SChris Lattner { 11130fdc8d8SChris Lattner Mutex::Locker locker(m_threads_mutex); 11230fdc8d8SChris Lattner 11330fdc8d8SChris Lattner if (can_update) 11430fdc8d8SChris Lattner m_process->UpdateThreadListIfNeeded(); 11530fdc8d8SChris Lattner 11630fdc8d8SChris Lattner ThreadSP thread_sp; 11730fdc8d8SChris Lattner uint32_t idx = 0; 11830fdc8d8SChris Lattner const uint32_t num_threads = m_threads.size(); 11930fdc8d8SChris Lattner for (idx = 0; idx < num_threads; ++idx) 12030fdc8d8SChris Lattner { 12130fdc8d8SChris Lattner if (m_threads[idx]->GetID() == tid) 12230fdc8d8SChris Lattner { 12330fdc8d8SChris Lattner thread_sp = m_threads[idx]; 12430fdc8d8SChris Lattner break; 12530fdc8d8SChris Lattner } 12630fdc8d8SChris Lattner } 12730fdc8d8SChris Lattner return thread_sp; 12830fdc8d8SChris Lattner } 12930fdc8d8SChris Lattner 13030fdc8d8SChris Lattner ThreadSP 13130fdc8d8SChris Lattner ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr) 13230fdc8d8SChris Lattner { 13330fdc8d8SChris Lattner ThreadSP thread_sp; 13430fdc8d8SChris Lattner if (thread_ptr) 13530fdc8d8SChris Lattner { 13630fdc8d8SChris Lattner Mutex::Locker locker(m_threads_mutex); 13730fdc8d8SChris Lattner 13830fdc8d8SChris Lattner uint32_t idx = 0; 13930fdc8d8SChris Lattner const uint32_t num_threads = m_threads.size(); 14030fdc8d8SChris Lattner for (idx = 0; idx < num_threads; ++idx) 14130fdc8d8SChris Lattner { 14230fdc8d8SChris Lattner if (m_threads[idx].get() == thread_ptr) 14330fdc8d8SChris Lattner { 14430fdc8d8SChris Lattner thread_sp = m_threads[idx]; 14530fdc8d8SChris Lattner break; 14630fdc8d8SChris Lattner } 14730fdc8d8SChris Lattner } 14830fdc8d8SChris Lattner } 14930fdc8d8SChris Lattner return thread_sp; 15030fdc8d8SChris Lattner } 15130fdc8d8SChris Lattner 15230fdc8d8SChris Lattner 15330fdc8d8SChris Lattner 15430fdc8d8SChris Lattner ThreadSP 15530fdc8d8SChris Lattner ThreadList::FindThreadByIndexID (uint32_t index_id, bool can_update) 15630fdc8d8SChris Lattner { 15730fdc8d8SChris Lattner Mutex::Locker locker(m_threads_mutex); 15830fdc8d8SChris Lattner 15930fdc8d8SChris Lattner if (can_update) 16030fdc8d8SChris Lattner m_process->UpdateThreadListIfNeeded(); 16130fdc8d8SChris Lattner 16230fdc8d8SChris Lattner ThreadSP thread_sp; 16330fdc8d8SChris Lattner const uint32_t num_threads = m_threads.size(); 16430fdc8d8SChris Lattner for (uint32_t idx = 0; idx < num_threads; ++idx) 16530fdc8d8SChris Lattner { 16630fdc8d8SChris Lattner if (m_threads[idx]->GetIndexID() == index_id) 16730fdc8d8SChris Lattner { 16830fdc8d8SChris Lattner thread_sp = m_threads[idx]; 16930fdc8d8SChris Lattner break; 17030fdc8d8SChris Lattner } 17130fdc8d8SChris Lattner } 17230fdc8d8SChris Lattner return thread_sp; 17330fdc8d8SChris Lattner } 17430fdc8d8SChris Lattner 17530fdc8d8SChris Lattner bool 17630fdc8d8SChris Lattner ThreadList::ShouldStop (Event *event_ptr) 17730fdc8d8SChris Lattner { 17830fdc8d8SChris Lattner Mutex::Locker locker(m_threads_mutex); 17930fdc8d8SChris Lattner 18030fdc8d8SChris Lattner // Running events should never stop, obviously... 18130fdc8d8SChris Lattner 182*2d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 18330fdc8d8SChris Lattner 18430fdc8d8SChris Lattner bool should_stop = false; 18530fdc8d8SChris Lattner m_process->UpdateThreadListIfNeeded(); 18630fdc8d8SChris Lattner 18730fdc8d8SChris Lattner collection::iterator pos, end = m_threads.end(); 18830fdc8d8SChris Lattner 1892cad65a5SGreg Clayton if (log) 1901346f7e0SGreg Clayton log->Printf ("%s %zu threads", __FUNCTION__, m_threads.size()); 1912cad65a5SGreg Clayton 19230fdc8d8SChris Lattner // Run through the threads and ask whether we should stop. Don't ask 19330fdc8d8SChris Lattner // suspended threads, however, it makes more sense for them to preserve their 19430fdc8d8SChris Lattner // state across the times the process runs but they don't get a chance to. 19530fdc8d8SChris Lattner for (pos = m_threads.begin(); pos != end; ++pos) 19630fdc8d8SChris Lattner { 19730fdc8d8SChris Lattner ThreadSP thread_sp(*pos); 1982cad65a5SGreg Clayton 1992cad65a5SGreg Clayton if (thread_sp->GetResumeState () == eStateSuspended) 20030fdc8d8SChris Lattner { 2012cad65a5SGreg Clayton if (log) 2021346f7e0SGreg Clayton log->Printf ("%s tid = 0x%4.4x, pc = 0x%16.16llx, should_stop = 0 (ignore since thread was suspended)", 2031346f7e0SGreg Clayton __FUNCTION__, 2041346f7e0SGreg Clayton thread_sp->GetID (), 2051346f7e0SGreg Clayton thread_sp->GetRegisterContext()->GetPC()); 2062cad65a5SGreg Clayton continue; 20730fdc8d8SChris Lattner } 2082cad65a5SGreg Clayton 2092cad65a5SGreg Clayton if (thread_sp->ThreadStoppedForAReason() == false) 2102cad65a5SGreg Clayton { 2112cad65a5SGreg Clayton if (log) 2121346f7e0SGreg Clayton log->Printf ("%s tid = 0x%4.4x, pc = 0x%16.16llx, should_stop = 0 (ignore since no stop reason)", 2131346f7e0SGreg Clayton __FUNCTION__, 2141346f7e0SGreg Clayton thread_sp->GetID (), 2151346f7e0SGreg Clayton thread_sp->GetRegisterContext()->GetPC()); 2162cad65a5SGreg Clayton continue; 21730fdc8d8SChris Lattner } 218b01e742aSJim Ingham 2192cad65a5SGreg Clayton const bool thread_should_stop = thread_sp->ShouldStop(event_ptr); 2202cad65a5SGreg Clayton if (log) 2211346f7e0SGreg Clayton log->Printf ("%s tid = 0x%4.4x, pc = 0x%16.16llx, should_stop = %i", 2221346f7e0SGreg Clayton __FUNCTION__, 2231346f7e0SGreg Clayton thread_sp->GetID (), 2241346f7e0SGreg Clayton thread_sp->GetRegisterContext()->GetPC(), 2251346f7e0SGreg Clayton thread_should_stop); 2262cad65a5SGreg Clayton if (thread_should_stop) 2272cad65a5SGreg Clayton should_stop |= true; 2282cad65a5SGreg Clayton } 2292cad65a5SGreg Clayton 2302cad65a5SGreg Clayton if (log) 2311346f7e0SGreg Clayton log->Printf ("%s overall should_stop = %i", __FUNCTION__, should_stop); 2322cad65a5SGreg Clayton 23330fdc8d8SChris Lattner if (should_stop) 23430fdc8d8SChris Lattner { 23530fdc8d8SChris Lattner for (pos = m_threads.begin(); pos != end; ++pos) 23630fdc8d8SChris Lattner { 23730fdc8d8SChris Lattner ThreadSP thread_sp(*pos); 23830fdc8d8SChris Lattner thread_sp->WillStop (); 23930fdc8d8SChris Lattner } 24030fdc8d8SChris Lattner } 24130fdc8d8SChris Lattner 24230fdc8d8SChris Lattner return should_stop; 24330fdc8d8SChris Lattner } 24430fdc8d8SChris Lattner 24530fdc8d8SChris Lattner Vote 24630fdc8d8SChris Lattner ThreadList::ShouldReportStop (Event *event_ptr) 24730fdc8d8SChris Lattner { 2482cad65a5SGreg Clayton Mutex::Locker locker(m_threads_mutex); 2492cad65a5SGreg Clayton 25030fdc8d8SChris Lattner Vote result = eVoteNoOpinion; 25130fdc8d8SChris Lattner m_process->UpdateThreadListIfNeeded(); 25230fdc8d8SChris Lattner collection::iterator pos, end = m_threads.end(); 25330fdc8d8SChris Lattner 254*2d4edfbcSGreg Clayton LogSP log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP)); 2552cad65a5SGreg Clayton 2562cad65a5SGreg Clayton if (log) 2571346f7e0SGreg Clayton log->Printf ("%s %zu threads", __FUNCTION__, m_threads.size()); 2582cad65a5SGreg Clayton 25930fdc8d8SChris Lattner // Run through the threads and ask whether we should report this event. 26030fdc8d8SChris Lattner // For stopping, a YES vote wins over everything. A NO vote wins over NO opinion. 26130fdc8d8SChris Lattner for (pos = m_threads.begin(); pos != end; ++pos) 26230fdc8d8SChris Lattner { 26330fdc8d8SChris Lattner ThreadSP thread_sp(*pos); 26430fdc8d8SChris Lattner if (thread_sp->ThreadStoppedForAReason() && (thread_sp->GetResumeState () != eStateSuspended)) 26530fdc8d8SChris Lattner { 2662cad65a5SGreg Clayton const lldb::Vote vote = thread_sp->ShouldReportStop (event_ptr); 2672cad65a5SGreg Clayton if (log) 2681346f7e0SGreg Clayton log->Printf ("%s thread 0x%4.4x: pc = 0x%16.16llx, vote = %s", 2692cad65a5SGreg Clayton __FUNCTION__, 2702cad65a5SGreg Clayton thread_sp->GetID (), 2712cad65a5SGreg Clayton thread_sp->GetRegisterContext()->GetPC(), 2722cad65a5SGreg Clayton GetVoteAsCString (vote)); 2732cad65a5SGreg Clayton switch (vote) 27430fdc8d8SChris Lattner { 27530fdc8d8SChris Lattner case eVoteNoOpinion: 27630fdc8d8SChris Lattner continue; 2772cad65a5SGreg Clayton 27830fdc8d8SChris Lattner case eVoteYes: 27930fdc8d8SChris Lattner result = eVoteYes; 28030fdc8d8SChris Lattner break; 2812cad65a5SGreg Clayton 28230fdc8d8SChris Lattner case eVoteNo: 28330fdc8d8SChris Lattner if (result == eVoteNoOpinion) 2842cad65a5SGreg Clayton { 28530fdc8d8SChris Lattner result = eVoteNo; 2862cad65a5SGreg Clayton } 2872cad65a5SGreg Clayton else 2882cad65a5SGreg Clayton { 2892cad65a5SGreg Clayton if (log) 2901346f7e0SGreg Clayton log->Printf ("%s thread 0x%4.4x: pc = 0x%16.16llx voted %s, but lost out because result was %s", 2912cad65a5SGreg Clayton __FUNCTION__, 2922cad65a5SGreg Clayton thread_sp->GetID (), 2932cad65a5SGreg Clayton thread_sp->GetRegisterContext()->GetPC(), 2942cad65a5SGreg Clayton GetVoteAsCString (vote), 2952cad65a5SGreg Clayton GetVoteAsCString (result)); 2962cad65a5SGreg Clayton } 29730fdc8d8SChris Lattner break; 29830fdc8d8SChris Lattner } 29930fdc8d8SChris Lattner } 30030fdc8d8SChris Lattner } 3012cad65a5SGreg Clayton if (log) 3021346f7e0SGreg Clayton log->Printf ("%s returning %s", __FUNCTION__, GetVoteAsCString (result)); 30330fdc8d8SChris Lattner return result; 30430fdc8d8SChris Lattner } 30530fdc8d8SChris Lattner 30630fdc8d8SChris Lattner Vote 30730fdc8d8SChris Lattner ThreadList::ShouldReportRun (Event *event_ptr) 30830fdc8d8SChris Lattner { 3092cad65a5SGreg Clayton 3102cad65a5SGreg Clayton Mutex::Locker locker(m_threads_mutex); 3112cad65a5SGreg Clayton 31230fdc8d8SChris Lattner Vote result = eVoteNoOpinion; 31330fdc8d8SChris Lattner m_process->UpdateThreadListIfNeeded(); 31430fdc8d8SChris Lattner collection::iterator pos, end = m_threads.end(); 31530fdc8d8SChris Lattner 31630fdc8d8SChris Lattner // Run through the threads and ask whether we should report this event. 31730fdc8d8SChris Lattner // The rule is NO vote wins over everything, a YES vote wins over no opinion. 31830fdc8d8SChris Lattner 31930fdc8d8SChris Lattner for (pos = m_threads.begin(); pos != end; ++pos) 32030fdc8d8SChris Lattner { 32130fdc8d8SChris Lattner ThreadSP thread_sp(*pos); 32230fdc8d8SChris Lattner if (thread_sp->GetResumeState () != eStateSuspended) 32330fdc8d8SChris Lattner 32430fdc8d8SChris Lattner switch (thread_sp->ShouldReportRun (event_ptr)) 32530fdc8d8SChris Lattner { 32630fdc8d8SChris Lattner case eVoteNoOpinion: 32730fdc8d8SChris Lattner continue; 32830fdc8d8SChris Lattner case eVoteYes: 32930fdc8d8SChris Lattner if (result == eVoteNoOpinion) 33030fdc8d8SChris Lattner result = eVoteYes; 33130fdc8d8SChris Lattner break; 33230fdc8d8SChris Lattner case eVoteNo: 33330fdc8d8SChris Lattner result = eVoteNo; 33430fdc8d8SChris Lattner break; 33530fdc8d8SChris Lattner } 33630fdc8d8SChris Lattner } 33730fdc8d8SChris Lattner return result; 33830fdc8d8SChris Lattner } 33930fdc8d8SChris Lattner 34030fdc8d8SChris Lattner void 34130fdc8d8SChris Lattner ThreadList::Clear() 34230fdc8d8SChris Lattner { 34330fdc8d8SChris Lattner m_stop_id = 0; 34430fdc8d8SChris Lattner m_threads.clear(); 3452976d00aSJim Ingham m_selected_tid = LLDB_INVALID_THREAD_ID; 34630fdc8d8SChris Lattner } 34730fdc8d8SChris Lattner 34830fdc8d8SChris Lattner void 34930fdc8d8SChris Lattner ThreadList::RefreshStateAfterStop () 35030fdc8d8SChris Lattner { 35130fdc8d8SChris Lattner Mutex::Locker locker(m_threads_mutex); 35230fdc8d8SChris Lattner 35330fdc8d8SChris Lattner m_process->UpdateThreadListIfNeeded(); 35430fdc8d8SChris Lattner 35530fdc8d8SChris Lattner collection::iterator pos, end = m_threads.end(); 35630fdc8d8SChris Lattner for (pos = m_threads.begin(); pos != end; ++pos) 35730fdc8d8SChris Lattner (*pos)->RefreshStateAfterStop (); 35830fdc8d8SChris Lattner } 35930fdc8d8SChris Lattner 36030fdc8d8SChris Lattner void 36130fdc8d8SChris Lattner ThreadList::DiscardThreadPlans () 36230fdc8d8SChris Lattner { 36330fdc8d8SChris Lattner // You don't need to update the thread list here, because only threads 36430fdc8d8SChris Lattner // that you currently know about have any thread plans. 36530fdc8d8SChris Lattner Mutex::Locker locker(m_threads_mutex); 36630fdc8d8SChris Lattner 36730fdc8d8SChris Lattner collection::iterator pos, end = m_threads.end(); 36830fdc8d8SChris Lattner for (pos = m_threads.begin(); pos != end; ++pos) 36930fdc8d8SChris Lattner (*pos)->DiscardThreadPlans (true); 37030fdc8d8SChris Lattner 37130fdc8d8SChris Lattner } 37230fdc8d8SChris Lattner 37330fdc8d8SChris Lattner bool 37430fdc8d8SChris Lattner ThreadList::WillResume () 37530fdc8d8SChris Lattner { 37630fdc8d8SChris Lattner // Run through the threads and perform their momentary actions. 37730fdc8d8SChris Lattner // But we only do this for threads that are running, user suspended 37830fdc8d8SChris Lattner // threads stay where they are. 37930fdc8d8SChris Lattner bool success = true; 38030fdc8d8SChris Lattner 38130fdc8d8SChris Lattner Mutex::Locker locker(m_threads_mutex); 38230fdc8d8SChris Lattner m_process->UpdateThreadListIfNeeded(); 38330fdc8d8SChris Lattner 38430fdc8d8SChris Lattner collection::iterator pos, end = m_threads.end(); 38530fdc8d8SChris Lattner 386a3241c1bSJim Ingham // See if any thread wants to run stopping others. If it does, then we won't 387a3241c1bSJim Ingham // setup the other threads for resume, since they aren't going to get a chance 388a3241c1bSJim Ingham // to run. This is necessary because the SetupForResume might add "StopOthers" 389a3241c1bSJim Ingham // plans which would then get to be part of the who-gets-to-run negotiation, but 390a3241c1bSJim Ingham // they're coming in after the fact, and the threads that are already set up should 391a3241c1bSJim Ingham // take priority. 392a3241c1bSJim Ingham 393a3241c1bSJim Ingham bool wants_solo_run = false; 39430fdc8d8SChris Lattner 39530fdc8d8SChris Lattner for (pos = m_threads.begin(); pos != end; ++pos) 396a3241c1bSJim Ingham { 397a3241c1bSJim Ingham if ((*pos)->GetResumeState() != eStateSuspended && 398a3241c1bSJim Ingham (*pos)->GetCurrentPlan()->StopOthers()) 399a3241c1bSJim Ingham { 400a3241c1bSJim Ingham wants_solo_run = true; 401a3241c1bSJim Ingham break; 402a3241c1bSJim Ingham } 403a3241c1bSJim Ingham } 404a3241c1bSJim Ingham 405a3241c1bSJim Ingham 406a3241c1bSJim Ingham // Give all the threads that are likely to run a last chance to set up their state before we 407a3241c1bSJim Ingham // negotiate who is actually going to get a chance to run... 408a3241c1bSJim Ingham // Don't set to resume suspended threads, and if any thread wanted to stop others, only 409a3241c1bSJim Ingham // call setup on the threads that request StopOthers... 410a3241c1bSJim Ingham 411a3241c1bSJim Ingham for (pos = m_threads.begin(); pos != end; ++pos) 412a3241c1bSJim Ingham { 413a3241c1bSJim Ingham if ((*pos)->GetResumeState() != eStateSuspended 414a3241c1bSJim Ingham && (!wants_solo_run || (*pos)->GetCurrentPlan()->StopOthers())) 415a3241c1bSJim Ingham { 41630fdc8d8SChris Lattner (*pos)->SetupForResume (); 417a3241c1bSJim Ingham } 418a3241c1bSJim Ingham } 41930fdc8d8SChris Lattner 42030fdc8d8SChris Lattner // Now go through the threads and see if any thread wants to run just itself. 42130fdc8d8SChris Lattner // if so then pick one and run it. 422a3241c1bSJim Ingham 42330fdc8d8SChris Lattner ThreadList run_me_only_list (m_process); 42430fdc8d8SChris Lattner 42530fdc8d8SChris Lattner run_me_only_list.SetStopID(m_process->GetStopID()); 42630fdc8d8SChris Lattner 42730fdc8d8SChris Lattner ThreadSP immediate_thread_sp; 42830fdc8d8SChris Lattner bool run_only_current_thread = false; 42930fdc8d8SChris Lattner 43030fdc8d8SChris Lattner for (pos = m_threads.begin(); pos != end; ++pos) 43130fdc8d8SChris Lattner { 43230fdc8d8SChris Lattner ThreadSP thread_sp(*pos); 433b15bfc75SJim Ingham if (thread_sp->GetResumeState() != eStateSuspended && 43430fdc8d8SChris Lattner thread_sp->GetCurrentPlan()->StopOthers()) 43530fdc8d8SChris Lattner { 43630fdc8d8SChris Lattner // You can't say "stop others" and also want yourself to be suspended. 43730fdc8d8SChris Lattner assert (thread_sp->GetCurrentPlan()->RunState() != eStateSuspended); 43830fdc8d8SChris Lattner 4392976d00aSJim Ingham if (thread_sp == GetSelectedThread()) 44030fdc8d8SChris Lattner { 44130fdc8d8SChris Lattner run_only_current_thread = true; 44230fdc8d8SChris Lattner run_me_only_list.Clear(); 44330fdc8d8SChris Lattner run_me_only_list.AddThread (thread_sp); 44430fdc8d8SChris Lattner break; 44530fdc8d8SChris Lattner } 44630fdc8d8SChris Lattner 44730fdc8d8SChris Lattner run_me_only_list.AddThread (thread_sp); 44830fdc8d8SChris Lattner } 44930fdc8d8SChris Lattner 45030fdc8d8SChris Lattner } 45130fdc8d8SChris Lattner 45230fdc8d8SChris Lattner if (immediate_thread_sp) 45330fdc8d8SChris Lattner { 45430fdc8d8SChris Lattner for (pos = m_threads.begin(); pos != end; ++pos) 45530fdc8d8SChris Lattner { 45630fdc8d8SChris Lattner ThreadSP thread_sp(*pos); 45730fdc8d8SChris Lattner if (thread_sp.get() == immediate_thread_sp.get()) 45830fdc8d8SChris Lattner thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState()); 45930fdc8d8SChris Lattner else 46030fdc8d8SChris Lattner thread_sp->WillResume (eStateSuspended); 46130fdc8d8SChris Lattner } 46230fdc8d8SChris Lattner } 46330fdc8d8SChris Lattner else if (run_me_only_list.GetSize (false) == 0) 46430fdc8d8SChris Lattner { 46530fdc8d8SChris Lattner // Everybody runs as they wish: 46630fdc8d8SChris Lattner for (pos = m_threads.begin(); pos != end; ++pos) 46730fdc8d8SChris Lattner { 46830fdc8d8SChris Lattner ThreadSP thread_sp(*pos); 46930fdc8d8SChris Lattner thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState()); 47030fdc8d8SChris Lattner } 47130fdc8d8SChris Lattner } 47230fdc8d8SChris Lattner else 47330fdc8d8SChris Lattner { 47430fdc8d8SChris Lattner ThreadSP thread_to_run; 47530fdc8d8SChris Lattner 47630fdc8d8SChris Lattner if (run_only_current_thread) 47730fdc8d8SChris Lattner { 4782976d00aSJim Ingham thread_to_run = GetSelectedThread(); 47930fdc8d8SChris Lattner } 48030fdc8d8SChris Lattner else if (run_me_only_list.GetSize (false) == 1) 48130fdc8d8SChris Lattner { 48230fdc8d8SChris Lattner thread_to_run = run_me_only_list.GetThreadAtIndex (0); 48330fdc8d8SChris Lattner } 48430fdc8d8SChris Lattner else 48530fdc8d8SChris Lattner { 48630fdc8d8SChris Lattner int random_thread = (int) 48730fdc8d8SChris Lattner ((run_me_only_list.GetSize (false) * (double) rand ()) / (RAND_MAX + 1.0)); 48830fdc8d8SChris Lattner thread_to_run = run_me_only_list.GetThreadAtIndex (random_thread); 48930fdc8d8SChris Lattner } 49030fdc8d8SChris Lattner 49130fdc8d8SChris Lattner for (pos = m_threads.begin(); pos != end; ++pos) 49230fdc8d8SChris Lattner { 49330fdc8d8SChris Lattner ThreadSP thread_sp(*pos); 49430fdc8d8SChris Lattner if (thread_sp == thread_to_run) 49530fdc8d8SChris Lattner thread_sp->WillResume(thread_sp->GetCurrentPlan()->RunState()); 49630fdc8d8SChris Lattner else 49730fdc8d8SChris Lattner thread_sp->WillResume (eStateSuspended); 49830fdc8d8SChris Lattner } 49930fdc8d8SChris Lattner } 50030fdc8d8SChris Lattner 50130fdc8d8SChris Lattner return success; 50230fdc8d8SChris Lattner } 50330fdc8d8SChris Lattner 50430fdc8d8SChris Lattner void 50530fdc8d8SChris Lattner ThreadList::DidResume () 50630fdc8d8SChris Lattner { 50730fdc8d8SChris Lattner collection::iterator pos, end = m_threads.end(); 50830fdc8d8SChris Lattner for (pos = m_threads.begin(); pos != end; ++pos) 50930fdc8d8SChris Lattner { 51030fdc8d8SChris Lattner // Don't clear out threads that aren't going to get a chance to run, rather 51130fdc8d8SChris Lattner // leave their state for the next time around. 51230fdc8d8SChris Lattner ThreadSP thread_sp(*pos); 51330fdc8d8SChris Lattner if (thread_sp->GetResumeState() != eStateSuspended) 51430fdc8d8SChris Lattner thread_sp->DidResume (); 51530fdc8d8SChris Lattner } 51630fdc8d8SChris Lattner } 51730fdc8d8SChris Lattner 51830fdc8d8SChris Lattner ThreadSP 5192976d00aSJim Ingham ThreadList::GetSelectedThread () 52030fdc8d8SChris Lattner { 52130fdc8d8SChris Lattner Mutex::Locker locker(m_threads_mutex); 5222976d00aSJim Ingham return FindThreadByID(m_selected_tid); 52330fdc8d8SChris Lattner } 52430fdc8d8SChris Lattner 52530fdc8d8SChris Lattner bool 5262976d00aSJim Ingham ThreadList::SetSelectedThreadByID (lldb::tid_t tid) 52730fdc8d8SChris Lattner { 52830fdc8d8SChris Lattner Mutex::Locker locker(m_threads_mutex); 52930fdc8d8SChris Lattner if (FindThreadByID(tid).get()) 5302976d00aSJim Ingham m_selected_tid = tid; 53130fdc8d8SChris Lattner else 5322976d00aSJim Ingham m_selected_tid = LLDB_INVALID_THREAD_ID; 53330fdc8d8SChris Lattner 5342976d00aSJim Ingham return m_selected_tid != LLDB_INVALID_THREAD_ID; 53530fdc8d8SChris Lattner } 53630fdc8d8SChris Lattner 53730fdc8d8SChris Lattner bool 5382976d00aSJim Ingham ThreadList::SetSelectedThreadByIndexID (uint32_t index_id) 53930fdc8d8SChris Lattner { 54030fdc8d8SChris Lattner Mutex::Locker locker(m_threads_mutex); 54130fdc8d8SChris Lattner ThreadSP thread_sp (FindThreadByIndexID(index_id)); 54230fdc8d8SChris Lattner if (thread_sp.get()) 5432976d00aSJim Ingham m_selected_tid = thread_sp->GetID(); 54430fdc8d8SChris Lattner else 5452976d00aSJim Ingham m_selected_tid = LLDB_INVALID_THREAD_ID; 54630fdc8d8SChris Lattner 5472976d00aSJim Ingham return m_selected_tid != LLDB_INVALID_THREAD_ID; 54830fdc8d8SChris Lattner } 54930fdc8d8SChris Lattner 550