Based on the conversation at 
http://lists.cs.uiuc.edu/pipermail/lldb-commits/Week-of-Mon-20140901/012760.html
 this patch splits the current ThreadList class into a process-related thread 
object called "ProcessThreadList" and a generic thread list now called just 
ThreadList. The idea is to expose the ThreadList as SBThreadList and make 
ASan-related API based on it.

http://reviews.llvm.org/D5200

Files:
  include/lldb/Target/OperatingSystem.h
  include/lldb/Target/Process.h
  include/lldb/Target/ProcessThreadList.h
  include/lldb/Target/Thread.h
  include/lldb/Target/ThreadList.h
  include/lldb/lldb-forward.h
  lldb.xcodeproj/project.pbxproj
  source/Commands/CommandObjectTarget.cpp
  source/Core/Debugger.cpp
  source/Core/IOHandler.cpp
  source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
  source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
  source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
  source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
  source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
  source/Plugins/Process/elf-core/ProcessElfCore.cpp
  source/Plugins/Process/elf-core/ProcessElfCore.h
  source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
  source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
  source/Plugins/Process/mach-core/ProcessMachCore.cpp
  source/Plugins/Process/mach-core/ProcessMachCore.h
  source/Target/Process.cpp
  source/Target/ProcessThreadList.cpp
  source/Target/Target.cpp
  source/Target/ThreadList.cpp
Index: include/lldb/Target/OperatingSystem.h
===================================================================
--- include/lldb/Target/OperatingSystem.h
+++ include/lldb/Target/OperatingSystem.h
@@ -65,9 +65,9 @@
     // Plug-in Methods
     //------------------------------------------------------------------
     virtual bool
-    UpdateThreadList (ThreadList &old_thread_list,
-                      ThreadList &real_thread_list,
-                      ThreadList &new_thread_list) = 0;
+    UpdateThreadList (ProcessThreadList &old_thread_list,
+                      ProcessThreadList &real_thread_list,
+                      ProcessThreadList &new_thread_list) = 0;
     
     virtual void
     ThreadWasSelected (Thread *thread) = 0;
Index: include/lldb/Target/Process.h
===================================================================
--- include/lldb/Target/Process.h
+++ include/lldb/Target/Process.h
@@ -48,7 +48,7 @@
 #include "lldb/Target/ProcessInfo.h"
 #include "lldb/Target/ProcessLaunchInfo.h"
 #include "lldb/Target/QueueList.h"
-#include "lldb/Target/ThreadList.h"
+#include "lldb/Target/ProcessThreadList.h"
 #include "lldb/Target/UnixSignals.h"
 #include "lldb/Utility/PseudoTerminal.h"
 
@@ -701,7 +701,7 @@
     friend class ProcessEventData;
     friend class StopInfo;
     friend class Target;
-    friend class ThreadList;
+    friend class ProcessThreadList;
 
 public:
 
@@ -2601,12 +2601,12 @@
     // Thread Queries
     //------------------------------------------------------------------
     virtual bool
-    UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list) = 0;
+    UpdateThreadList (ProcessThreadList &old_thread_list, ProcessThreadList &new_thread_list) = 0;
 
     void
     UpdateThreadListIfNeeded ();
 
-    ThreadList &
+    ProcessThreadList &
     GetThreadList ()
     {
         return m_thread_list;
@@ -2617,13 +2617,13 @@
     // threads in this list are not iterated over - driver programs need to
     // request the extended backtrace calls starting from a root concrete
     // thread one by one.
-    ThreadList &
+    ProcessThreadList &
     GetExtendedThreadList ()
     {
         return m_extended_thread_list;
     }
 
-    ThreadList::ThreadIterable
+    ProcessThreadList::ThreadIterable
     Threads ()
     {
         return m_thread_list.Threads();
@@ -2914,6 +2914,9 @@
         else
             return m_public_run_lock;
     }
+    
+    lldb::ThreadListSP
+    GetHistoryThreads(lldb::addr_t addr);
 
 public:
     virtual Error
@@ -3047,10 +3050,10 @@
     int                         m_exit_status;          ///< The exit status of the process, or -1 if not set.
     std::string                 m_exit_string;          ///< A textual description of why a process exited.
     Mutex                       m_thread_mutex;
-    ThreadList                  m_thread_list_real;     ///< The threads for this process as are known to the protocol we are debugging with
-    ThreadList                  m_thread_list;          ///< The threads for this process as the user will see them. This is usually the same as
+    ProcessThreadList                  m_thread_list_real;     ///< The threads for this process as are known to the protocol we are debugging with
+    ProcessThreadList                  m_thread_list;          ///< The threads for this process as the user will see them. This is usually the same as
                                                         ///< m_thread_list_real, but might be different if there is an OS plug-in creating memory threads
-    ThreadList                  m_extended_thread_list; ///< Owner for extended threads that may be generated, cleared on natural stops
+    ProcessThreadList                  m_extended_thread_list; ///< Owner for extended threads that may be generated, cleared on natural stops
     uint32_t                    m_extended_thread_stop_id; ///< The natural stop id when extended_thread_list was last updated
     QueueList                   m_queue_list;           ///< The list of libdispatch queues at a given stop point
     uint32_t                    m_queue_list_stop_id;   ///< The natural stop id when queue list was last fetched
Index: include/lldb/Target/ProcessThreadList.h
===================================================================
--- include/lldb/Target/ProcessThreadList.h
+++ include/lldb/Target/ProcessThreadList.h
@@ -0,0 +1,155 @@
+//===-- ProcessThreadList.h -------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef liblldb_ProcessThreadList_h_
+#define liblldb_ProcessThreadList_h_
+
+#include <vector>
+
+#include "lldb/lldb-private.h"
+#include "lldb/Core/UserID.h"
+#include "lldb/Utility/Iterable.h"
+#include "lldb/Target/ThreadList.h"
+
+namespace lldb_private {
+    
+class ProcessThreadList : public ThreadList
+{
+    friend class Process;
+    
+public:
+    
+    ProcessThreadList (Process *process);
+    
+    ProcessThreadList (const ProcessThreadList &rhs);
+    
+    ~ProcessThreadList ();
+    
+    const ProcessThreadList&
+    operator = (const ProcessThreadList& rhs);
+    
+    uint32_t
+    GetSize(bool can_update = true);
+    
+    // Return the selected thread if there is one.  Otherwise, return the thread
+    // selected at index 0.
+    lldb::ThreadSP
+    GetSelectedThread ();
+    
+    bool
+    SetSelectedThreadByID (lldb::tid_t tid, bool notify = false);
+    
+    bool
+    SetSelectedThreadByIndexID (uint32_t index_id, bool notify = false);
+    
+    void
+    Clear();
+    
+    void
+    Flush();
+    
+    void
+    Destroy();
+    
+    // Note that "idx" is not the same as the "thread_index". It is a zero
+    // based index to accessing the current threads, whereas "thread_index"
+    // is a unique index assigned
+    lldb::ThreadSP
+    GetThreadAtIndex (uint32_t idx, bool can_update = true);
+    
+    lldb::ThreadSP
+    FindThreadByID (lldb::tid_t tid, bool can_update = true);
+    
+    lldb::ThreadSP
+    FindThreadByProtocolID (lldb::tid_t tid, bool can_update = true);
+    
+    lldb::ThreadSP
+    RemoveThreadByID (lldb::tid_t tid, bool can_update = true);
+    
+    lldb::ThreadSP
+    RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update = true);
+    
+    lldb::ThreadSP
+    FindThreadByIndexID (uint32_t index_id, bool can_update = true);
+    
+    lldb::ThreadSP
+    GetThreadSPForThreadPtr (Thread *thread_ptr);
+    
+    bool
+    ShouldStop (Event *event_ptr);
+    
+    Vote
+    ShouldReportStop (Event *event_ptr);
+    
+    Vote
+    ShouldReportRun (Event *event_ptr);
+    
+    void
+    RefreshStateAfterStop ();
+    
+    //------------------------------------------------------------------
+    /// The thread list asks tells all the threads it is about to resume.
+    /// If a thread can "resume" without having to resume the target, it
+    /// will return false for WillResume, and then the process will not be
+    /// restarted.
+    ///
+    /// @return
+    ///    \b true instructs the process to resume normally,
+    ///    \b false means start & stopped events will be generated, but
+    ///    the process will not actually run.  The thread must then return
+    ///    the correct StopInfo when asked.
+    ///
+    //------------------------------------------------------------------
+    bool
+    WillResume ();
+    
+    void
+    DidResume ();
+    
+    void
+    DidStop ();
+    
+    void
+    DiscardThreadPlans();
+    
+    uint32_t
+    GetStopID () const;
+    
+    void
+    SetStopID (uint32_t stop_id);
+    
+    Mutex &
+    GetMutex ();
+    
+    void
+    Update (ProcessThreadList &rhs);
+
+    
+protected:
+    
+    void
+    SetShouldReportStop (Vote vote);
+    
+    void
+    NotifySelectedThreadChanged (lldb::tid_t tid);
+    
+    //------------------------------------------------------------------
+    // Classes that inherit from Process can see and modify these
+    //------------------------------------------------------------------
+    Process *m_process; ///< The process that manages this thread list.
+    uint32_t m_stop_id; ///< The process stop ID that this thread list is valid for.
+    lldb::tid_t m_selected_tid;  ///< For targets that need the notion of a current thread.
+    
+private:
+    ProcessThreadList ();
+};
+    
+} // namespace lldb_private
+
+#endif  // liblldb_ProcessThreadList_h_
Index: include/lldb/Target/Thread.h
===================================================================
--- include/lldb/Target/Thread.h
+++ include/lldb/Target/Thread.h
@@ -1235,7 +1235,7 @@
 protected:
 
     friend class ThreadPlan;
-    friend class ThreadList;
+    friend class ProcessThreadList;
     friend class ThreadEventData;
     friend class StackFrameList;
     friend class StackFrame;
Index: include/lldb/Target/ThreadList.h
===================================================================
--- include/lldb/Target/ThreadList.h
+++ include/lldb/Target/ThreadList.h
@@ -17,156 +17,48 @@
 #include "lldb/Utility/Iterable.h"
 
 
-// FIXME: Currently this is a thread list with lots of functionality for use only by
-// the process for which this is the thread list.  If we ever want a container class
-// to hand out that is just a random subset of threads, with iterator functionality,
-// then we should make that part a base class, and make a ProcessThreadList for the
-// process.
 namespace lldb_private {
 
 class ThreadList
 {
-friend class Process;
-
 public:
-
-    ThreadList (Process *process);
-
-    ThreadList (const ThreadList &rhs);
-
-    ~ThreadList ();
-
-    const ThreadList&
-    operator = (const ThreadList& rhs);
-
+    typedef std::vector<lldb::ThreadSP> collection;
+    typedef LockingAdaptedIterable<collection, lldb::ThreadSP, vector_adapter> ThreadIterable;
+    
+    ThreadList();
+    
+    ThreadList(collection threads);
+    
     uint32_t
-    GetSize(bool can_update = true);
+    GetSize();
 
     void
     AddThread (const lldb::ThreadSP &thread_sp);
 
     void
     InsertThread (const lldb::ThreadSP &thread_sp, uint32_t idx);
-    // Return the selected thread if there is one.  Otherwise, return the thread
-    // selected at index 0.
-    lldb::ThreadSP
-    GetSelectedThread ();
 
-    bool
-    SetSelectedThreadByID (lldb::tid_t tid, bool notify = false);
-
-    bool
-    SetSelectedThreadByIndexID (uint32_t index_id, bool notify = false);
-
-    void
-    Clear();
-
-    void
-    Flush();
-
-    void
-    Destroy();
-
     // Note that "idx" is not the same as the "thread_index". It is a zero
     // based index to accessing the current threads, whereas "thread_index"
     // is a unique index assigned
     lldb::ThreadSP
-    GetThreadAtIndex (uint32_t idx, bool can_update = true);
+    GetThreadAtIndex (uint32_t idx);
     
-    typedef std::vector<lldb::ThreadSP> collection;
-    typedef LockingAdaptedIterable<collection, lldb::ThreadSP, vector_adapter> ThreadIterable;
-    
     ThreadIterable
     Threads ()
     {
         return ThreadIterable(m_threads, GetMutex());
     }
-
-    lldb::ThreadSP
-    FindThreadByID (lldb::tid_t tid, bool can_update = true);
     
-    lldb::ThreadSP
-    FindThreadByProtocolID (lldb::tid_t tid, bool can_update = true);
+    Mutex &
+    GetMutex()
+    {
+        return m_mutex;
+    }
 
-    lldb::ThreadSP
-    RemoveThreadByID (lldb::tid_t tid, bool can_update = true);
-    
-    lldb::ThreadSP
-    RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update = true);
-
-    lldb::ThreadSP
-    FindThreadByIndexID (uint32_t index_id, bool can_update = true);
-
-    lldb::ThreadSP
-    GetThreadSPForThreadPtr (Thread *thread_ptr);
-
-    bool
-    ShouldStop (Event *event_ptr);
-
-    Vote
-    ShouldReportStop (Event *event_ptr);
-
-    Vote
-    ShouldReportRun (Event *event_ptr);
-
-    void
-    RefreshStateAfterStop ();
-
-    //------------------------------------------------------------------
-    /// The thread list asks tells all the threads it is about to resume.
-    /// If a thread can "resume" without having to resume the target, it
-    /// will return false for WillResume, and then the process will not be
-    /// restarted.
-    ///
-    /// @return
-    ///    \b true instructs the process to resume normally,
-    ///    \b false means start & stopped events will be generated, but
-    ///    the process will not actually run.  The thread must then return
-    ///    the correct StopInfo when asked.
-    ///
-    //------------------------------------------------------------------
-    bool
-    WillResume ();
-
-    void
-    DidResume ();
-
-    void
-    DidStop ();
-
-    void
-    DiscardThreadPlans();
-
-    uint32_t
-    GetStopID () const;
-
-    void
-    SetStopID (uint32_t stop_id);
-
-    Mutex &
-    GetMutex ();
-    
-    void
-    Update (ThreadList &rhs);
-    
 protected:
-
-    void
-    SetShouldReportStop (Vote vote);
-
-    void
-    NotifySelectedThreadChanged (lldb::tid_t tid);
-
-    //------------------------------------------------------------------
-    // Classes that inherit from Process can see and modify these
-    //------------------------------------------------------------------
-    Process *m_process; ///< The process that manages this thread list.
-    uint32_t m_stop_id; ///< The process stop ID that this thread list is valid for.
     collection m_threads; ///< The threads for this process.
-    lldb::tid_t m_selected_tid;  ///< For targets that need the notion of a current thread.
-
-private:
-    ThreadList ();
+    Mutex m_mutex;
 };
 
 } // namespace lldb_private
Index: include/lldb/lldb-forward.h
===================================================================
--- include/lldb/lldb-forward.h
+++ include/lldb/lldb-forward.h
@@ -160,6 +160,7 @@
 class   ProcessInstanceInfoList;
 class   ProcessInstanceInfoMatch;
 class   ProcessLaunchInfo;
+class   ProcessThreadList;
 class   Property;
 struct  PropertyDefinition;
 class   PythonArray;
@@ -381,6 +382,7 @@
     typedef std::weak_ptr<lldb_private::Target> TargetWP;
     typedef std::shared_ptr<lldb_private::Thread> ThreadSP;
     typedef std::weak_ptr<lldb_private::Thread> ThreadWP;
+    typedef std::shared_ptr<lldb_private::ThreadList> ThreadListSP;
     typedef std::shared_ptr<lldb_private::ThreadPlan> ThreadPlanSP;
     typedef std::shared_ptr<lldb_private::ThreadPlanTracer> ThreadPlanTracerSP;
     typedef std::shared_ptr<lldb_private::Type> TypeSP;
Index: lldb.xcodeproj/project.pbxproj
===================================================================
--- lldb.xcodeproj/project.pbxproj
+++ lldb.xcodeproj/project.pbxproj
@@ -620,6 +620,7 @@
        4CF52AF8142829390051E832 /* SBFileSpecList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 4CF52AF7142829390051E832 /* SBFileSpecList.cpp */; };
        8C2D6A53197A1EAF006989C9 /* MemoryHistory.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A52197A1EAF006989C9 /* MemoryHistory.cpp */; };
        8C2D6A5E197A250F006989C9 /* MemoryHistoryASan.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C2D6A5A197A1FDC006989C9 /* MemoryHistoryASan.cpp */; };
+       8C395A2D19B91D37001C9B07 /* ProcessThreadList.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 8C395A2B19B91C8F001C9B07 /* ProcessThreadList.cpp */; };
        94094C6B163B6F840083A547 /* ValueObjectCast.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 94094C69163B6CD90083A547 /* ValueObjectCast.cpp */; };
        94145431175E63B500284436 /* lldb-versioning.h in Headers */ = {isa = PBXBuildFile; fileRef = 94145430175D7FDE00284436 /* lldb-versioning.h */; settings = {ATTRIBUTES = (Public, ); }; };
        941BCC7F14E48C4000BB969C /* SBTypeFilter.h in Headers */ = {isa = PBXBuildFile; fileRef = 9461568614E355F2003A195C /* SBTypeFilter.h */; settings = {ATTRIBUTES = (Public, ); }; };
@@ -1900,6 +1903,8 @@
        8C2D6A54197A1EBE006989C9 /* MemoryHistory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = MemoryHistory.h; path = include/lldb/Target/MemoryHistory.h; sourceTree = "<group>"; };
        8C2D6A5A197A1FDC006989C9 /* MemoryHistoryASan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MemoryHistoryASan.cpp; sourceTree = "<group>"; };
        8C2D6A5B197A1FDC006989C9 /* MemoryHistoryASan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemoryHistoryASan.h; sourceTree = "<group>"; };
+       8C395A2B19B91C8F001C9B07 /* ProcessThreadList.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = ProcessThreadList.cpp; path = source/Target/ProcessThreadList.cpp; sourceTree = "<group>"; };
+       8C395A2C19B91C8F001C9B07 /* ProcessThreadList.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ProcessThreadList.h; path = include/lldb/Target/ProcessThreadList.h; sourceTree = "<group>"; };
        94005E0313F438DF001EF42D /* python-wrapper.swig */ = {isa = PBXFileReference; lastKnownFileType = text; path = "python-wrapper.swig"; sourceTree = "<group>"; };
        94005E0513F45A1B001EF42D /* embedded_interpreter.py */ = {isa = PBXFileReference; lastKnownFileType = text.script.python; name = embedded_interpreter.py; path = source/Interpreter/embedded_interpreter.py; sourceTree = "<group>"; };
        94031A9F13CF5B3D00DCFF3C /* PriorityPointerPair.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = PriorityPointerPair.h; path = include/lldb/Utility/PriorityPointerPair.h; sourceTree = "<group>"; };
@@ -3681,6 +3692,8 @@
                233B007B1960C9E60090E598 /* ProcessInfo.cpp */,
                233B007E1960CB280090E598 /* ProcessLaunchInfo.cpp */,
                233B007919609DB40090E598 /* ProcessLaunchInfo.h */,
+               8C395A2C19B91C8F001C9B07 /* ProcessThreadList.h */,
+               8C395A2B19B91C8F001C9B07 /* ProcessThreadList.cpp */,
                26BC7DF310F1B81A00F91463 /* Process.h */,
                26BC7F3610F1B90C00F91463 /* Process.cpp */,
                260A63111860FDB600FECF8E /* Queue.h */,
@@ -4867,6 +4882,7 @@
                2689002713353DDE00698AC0 /* CommandObjectTarget.cpp in Sources */,
                2689002813353DDE00698AC0 /* CommandObjectThread.cpp in Sources */,
                2689002913353DDE00698AC0 /* CommandObjectVersion.cpp in Sources */,
+               8C395A2D19B91D37001C9B07 /* ProcessThreadList.cpp in Sources */,
                2689002A13353E0400698AC0 /* Address.cpp in Sources */,
                2689002B13353E0400698AC0 /* AddressRange.cpp in Sources */,
                236124A41986B4E2004EFC37 /* IOObject.cpp in Sources */,
Index: source/Commands/CommandObjectTarget.cpp
===================================================================
--- source/Commands/CommandObjectTarget.cpp
+++ source/Commands/CommandObjectTarget.cpp
@@ -3648,7 +3648,7 @@
             return false;
         }
 
-        ThreadList threads(process->GetThreadList());
+        ProcessThreadList threads(process->GetThreadList());
         if (threads.GetSize() == 0)
         {
             result.AppendError ("The process must be paused to use this command.");
Index: source/Core/Debugger.cpp
===================================================================
--- source/Core/Debugger.cpp
+++ source/Core/Debugger.cpp
@@ -3053,7 +3053,7 @@
                     {
                         // Lock the thread list so it doesn't change on us, this is the scope for the locker:
                         {
-                            ThreadList &thread_list = process_sp->GetThreadList();
+                            ProcessThreadList &thread_list = process_sp->GetThreadList();
                             Mutex::Locker locker (thread_list.GetMutex());
                             
                             ThreadSP curr_thread (thread_list.GetSelectedThread());
Index: source/Core/IOHandler.cpp
===================================================================
--- source/Core/IOHandler.cpp
+++ source/Core/IOHandler.cpp
@@ -3232,7 +3232,7 @@
                 ThreadSP thread_sp = GetThread (item);
                 if (thread_sp)
                 {
-                    ThreadList &thread_list = thread_sp->GetProcess()->GetThreadList();
+                    ProcessThreadList &thread_list = thread_sp->GetProcess()->GetThreadList();
                     Mutex::Locker locker (thread_list.GetMutex());
                     ThreadSP selected_thread_sp = thread_list.GetSelectedThread();
                     if (selected_thread_sp->GetID() != thread_sp->GetID())
@@ -3315,7 +3315,7 @@
                 }
                 
                 TreeItem t (&item, *m_thread_delegate_sp, false);
-                ThreadList &threads = process_sp->GetThreadList();
+                ProcessThreadList &threads = process_sp->GetThreadList();
                 Mutex::Locker locker (threads.GetMutex());
                 size_t num_threads = threads.GetSize();
                 item.Resize (num_threads, t);
@@ -4333,7 +4333,7 @@
                         else if (submenus.size() > 8)
                             submenus.erase (submenus.begin() + 8, submenus.end());
                         
-                        ThreadList &threads = process->GetThreadList();
+                        ProcessThreadList &threads = process->GetThreadList();
                         Mutex::Locker locker (threads.GetMutex());
                         size_t num_threads = threads.GetSize();
                         for (size_t i=0; i<num_threads; ++i)
Index: source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
===================================================================
--- source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
+++ source/Plugins/ObjectFile/Mach-O/ObjectFileMachO.cpp
@@ -5306,7 +5306,7 @@
                     mach_header.ncmds = segment_load_commands.size();
                     mach_header.flags = 0;
                     mach_header.reserved = 0;
-                    ThreadList &thread_list = process_sp->GetThreadList();
+                    ProcessThreadList &thread_list = process_sp->GetThreadList();
                     const uint32_t num_threads = thread_list.GetSize();
 
                     // Make an array of LC_THREAD data items. Each one contains
Index: source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
===================================================================
--- source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
+++ source/Plugins/OperatingSystem/Python/OperatingSystemPython.cpp
@@ -167,9 +167,9 @@
 }
 
 bool
-OperatingSystemPython::UpdateThreadList (ThreadList &old_thread_list,
-                                         ThreadList &core_thread_list,
-                                         ThreadList &new_thread_list)
+OperatingSystemPython::UpdateThreadList (ProcessThreadList &old_thread_list,
+                                         ProcessThreadList &core_thread_list,
+                                         ProcessThreadList &new_thread_list)
 {
     if (!m_interpreter || !m_python_object_sp)
         return false;
@@ -240,8 +240,8 @@
 
 ThreadSP
 OperatingSystemPython::CreateThreadFromThreadInfo (PythonDictionary &thread_dict,
-                                                   ThreadList &core_thread_list,
-                                                   ThreadList &old_thread_list,
+                                                   ProcessThreadList &core_thread_list,
+                                                   ProcessThreadList &old_thread_list,
                                                    std::vector<bool> &core_used_map,
                                                    bool *did_create_ptr)
 {
@@ -421,8 +421,8 @@
         std::vector<bool> core_used_map;
         if (thread_info_dict)
         {
-            ThreadList core_threads(m_process);
-            ThreadList &thread_list = m_process->GetThreadList();
+            ProcessThreadList core_threads(m_process);
+            ProcessThreadList &thread_list = m_process->GetThreadList();
             bool did_create = false;
             ThreadSP thread_sp (CreateThreadFromThreadInfo (thread_info_dict, core_threads, thread_list, core_used_map, &did_create));
             if (did_create)
Index: source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
===================================================================
--- source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
+++ source/Plugins/OperatingSystem/Python/OperatingSystemPython.h
@@ -62,9 +62,9 @@
     // lldb_private::OperatingSystem Methods
     //------------------------------------------------------------------
     virtual bool
-    UpdateThreadList (lldb_private::ThreadList &old_thread_list,
-                      lldb_private::ThreadList &real_thread_list,
-                      lldb_private::ThreadList &new_thread_list);
+    UpdateThreadList (lldb_private::ProcessThreadList &old_thread_list,
+                      lldb_private::ProcessThreadList &real_thread_list,
+                      lldb_private::ProcessThreadList &new_thread_list);
     
     virtual void
     ThreadWasSelected (lldb_private::Thread *thread);
@@ -91,8 +91,8 @@
     
     lldb::ThreadSP
     CreateThreadFromThreadInfo (lldb_private::PythonDictionary &thread_dict,
-                                lldb_private::ThreadList &core_thread_list,
-                                lldb_private::ThreadList &old_thread_list,
+                                lldb_private::ProcessThreadList &core_thread_list,
+                                lldb_private::ProcessThreadList &old_thread_list,
                                 std::vector<bool> &core_used_map,
                                 bool *did_create_ptr);
 
Index: source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
===================================================================
--- source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
+++ source/Plugins/Process/MacOSX-Kernel/ProcessKDP.cpp
@@ -575,7 +575,7 @@
 
 
 bool
-ProcessKDP::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
+ProcessKDP::UpdateThreadList (ProcessThreadList &old_thread_list, ProcessThreadList &new_thread_list)
 {
     // locker will keep a mutex locked until it goes out of scope
     Log *log (ProcessKDPLog::GetLogIfAllCategoriesSet (KDP_LOG_THREAD));
Index: source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
===================================================================
--- source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
+++ source/Plugins/Process/MacOSX-Kernel/ProcessKDP.h
@@ -229,8 +229,8 @@
     Clear ( );
     
     virtual bool
-    UpdateThreadList (lldb_private::ThreadList &old_thread_list, 
-                      lldb_private::ThreadList &new_thread_list);
+    UpdateThreadList (lldb_private::ProcessThreadList &old_thread_list,
+                      lldb_private::ProcessThreadList &new_thread_list);
     
     enum
     {
Index: source/Plugins/Process/elf-core/ProcessElfCore.cpp
===================================================================
--- source/Plugins/Process/elf-core/ProcessElfCore.cpp
+++ source/Plugins/Process/elf-core/ProcessElfCore.cpp
@@ -264,7 +264,7 @@
 }
 
 bool
-ProcessElfCore::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
+ProcessElfCore::UpdateThreadList (ProcessThreadList &old_thread_list, ProcessThreadList &new_thread_list)
 {
     const uint32_t num_threads = GetNumThreadContexts ();
     if (!m_thread_data_valid)
Index: source/Plugins/Process/elf-core/ProcessElfCore.h
===================================================================
--- source/Plugins/Process/elf-core/ProcessElfCore.h
+++ source/Plugins/Process/elf-core/ProcessElfCore.h
@@ -127,8 +127,8 @@
     Clear ( );
 
     virtual bool
-    UpdateThreadList (lldb_private::ThreadList &old_thread_list,
-                      lldb_private::ThreadList &new_thread_list);
+    UpdateThreadList (lldb_private::ProcessThreadList &old_thread_list,
+                      lldb_private::ProcessThreadList &new_thread_list);
 
 private:
     //------------------------------------------------------------------
Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
===================================================================
--- source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
+++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.cpp
@@ -1482,7 +1482,7 @@
 }
 
 bool
-ProcessGDBRemote::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
+ProcessGDBRemote::UpdateThreadList (ProcessThreadList &old_thread_list, ProcessThreadList &new_thread_list)
 {
     // locker will keep a mutex locked until it goes out of scope
     Log *log (ProcessGDBRemoteLog::GetLogIfAllCategoriesSet (GDBR_LOG_THREAD));
@@ -1499,7 +1499,7 @@
         num_thread_ids = m_thread_ids.size();
     }
 
-    ThreadList old_thread_list_copy(old_thread_list);
+    ProcessThreadList old_thread_list_copy(old_thread_list);
     if (num_thread_ids > 0)
     {
         for (size_t i=0; i<num_thread_ids; ++i)
@@ -1991,7 +1991,7 @@
                 DisableAllBreakpointSites();
                 
                 bool stop_looks_like_crash = false;
-                ThreadList &threads = GetThreadList();
+                ProcessThreadList &threads = GetThreadList();
                 
                 {
                     Mutex::Locker locker(threads.GetMutex());
Index: source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
===================================================================
--- source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
+++ source/Plugins/Process/gdb-remote/ProcessGDBRemote.h
@@ -285,8 +285,8 @@
     }
 
     virtual bool
-    UpdateThreadList (lldb_private::ThreadList &old_thread_list, 
-                      lldb_private::ThreadList &new_thread_list);
+    UpdateThreadList (lldb_private::ProcessThreadList &old_thread_list,
+                      lldb_private::ProcessThreadList &new_thread_list);
 
     lldb_private::Error
     LaunchAndConnectToDebugserver (const lldb_private::ProcessInfo &process_info);
Index: source/Plugins/Process/mach-core/ProcessMachCore.cpp
===================================================================
--- source/Plugins/Process/mach-core/ProcessMachCore.cpp
+++ source/Plugins/Process/mach-core/ProcessMachCore.cpp
@@ -375,7 +375,7 @@
 }
 
 bool
-ProcessMachCore::UpdateThreadList (ThreadList &old_thread_list, ThreadList &new_thread_list)
+ProcessMachCore::UpdateThreadList (ProcessThreadList &old_thread_list, ProcessThreadList &new_thread_list)
 {
     if (old_thread_list.GetSize(false) == 0)
     {
Index: source/Plugins/Process/mach-core/ProcessMachCore.h
===================================================================
--- source/Plugins/Process/mach-core/ProcessMachCore.h
+++ source/Plugins/Process/mach-core/ProcessMachCore.h
@@ -118,8 +118,8 @@
     Clear ( );
     
     virtual bool
-    UpdateThreadList (lldb_private::ThreadList &old_thread_list, 
-                      lldb_private::ThreadList &new_thread_list);
+    UpdateThreadList (lldb_private::ProcessThreadList &old_thread_list,
+                      lldb_private::ProcessThreadList &new_thread_list);
     
     lldb_private::ObjectFile *
     GetCoreObjectFile ();
Index: source/Target/Process.cpp
===================================================================
--- source/Target/Process.cpp
+++ source/Target/Process.cpp
@@ -1279,9 +1280,9 @@
             // m_thread_list does have its own mutex, but we need to
             // hold onto the mutex between the call to UpdateThreadList(...)
             // and the os->UpdateThreadList(...) so it doesn't change on us
-            ThreadList &old_thread_list = m_thread_list;
-            ThreadList real_thread_list(this);
-            ThreadList new_thread_list(this);
+            ProcessThreadList &old_thread_list = m_thread_list;
+            ProcessThreadList real_thread_list(this);
+            ProcessThreadList new_thread_list(this);
             // Always update the thread list with the protocol specific
             // thread list, but only update if "true" is returned
             if (UpdateThreadList (m_thread_list_real, real_thread_list))
@@ -4244,7 +4245,7 @@
     // If we're stopped and haven't restarted, then do the StopInfo actions here:
     if (m_state == eStateStopped && ! m_restarted)
     {        
-        ThreadList &curr_thread_list = m_process_sp->GetThreadList();
+        ProcessThreadList &curr_thread_list = m_process_sp->GetThreadList();
         uint32_t num_threads = curr_thread_list.GetSize();
         uint32_t idx;
 
@@ -5637,7 +5638,7 @@
                             break;
                         }
 
-                        ThreadList &thread_list = process->GetThreadList();
+                        ProcessThreadList &thread_list = process->GetThreadList();
 
                         uint32_t num_threads = thread_list.GetSize();
                         uint32_t thread_index;
@@ -5861,7 +5862,7 @@
     //Scope for thread list locker;
     {
         Mutex::Locker locker (GetThreadList().GetMutex());
-        ThreadList &curr_thread_list = GetThreadList();
+        ProcessThreadList &curr_thread_list = GetThreadList();
         num_threads = curr_thread_list.GetSize();
         uint32_t idx;
         thread_index_array.resize(num_threads);
Index: source/Target/ProcessThreadList.cpp
===================================================================
--- source/Target/ProcessThreadList.cpp
+++ source/Target/ProcessThreadList.cpp
@@ -0,0 +1,800 @@
+//===-- ProcessThreadList.cpp -----------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+#include <stdlib.h>
+
+#include <algorithm>
+
+#include "lldb/Core/Log.h"
+#include "lldb/Core/State.h"
+#include "lldb/Target/RegisterContext.h"
+#include "lldb/Target/ProcessThreadList.h"
+#include "lldb/Target/Thread.h"
+#include "lldb/Target/ThreadPlan.h"
+#include "lldb/Target/Process.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+ProcessThreadList::ProcessThreadList (Process *process) :
+ThreadList (),
+m_process (process),
+m_stop_id (0),
+m_selected_tid (LLDB_INVALID_THREAD_ID)
+{
+}
+
+ProcessThreadList::ProcessThreadList (const ProcessThreadList &rhs) :
+ThreadList (),
+m_process (rhs.m_process),
+m_stop_id (rhs.m_stop_id),
+m_selected_tid ()
+{
+    // Use the assignment operator since it uses the mutex
+    *this = rhs;
+}
+
+const ProcessThreadList&
+ProcessThreadList::operator = (const ProcessThreadList& rhs)
+{
+    if (this != &rhs)
+    {
+        // Lock both mutexes to make sure neither side changes anyone on us
+        // while the assignement occurs
+        Mutex::Locker locker(GetMutex());
+        m_process = rhs.m_process;
+        m_stop_id = rhs.m_stop_id;
+        m_threads = rhs.m_threads;
+        m_selected_tid = rhs.m_selected_tid;
+    }
+    return *this;
+}
+
+
+ProcessThreadList::~ProcessThreadList()
+{
+    // Clear the thread list. Clear will take the mutex lock
+    // which will ensure that if anyone is using the list
+    // they won't get it removed while using it.
+    Clear();
+}
+
+
+uint32_t
+ProcessThreadList::GetStopID () const
+{
+    return m_stop_id;
+}
+
+void
+ProcessThreadList::SetStopID (uint32_t stop_id)
+{
+    m_stop_id = stop_id;
+}
+
+uint32_t
+ProcessThreadList::GetSize (bool can_update)
+{
+    Mutex::Locker locker(GetMutex());
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+    return m_threads.size();
+}
+
+ThreadSP
+ProcessThreadList::GetThreadAtIndex (uint32_t idx, bool can_update)
+{
+    Mutex::Locker locker(GetMutex());
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+    
+    ThreadSP thread_sp;
+    if (idx < m_threads.size())
+        thread_sp = m_threads[idx];
+    return thread_sp;
+}
+
+ThreadSP
+ProcessThreadList::FindThreadByID (lldb::tid_t tid, bool can_update)
+{
+    Mutex::Locker locker(GetMutex());
+    
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+    
+    ThreadSP thread_sp;
+    uint32_t idx = 0;
+    const uint32_t num_threads = m_threads.size();
+    for (idx = 0; idx < num_threads; ++idx)
+    {
+        if (m_threads[idx]->GetID() == tid)
+        {
+            thread_sp = m_threads[idx];
+            break;
+        }
+    }
+    return thread_sp;
+}
+
+ThreadSP
+ProcessThreadList::FindThreadByProtocolID (lldb::tid_t tid, bool can_update)
+{
+    Mutex::Locker locker(GetMutex());
+    
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+    
+    ThreadSP thread_sp;
+    uint32_t idx = 0;
+    const uint32_t num_threads = m_threads.size();
+    for (idx = 0; idx < num_threads; ++idx)
+    {
+        if (m_threads[idx]->GetProtocolID() == tid)
+        {
+            thread_sp = m_threads[idx];
+            break;
+        }
+    }
+    return thread_sp;
+}
+
+
+ThreadSP
+ProcessThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update)
+{
+    Mutex::Locker locker(GetMutex());
+    
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+    
+    ThreadSP thread_sp;
+    uint32_t idx = 0;
+    const uint32_t num_threads = m_threads.size();
+    for (idx = 0; idx < num_threads; ++idx)
+    {
+        if (m_threads[idx]->GetID() == tid)
+        {
+            thread_sp = m_threads[idx];
+            m_threads.erase(m_threads.begin()+idx);
+            break;
+        }
+    }
+    return thread_sp;
+}
+
+ThreadSP
+ProcessThreadList::RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update)
+{
+    Mutex::Locker locker(GetMutex());
+    
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+    
+    ThreadSP thread_sp;
+    uint32_t idx = 0;
+    const uint32_t num_threads = m_threads.size();
+    for (idx = 0; idx < num_threads; ++idx)
+    {
+        if (m_threads[idx]->GetProtocolID() == tid)
+        {
+            thread_sp = m_threads[idx];
+            m_threads.erase(m_threads.begin()+idx);
+            break;
+        }
+    }
+    return thread_sp;
+}
+
+ThreadSP
+ProcessThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr)
+{
+    ThreadSP thread_sp;
+    if (thread_ptr)
+    {
+        Mutex::Locker locker(GetMutex());
+        
+        uint32_t idx = 0;
+        const uint32_t num_threads = m_threads.size();
+        for (idx = 0; idx < num_threads; ++idx)
+        {
+            if (m_threads[idx].get() == thread_ptr)
+            {
+                thread_sp = m_threads[idx];
+                break;
+            }
+        }
+    }
+    return thread_sp;
+}
+
+
+
+ThreadSP
+ProcessThreadList::FindThreadByIndexID (uint32_t index_id, bool can_update)
+{
+    Mutex::Locker locker(GetMutex());
+    
+    if (can_update)
+        m_process->UpdateThreadListIfNeeded();
+    
+    ThreadSP thread_sp;
+    const uint32_t num_threads = m_threads.size();
+    for (uint32_t idx = 0; idx < num_threads; ++idx)
+    {
+        if (m_threads[idx]->GetIndexID() == index_id)
+        {
+            thread_sp = m_threads[idx];
+            break;
+        }
+    }
+    return thread_sp;
+}
+
+bool
+ProcessThreadList::ShouldStop (Event *event_ptr)
+{
+    // Running events should never stop, obviously...
+    
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    
+    // The ShouldStop method of the threads can do a whole lot of work,
+    // figuring out whether the thread plan conditions are met.  So we don't want
+    // to keep the ThreadList locked the whole time we are doing this.
+    // FIXME: It is possible that running code could cause new threads
+    // to be created.  If that happens we will miss asking them whether
+    // then should stop.  This is not a big deal, since we haven't had
+    // a chance to hang any interesting operations on those threads yet.
+    
+    collection threads_copy;
+    {
+        // Scope for locker
+        Mutex::Locker locker(GetMutex());
+        
+        m_process->UpdateThreadListIfNeeded();
+        threads_copy = m_threads;
+    }
+    
+    collection::iterator pos, end = threads_copy.end();
+    
+    if (log)
+    {
+        log->PutCString("");
+        log->Printf ("ThreadList::%s: %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size());
+    }
+    
+    bool did_anybody_stop_for_a_reason = false;
+    
+    // If the event is an Interrupt event, then we're going to stop no matter what.  Otherwise, presume we won't stop.
+    bool should_stop = false;
+    if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr))
+    {
+        if (log)
+            log->Printf("ThreadList::%s handling interrupt event, should stop set to true", __FUNCTION__);
+        
+        should_stop = true;
+    }
+    
+    // Now we run through all the threads and get their stop info's.  We want to make sure to do this first before
+    // we start running the ShouldStop, because one thread's ShouldStop could destroy information (like deleting a
+    // thread specific breakpoint another thread had stopped at) which could lead us to compute the StopInfo incorrectly.
+    // We don't need to use it here, we just want to make sure it gets computed.
+    
+    for (pos = threads_copy.begin(); pos != end; ++pos)
+    {
+        ThreadSP thread_sp(*pos);
+        thread_sp->GetStopInfo();
+    }
+    
+    for (pos = threads_copy.begin(); pos != end; ++pos)
+    {
+        ThreadSP thread_sp(*pos);
+        
+        // We should never get a stop for which no thread had a stop reason, but sometimes we do see this -
+        // for instance when we first connect to a remote stub.  In that case we should stop, since we can't figure out
+        // the right thing to do and stopping gives the user control over what to do in this instance.
+        //
+        // Note, this causes a problem when you have a thread specific breakpoint, and a bunch of threads hit the breakpoint,
+        // but not the thread which we are waiting for.  All the threads that are not "supposed" to hit the breakpoint
+        // are marked as having no stop reason, which is right, they should not show a stop reason.  But that triggers this
+        // code and causes us to stop seemingly for no reason.
+        //
+        // Since the only way we ever saw this error was on first attach, I'm only going to trigger set did_anybody_stop_for_a_reason
+        // to true unless this is the first stop.
+        //
+        // If this becomes a problem, we'll have to have another StopReason like "StopInfoHidden" which will look invalid
+        // everywhere but at this check.
+        
+        if (thread_sp->GetProcess()->GetStopID() > 1)
+            did_anybody_stop_for_a_reason = true;
+        else
+            did_anybody_stop_for_a_reason |= thread_sp->ThreadStoppedForAReason();
+        
+        const bool thread_should_stop = thread_sp->ShouldStop(event_ptr);
+        if (thread_should_stop)
+            should_stop |= true;
+    }
+    
+    if (!should_stop && !did_anybody_stop_for_a_reason)
+    {
+        should_stop = true;
+        if (log)
+            log->Printf ("ThreadList::%s we stopped but no threads had a stop reason, overriding should_stop and stopping.", __FUNCTION__);
+    }
+    
+    if (log)
+        log->Printf ("ThreadList::%s overall should_stop = %i", __FUNCTION__, should_stop);
+    
+    if (should_stop)
+    {
+        for (pos = threads_copy.begin(); pos != end; ++pos)
+        {
+            ThreadSP thread_sp(*pos);
+            thread_sp->WillStop ();
+        }
+    }
+    
+    return should_stop;
+}
+
+Vote
+ProcessThreadList::ShouldReportStop (Event *event_ptr)
+{
+    Mutex::Locker locker(GetMutex());
+    
+    Vote result = eVoteNoOpinion;
+    m_process->UpdateThreadListIfNeeded();
+    collection::iterator pos, end = m_threads.end();
+    
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    
+    if (log)
+        log->Printf ("ThreadList::%s %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size());
+    
+    // Run through the threads and ask whether we should report this event.
+    // For stopping, a YES vote wins over everything.  A NO vote wins over NO opinion.
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        ThreadSP thread_sp(*pos);
+        const Vote vote = thread_sp->ShouldReportStop (event_ptr);
+        switch (vote)
+        {
+            case eVoteNoOpinion:
+                continue;
+                
+            case eVoteYes:
+                result = eVoteYes;
+                break;
+                
+            case eVoteNo:
+                if (result == eVoteNoOpinion)
+                {
+                    result = eVoteNo;
+                }
+                else
+                {
+                    if (log)
+                        log->Printf ("ThreadList::%s thread 0x%4.4" PRIx64 ": voted %s, but lost out because result was %s",
+                                     __FUNCTION__,
+                                     thread_sp->GetID (),
+                                     GetVoteAsCString (vote),
+                                     GetVoteAsCString (result));
+                }
+                break;
+        }
+    }
+    if (log)
+        log->Printf ("ThreadList::%s returning %s", __FUNCTION__, GetVoteAsCString (result));
+    return result;
+}
+
+void
+ProcessThreadList::SetShouldReportStop (Vote vote)
+{
+    Mutex::Locker locker(GetMutex());
+    m_process->UpdateThreadListIfNeeded();
+    collection::iterator pos, end = m_threads.end();
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        ThreadSP thread_sp(*pos);
+        thread_sp->SetShouldReportStop (vote);
+    }
+}
+
+Vote
+ProcessThreadList::ShouldReportRun (Event *event_ptr)
+{
+    
+    Mutex::Locker locker(GetMutex());
+    
+    Vote result = eVoteNoOpinion;
+    m_process->UpdateThreadListIfNeeded();
+    collection::iterator pos, end = m_threads.end();
+    
+    // Run through the threads and ask whether we should report this event.
+    // The rule is NO vote wins over everything, a YES vote wins over no opinion.
+    
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        if ((*pos)->GetResumeState () != eStateSuspended)
+        {
+            switch ((*pos)->ShouldReportRun (event_ptr))
+            {
+                case eVoteNoOpinion:
+                    continue;
+                case eVoteYes:
+                    if (result == eVoteNoOpinion)
+                        result = eVoteYes;
+                    break;
+                case eVoteNo:
+                    if (log)
+                        log->Printf ("ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64 ") says don't report.",
+                                     (*pos)->GetIndexID(),
+                                     (*pos)->GetID());
+                    result = eVoteNo;
+                    break;
+            }
+        }
+    }
+    return result;
+}
+
+void
+ProcessThreadList::Clear()
+{
+    Mutex::Locker locker(GetMutex());
+    m_stop_id = 0;
+    m_threads.clear();
+    m_selected_tid = LLDB_INVALID_THREAD_ID;
+}
+
+void
+ProcessThreadList::Destroy()
+{
+    Mutex::Locker locker(GetMutex());
+    const uint32_t num_threads = m_threads.size();
+    for (uint32_t idx = 0; idx < num_threads; ++idx)
+    {
+        m_threads[idx]->DestroyThread();
+    }
+}
+
+void
+ProcessThreadList::RefreshStateAfterStop ()
+{
+    Mutex::Locker locker(GetMutex());
+    
+    m_process->UpdateThreadListIfNeeded();
+    
+    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+    if (log && log->GetVerbose())
+        log->Printf ("Turning off notification of new threads while single stepping a thread.");
+    
+    collection::iterator pos, end = m_threads.end();
+    for (pos = m_threads.begin(); pos != end; ++pos)
+        (*pos)->RefreshStateAfterStop ();
+}
+
+void
+ProcessThreadList::DiscardThreadPlans ()
+{
+    // You don't need to update the thread list here, because only threads
+    // that you currently know about have any thread plans.
+    Mutex::Locker locker(GetMutex());
+    
+    collection::iterator pos, end = m_threads.end();
+    for (pos = m_threads.begin(); pos != end; ++pos)
+        (*pos)->DiscardThreadPlans (true);
+    
+}
+
+bool
+ProcessThreadList::WillResume ()
+{
+    // Run through the threads and perform their momentary actions.
+    // But we only do this for threads that are running, user suspended
+    // threads stay where they are.
+    
+    Mutex::Locker locker(GetMutex());
+    m_process->UpdateThreadListIfNeeded();
+    
+    collection::iterator pos, end = m_threads.end();
+    
+    // See if any thread wants to run stopping others.  If it does, then we won't
+    // setup the other threads for resume, since they aren't going to get a chance
+    // to run.  This is necessary because the SetupForResume might add "StopOthers"
+    // plans which would then get to be part of the who-gets-to-run negotiation, but
+    // they're coming in after the fact, and the threads that are already set up should
+    // take priority.
+    
+    bool wants_solo_run = false;
+    
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        if ((*pos)->GetResumeState() != eStateSuspended &&
+            (*pos)->GetCurrentPlan()->StopOthers())
+        {
+            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
+                continue;
+            wants_solo_run = true;
+            break;
+        }
+    }
+    
+    if (wants_solo_run)
+    {
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+        if (log && log->GetVerbose())
+            log->Printf ("Turning on notification of new threads while single stepping a thread.");
+        m_process->StartNoticingNewThreads();
+    }
+    else
+    {
+        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
+        if (log && log->GetVerbose())
+            log->Printf ("Turning off notification of new threads while single stepping a thread.");
+        m_process->StopNoticingNewThreads();
+    }
+    
+    // Give all the threads that are likely to run a last chance to set up their state before we
+    // negotiate who is actually going to get a chance to run...
+    // Don't set to resume suspended threads, and if any thread wanted to stop others, only
+    // call setup on the threads that request StopOthers...
+    
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        if ((*pos)->GetResumeState() != eStateSuspended
+            && (!wants_solo_run || (*pos)->GetCurrentPlan()->StopOthers()))
+        {
+            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
+                continue;
+            (*pos)->SetupForResume ();
+        }
+    }
+    
+    // Now go through the threads and see if any thread wants to run just itself.
+    // if so then pick one and run it.
+    
+    ProcessThreadList run_me_only_list (m_process);
+    
+    run_me_only_list.SetStopID(m_process->GetStopID());
+    
+    bool run_only_current_thread = false;
+    
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        ThreadSP thread_sp(*pos);
+        if (thread_sp->GetResumeState() != eStateSuspended &&
+            thread_sp->GetCurrentPlan()->StopOthers())
+        {
+            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
+                continue;
+            
+            // You can't say "stop others" and also want yourself to be suspended.
+            assert (thread_sp->GetCurrentPlan()->RunState() != eStateSuspended);
+            
+            if (thread_sp == GetSelectedThread())
+            {
+                run_only_current_thread = true;
+                run_me_only_list.Clear();
+                run_me_only_list.AddThread (thread_sp);
+                break;
+            }
+            
+            run_me_only_list.AddThread (thread_sp);
+        }
+        
+    }
+    
+    bool need_to_resume = true;
+    
+    if (run_me_only_list.GetSize (false) == 0)
+    {
+        // Everybody runs as they wish:
+        for (pos = m_threads.begin(); pos != end; ++pos)
+        {
+            ThreadSP thread_sp(*pos);
+            StateType run_state;
+            if (thread_sp->GetResumeState() != eStateSuspended)
+                run_state = thread_sp->GetCurrentPlan()->RunState();
+            else
+                run_state = eStateSuspended;
+            if (!thread_sp->ShouldResume(run_state))
+                need_to_resume = false;
+        }
+    }
+    else
+    {
+        ThreadSP thread_to_run;
+        
+        if (run_only_current_thread)
+        {
+            thread_to_run = GetSelectedThread();
+        }
+        else if (run_me_only_list.GetSize (false) == 1)
+        {
+            thread_to_run = run_me_only_list.GetThreadAtIndex (0);
+        }
+        else
+        {
+            int random_thread = (int)
+            ((run_me_only_list.GetSize (false) * (double) rand ()) / (RAND_MAX + 1.0));
+            thread_to_run = run_me_only_list.GetThreadAtIndex (random_thread);
+        }
+        
+        for (pos = m_threads.begin(); pos != end; ++pos)
+        {
+            ThreadSP thread_sp(*pos);
+            if (thread_sp == thread_to_run)
+            {
+                if (!thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState()))
+                    need_to_resume = false;
+            }
+            else
+                thread_sp->ShouldResume (eStateSuspended);
+        }
+    }
+    
+    return need_to_resume;
+}
+
+void
+ProcessThreadList::DidResume ()
+{
+    Mutex::Locker locker(GetMutex());
+    collection::iterator pos, end = m_threads.end();
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        // Don't clear out threads that aren't going to get a chance to run, rather
+        // leave their state for the next time around.
+        ThreadSP thread_sp(*pos);
+        if (thread_sp->GetResumeState() != eStateSuspended)
+            thread_sp->DidResume ();
+    }
+}
+
+void
+ProcessThreadList::DidStop ()
+{
+    Mutex::Locker locker(GetMutex());
+    collection::iterator pos, end = m_threads.end();
+    for (pos = m_threads.begin(); pos != end; ++pos)
+    {
+        // Notify threads that the process just stopped.
+        // Note, this currently assumes that all threads in the list
+        // stop when the process stops.  In the future we will want to support
+        // a debugging model where some threads continue to run while others
+        // are stopped.  We either need to handle that somehow here or
+        // create a special thread list containing only threads which will
+        // stop in the code that calls this method (currently
+        // Process::SetPrivateState).
+        ThreadSP thread_sp(*pos);
+        if (StateIsRunningState(thread_sp->GetState()))
+            thread_sp->DidStop ();
+    }
+}
+
+ThreadSP
+ProcessThreadList::GetSelectedThread ()
+{
+    Mutex::Locker locker(GetMutex());
+    ThreadSP thread_sp = FindThreadByID(m_selected_tid);
+    if (!thread_sp.get())
+    {
+        if (m_threads.size() == 0)
+            return thread_sp;
+        m_selected_tid = m_threads[0]->GetID();
+        thread_sp = m_threads[0];
+    }
+    return thread_sp;
+}
+
+bool
+ProcessThreadList::SetSelectedThreadByID (lldb::tid_t tid, bool notify)
+{
+    Mutex::Locker locker(GetMutex());
+    ThreadSP selected_thread_sp(FindThreadByID(tid));
+    if  (selected_thread_sp)
+    {
+        m_selected_tid = tid;
+        selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
+    }
+    else
+        m_selected_tid = LLDB_INVALID_THREAD_ID;
+    
+    if (notify)
+        NotifySelectedThreadChanged(m_selected_tid);
+    
+    return m_selected_tid != LLDB_INVALID_THREAD_ID;
+}
+
+bool
+ProcessThreadList::SetSelectedThreadByIndexID (uint32_t index_id, bool notify)
+{
+    Mutex::Locker locker(GetMutex());
+    ThreadSP selected_thread_sp (FindThreadByIndexID(index_id));
+    if  (selected_thread_sp.get())
+    {
+        m_selected_tid = selected_thread_sp->GetID();
+        selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
+    }
+    else
+        m_selected_tid = LLDB_INVALID_THREAD_ID;
+    
+    if (notify)
+        NotifySelectedThreadChanged(m_selected_tid);
+    
+    return m_selected_tid != LLDB_INVALID_THREAD_ID;
+}
+
+void
+ProcessThreadList::NotifySelectedThreadChanged (lldb::tid_t tid)
+{
+    ThreadSP selected_thread_sp (FindThreadByID(tid));
+    if (selected_thread_sp->EventTypeHasListeners(Thread::eBroadcastBitThreadSelected))
+        selected_thread_sp->BroadcastEvent(Thread::eBroadcastBitThreadSelected,
+                                           new Thread::ThreadEventData(selected_thread_sp));
+}
+
+void
+ProcessThreadList::Update (ProcessThreadList &rhs)
+{
+    if (this != &rhs)
+    {
+        // Lock both mutexes to make sure neither side changes anyone on us
+        // while the assignement occurs
+        Mutex::Locker locker(GetMutex());
+        m_process = rhs.m_process;
+        m_stop_id = rhs.m_stop_id;
+        m_threads.swap(rhs.m_threads);
+        m_selected_tid = rhs.m_selected_tid;
+        
+        
+        // Now we look for threads that we are done with and
+        // make sure to clear them up as much as possible so
+        // anyone with a shared pointer will still have a reference,
+        // but the thread won't be of much use. Using std::weak_ptr
+        // for all backward references (such as a thread to a process)
+        // will eventually solve this issue for us, but for now, we
+        // need to work around the issue
+        collection::iterator rhs_pos, rhs_end = rhs.m_threads.end();
+        for (rhs_pos = rhs.m_threads.begin(); rhs_pos != rhs_end; ++rhs_pos)
+        {
+            const lldb::tid_t tid = (*rhs_pos)->GetID();
+            bool thread_is_alive = false;
+            const uint32_t num_threads = m_threads.size();
+            for (uint32_t idx = 0; idx < num_threads; ++idx)
+            {
+                if (m_threads[idx]->GetID() == tid)
+                {
+                    thread_is_alive = true;
+                    break;
+                }
+            }
+            if (!thread_is_alive)
+                (*rhs_pos)->DestroyThread();
+        }
+    }
+}
+
+void
+ProcessThreadList::Flush ()
+{
+    Mutex::Locker locker(GetMutex());
+    collection::iterator pos, end = m_threads.end();
+    for (pos = m_threads.begin(); pos != end; ++pos)
+        (*pos)->Flush ();
+}
+
+Mutex &
+ProcessThreadList::GetMutex ()
+{
+    return m_process->m_thread_mutex;
+}
+
Index: source/Target/Target.cpp
===================================================================
--- source/Target/Target.cpp
+++ source/Target/Target.cpp
@@ -2109,7 +2109,7 @@
     std::vector<ExecutionContext> exc_ctx_with_reasons;
     std::vector<SymbolContext> sym_ctx_with_reasons;
     
-    ThreadList &cur_threadlist = m_process_sp->GetThreadList();
+    ProcessThreadList &cur_threadlist = m_process_sp->GetThreadList();
     size_t num_threads = cur_threadlist.GetSize();
     for (size_t i = 0; i < num_threads; i++)
     {
Index: source/Target/ThreadList.cpp
===================================================================
--- source/Target/ThreadList.cpp
+++ source/Target/ThreadList.cpp
@@ -6,79 +6,27 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-#include <stdlib.h>
 
-#include <algorithm>
-
-#include "lldb/Core/Log.h"
-#include "lldb/Core/State.h"
-#include "lldb/Target/RegisterContext.h"
 #include "lldb/Target/ThreadList.h"
-#include "lldb/Target/Thread.h"
-#include "lldb/Target/ThreadPlan.h"
-#include "lldb/Target/Process.h"
 
 using namespace lldb;
 using namespace lldb_private;
 
-ThreadList::ThreadList (Process *process) :
-    m_process (process),
-    m_stop_id (0),
-    m_threads(),
-    m_selected_tid (LLDB_INVALID_THREAD_ID)
+ThreadList::ThreadList() :
+m_threads(),
+m_mutex()
 {
+    
 }
 
-ThreadList::ThreadList (const ThreadList &rhs) :
-    m_process (rhs.m_process),
-    m_stop_id (rhs.m_stop_id),
-    m_threads (),
-    m_selected_tid ()
+ThreadList::ThreadList(collection threads) :
+m_threads(threads),
+m_mutex()
 {
-    // Use the assignment operator since it uses the mutex
-    *this = rhs;
+    
 }
 
-const ThreadList&
-ThreadList::operator = (const ThreadList& rhs)
-{
-    if (this != &rhs)
-    {
-        // Lock both mutexes to make sure neither side changes anyone on us
-        // while the assignement occurs
-        Mutex::Locker locker(GetMutex());
-        m_process = rhs.m_process;
-        m_stop_id = rhs.m_stop_id;
-        m_threads = rhs.m_threads;
-        m_selected_tid = rhs.m_selected_tid;
-    }
-    return *this;
-}
-
-
-ThreadList::~ThreadList()
-{
-    // Clear the thread list. Clear will take the mutex lock
-    // which will ensure that if anyone is using the list
-    // they won't get it removed while using it.
-    Clear();
-}
-
-
-uint32_t
-ThreadList::GetStopID () const
-{
-    return m_stop_id;
-}
-
 void
-ThreadList::SetStopID (uint32_t stop_id)
-{
-    m_stop_id = stop_id;
-}
-
-
-void
 ThreadList::AddThread (const ThreadSP &thread_sp)
 {
     Mutex::Locker locker(GetMutex());
@@ -95,725 +43,20 @@
         m_threads.push_back (thread_sp);
 }
 
-
 uint32_t
-ThreadList::GetSize (bool can_update)
+ThreadList::GetSize ()
 {
     Mutex::Locker locker(GetMutex());
-    if (can_update)
-        m_process->UpdateThreadListIfNeeded();
     return m_threads.size();
 }
 
 ThreadSP
-ThreadList::GetThreadAtIndex (uint32_t idx, bool can_update)
+ThreadList::GetThreadAtIndex (uint32_t idx)
 {
     Mutex::Locker locker(GetMutex());
-    if (can_update)
-        m_process->UpdateThreadListIfNeeded();
-
+    
     ThreadSP thread_sp;
     if (idx < m_threads.size())
         thread_sp = m_threads[idx];
     return thread_sp;
 }
-
-ThreadSP
-ThreadList::FindThreadByID (lldb::tid_t tid, bool can_update)
-{
-    Mutex::Locker locker(GetMutex());
-
-    if (can_update)
-        m_process->UpdateThreadListIfNeeded();
-
-    ThreadSP thread_sp;
-    uint32_t idx = 0;
-    const uint32_t num_threads = m_threads.size();
-    for (idx = 0; idx < num_threads; ++idx)
-    {
-        if (m_threads[idx]->GetID() == tid)
-        {
-            thread_sp = m_threads[idx];
-            break;
-        }
-    }
-    return thread_sp;
-}
-
-ThreadSP
-ThreadList::FindThreadByProtocolID (lldb::tid_t tid, bool can_update)
-{
-    Mutex::Locker locker(GetMutex());
-    
-    if (can_update)
-        m_process->UpdateThreadListIfNeeded();
-    
-    ThreadSP thread_sp;
-    uint32_t idx = 0;
-    const uint32_t num_threads = m_threads.size();
-    for (idx = 0; idx < num_threads; ++idx)
-    {
-        if (m_threads[idx]->GetProtocolID() == tid)
-        {
-            thread_sp = m_threads[idx];
-            break;
-        }
-    }
-    return thread_sp;
-}
-
-
-ThreadSP
-ThreadList::RemoveThreadByID (lldb::tid_t tid, bool can_update)
-{
-    Mutex::Locker locker(GetMutex());
-    
-    if (can_update)
-        m_process->UpdateThreadListIfNeeded();
-    
-    ThreadSP thread_sp;
-    uint32_t idx = 0;
-    const uint32_t num_threads = m_threads.size();
-    for (idx = 0; idx < num_threads; ++idx)
-    {
-        if (m_threads[idx]->GetID() == tid)
-        {
-            thread_sp = m_threads[idx];
-            m_threads.erase(m_threads.begin()+idx);
-            break;
-        }
-    }
-    return thread_sp;
-}
-
-ThreadSP
-ThreadList::RemoveThreadByProtocolID (lldb::tid_t tid, bool can_update)
-{
-    Mutex::Locker locker(GetMutex());
-    
-    if (can_update)
-        m_process->UpdateThreadListIfNeeded();
-    
-    ThreadSP thread_sp;
-    uint32_t idx = 0;
-    const uint32_t num_threads = m_threads.size();
-    for (idx = 0; idx < num_threads; ++idx)
-    {
-        if (m_threads[idx]->GetProtocolID() == tid)
-        {
-            thread_sp = m_threads[idx];
-            m_threads.erase(m_threads.begin()+idx);
-            break;
-        }
-    }
-    return thread_sp;
-}
-
-ThreadSP
-ThreadList::GetThreadSPForThreadPtr (Thread *thread_ptr)
-{
-    ThreadSP thread_sp;
-    if (thread_ptr)
-    {
-        Mutex::Locker locker(GetMutex());
-
-        uint32_t idx = 0;
-        const uint32_t num_threads = m_threads.size();
-        for (idx = 0; idx < num_threads; ++idx)
-        {
-            if (m_threads[idx].get() == thread_ptr)
-            {
-                thread_sp = m_threads[idx];
-                break;
-            }
-        }
-    }
-    return thread_sp;
-}
-
-
-
-ThreadSP
-ThreadList::FindThreadByIndexID (uint32_t index_id, bool can_update)
-{
-    Mutex::Locker locker(GetMutex());
-
-    if (can_update)
-        m_process->UpdateThreadListIfNeeded();
-
-    ThreadSP thread_sp;
-    const uint32_t num_threads = m_threads.size();
-    for (uint32_t idx = 0; idx < num_threads; ++idx)
-    {
-        if (m_threads[idx]->GetIndexID() == index_id)
-        {
-            thread_sp = m_threads[idx];
-            break;
-        }
-    }
-    return thread_sp;
-}
-
-bool
-ThreadList::ShouldStop (Event *event_ptr)
-{
-    // Running events should never stop, obviously...
-
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-
-    // The ShouldStop method of the threads can do a whole lot of work,
-    // figuring out whether the thread plan conditions are met.  So we don't want
-    // to keep the ThreadList locked the whole time we are doing this.
-    // FIXME: It is possible that running code could cause new threads
-    // to be created.  If that happens we will miss asking them whether
-    // then should stop.  This is not a big deal, since we haven't had
-    // a chance to hang any interesting operations on those threads yet.
-    
-    collection threads_copy;
-    {
-        // Scope for locker
-        Mutex::Locker locker(GetMutex());
-
-        m_process->UpdateThreadListIfNeeded();
-        threads_copy = m_threads;
-    }
-
-    collection::iterator pos, end = threads_copy.end();
-
-    if (log)
-    {
-        log->PutCString("");
-        log->Printf ("ThreadList::%s: %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size());
-    }
-
-    bool did_anybody_stop_for_a_reason = false;
-    
-    // If the event is an Interrupt event, then we're going to stop no matter what.  Otherwise, presume we won't stop.
-    bool should_stop = false;
-    if (Process::ProcessEventData::GetInterruptedFromEvent(event_ptr))
-    {
-        if (log)
-            log->Printf("ThreadList::%s handling interrupt event, should stop set to true", __FUNCTION__);
-        
-        should_stop = true;
-    }
-    
-    // Now we run through all the threads and get their stop info's.  We want to make sure to do this first before
-    // we start running the ShouldStop, because one thread's ShouldStop could destroy information (like deleting a
-    // thread specific breakpoint another thread had stopped at) which could lead us to compute the StopInfo incorrectly.
-    // We don't need to use it here, we just want to make sure it gets computed.
-    
-    for (pos = threads_copy.begin(); pos != end; ++pos)
-    {
-        ThreadSP thread_sp(*pos);
-        thread_sp->GetStopInfo();
-    }
-    
-    for (pos = threads_copy.begin(); pos != end; ++pos)
-    {
-        ThreadSP thread_sp(*pos);
-        
-        // We should never get a stop for which no thread had a stop reason, but sometimes we do see this -
-        // for instance when we first connect to a remote stub.  In that case we should stop, since we can't figure out
-        // the right thing to do and stopping gives the user control over what to do in this instance.
-        //
-        // Note, this causes a problem when you have a thread specific breakpoint, and a bunch of threads hit the breakpoint,
-        // but not the thread which we are waiting for.  All the threads that are not "supposed" to hit the breakpoint
-        // are marked as having no stop reason, which is right, they should not show a stop reason.  But that triggers this
-        // code and causes us to stop seemingly for no reason.
-        //
-        // Since the only way we ever saw this error was on first attach, I'm only going to trigger set did_anybody_stop_for_a_reason
-        // to true unless this is the first stop.
-        //
-        // If this becomes a problem, we'll have to have another StopReason like "StopInfoHidden" which will look invalid
-        // everywhere but at this check.
-    
-        if (thread_sp->GetProcess()->GetStopID() > 1)
-            did_anybody_stop_for_a_reason = true;
-        else
-            did_anybody_stop_for_a_reason |= thread_sp->ThreadStoppedForAReason();
-        
-        const bool thread_should_stop = thread_sp->ShouldStop(event_ptr);
-        if (thread_should_stop)
-            should_stop |= true;
-    }
-
-    if (!should_stop && !did_anybody_stop_for_a_reason)
-    {
-        should_stop = true;
-        if (log)
-            log->Printf ("ThreadList::%s we stopped but no threads had a stop reason, overriding should_stop and stopping.", __FUNCTION__);
-    }
-    
-    if (log)
-        log->Printf ("ThreadList::%s overall should_stop = %i", __FUNCTION__, should_stop);
-
-    if (should_stop)
-    {
-        for (pos = threads_copy.begin(); pos != end; ++pos)
-        {
-            ThreadSP thread_sp(*pos);
-            thread_sp->WillStop ();
-        }
-    }
-
-    return should_stop;
-}
-
-Vote
-ThreadList::ShouldReportStop (Event *event_ptr)
-{
-    Mutex::Locker locker(GetMutex());
-
-    Vote result = eVoteNoOpinion;
-    m_process->UpdateThreadListIfNeeded();
-    collection::iterator pos, end = m_threads.end();
-
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-
-    if (log)
-        log->Printf ("ThreadList::%s %" PRIu64 " threads", __FUNCTION__, (uint64_t)m_threads.size());
-
-    // Run through the threads and ask whether we should report this event.
-    // For stopping, a YES vote wins over everything.  A NO vote wins over NO opinion.
-    for (pos = m_threads.begin(); pos != end; ++pos)
-    {
-        ThreadSP thread_sp(*pos);
-        const Vote vote = thread_sp->ShouldReportStop (event_ptr);
-        switch (vote)
-        {
-        case eVoteNoOpinion:
-            continue;
-
-        case eVoteYes:
-            result = eVoteYes;
-            break;
-
-        case eVoteNo:
-            if (result == eVoteNoOpinion)
-            {
-                result = eVoteNo;
-            }
-            else
-            {
-                if (log)
-                    log->Printf ("ThreadList::%s thread 0x%4.4" PRIx64 ": voted %s, but lost out because result was %s",
-                                 __FUNCTION__,
-                                 thread_sp->GetID (), 
-                                 GetVoteAsCString (vote),
-                                 GetVoteAsCString (result));
-            }
-            break;
-        }
-    }
-    if (log)
-        log->Printf ("ThreadList::%s returning %s", __FUNCTION__, GetVoteAsCString (result));
-    return result;
-}
-
-void
-ThreadList::SetShouldReportStop (Vote vote)
-{
-    Mutex::Locker locker(GetMutex());
-    m_process->UpdateThreadListIfNeeded();
-    collection::iterator pos, end = m_threads.end();
-    for (pos = m_threads.begin(); pos != end; ++pos)
-    {
-        ThreadSP thread_sp(*pos);
-        thread_sp->SetShouldReportStop (vote);
-    }
-}
-
-Vote
-ThreadList::ShouldReportRun (Event *event_ptr)
-{
-
-    Mutex::Locker locker(GetMutex());
-
-    Vote result = eVoteNoOpinion;
-    m_process->UpdateThreadListIfNeeded();
-    collection::iterator pos, end = m_threads.end();
-
-    // Run through the threads and ask whether we should report this event.
-    // The rule is NO vote wins over everything, a YES vote wins over no opinion.
-
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    
-    for (pos = m_threads.begin(); pos != end; ++pos)
-    {
-        if ((*pos)->GetResumeState () != eStateSuspended)
-        {
-            switch ((*pos)->ShouldReportRun (event_ptr))
-            {
-                case eVoteNoOpinion:
-                    continue;
-                case eVoteYes:
-                    if (result == eVoteNoOpinion)
-                        result = eVoteYes;
-                    break;
-                case eVoteNo:
-                    if (log)
-                        log->Printf ("ThreadList::ShouldReportRun() thread %d (0x%4.4" PRIx64 ") says don't report.",
-                                     (*pos)->GetIndexID(), 
-                                     (*pos)->GetID());
-                    result = eVoteNo;
-                    break;
-            }
-        }
-    }
-    return result;
-}
-
-void
-ThreadList::Clear()
-{
-    Mutex::Locker locker(GetMutex());
-    m_stop_id = 0;
-    m_threads.clear();
-    m_selected_tid = LLDB_INVALID_THREAD_ID;
-}
-
-void
-ThreadList::Destroy()
-{
-    Mutex::Locker locker(GetMutex());
-    const uint32_t num_threads = m_threads.size();
-    for (uint32_t idx = 0; idx < num_threads; ++idx)
-    {
-        m_threads[idx]->DestroyThread();
-    }
-}
-
-void
-ThreadList::RefreshStateAfterStop ()
-{
-    Mutex::Locker locker(GetMutex());
-
-    m_process->UpdateThreadListIfNeeded();
-    
-    Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-    if (log && log->GetVerbose())
-        log->Printf ("Turning off notification of new threads while single stepping a thread.");
-
-    collection::iterator pos, end = m_threads.end();
-    for (pos = m_threads.begin(); pos != end; ++pos)
-        (*pos)->RefreshStateAfterStop ();
-}
-
-void
-ThreadList::DiscardThreadPlans ()
-{
-    // You don't need to update the thread list here, because only threads
-    // that you currently know about have any thread plans.
-    Mutex::Locker locker(GetMutex());
-
-    collection::iterator pos, end = m_threads.end();
-    for (pos = m_threads.begin(); pos != end; ++pos)
-        (*pos)->DiscardThreadPlans (true);
-
-}
-
-bool
-ThreadList::WillResume ()
-{
-    // Run through the threads and perform their momentary actions.
-    // But we only do this for threads that are running, user suspended
-    // threads stay where they are.
-
-    Mutex::Locker locker(GetMutex());
-    m_process->UpdateThreadListIfNeeded();
-
-    collection::iterator pos, end = m_threads.end();
-
-    // See if any thread wants to run stopping others.  If it does, then we won't
-    // setup the other threads for resume, since they aren't going to get a chance
-    // to run.  This is necessary because the SetupForResume might add "StopOthers"
-    // plans which would then get to be part of the who-gets-to-run negotiation, but
-    // they're coming in after the fact, and the threads that are already set up should
-    // take priority.
-    
-    bool wants_solo_run = false;
-    
-    for (pos = m_threads.begin(); pos != end; ++pos)
-    {
-        if ((*pos)->GetResumeState() != eStateSuspended &&
-                 (*pos)->GetCurrentPlan()->StopOthers())
-        {
-            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
-                continue;
-            wants_solo_run = true;
-            break;
-        }
-    }   
-
-    if (wants_solo_run)
-    {
-        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-        if (log && log->GetVerbose())
-            log->Printf ("Turning on notification of new threads while single stepping a thread.");
-        m_process->StartNoticingNewThreads();
-    }
-    else
-    {
-        Log *log(lldb_private::GetLogIfAllCategoriesSet (LIBLLDB_LOG_STEP));
-        if (log && log->GetVerbose())
-            log->Printf ("Turning off notification of new threads while single stepping a thread.");
-        m_process->StopNoticingNewThreads();
-    }
-    
-    // Give all the threads that are likely to run a last chance to set up their state before we
-    // negotiate who is actually going to get a chance to run...
-    // Don't set to resume suspended threads, and if any thread wanted to stop others, only
-    // call setup on the threads that request StopOthers...
-    
-    for (pos = m_threads.begin(); pos != end; ++pos)
-    {
-        if ((*pos)->GetResumeState() != eStateSuspended
-            && (!wants_solo_run || (*pos)->GetCurrentPlan()->StopOthers()))
-        {
-            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
-                continue;
-            (*pos)->SetupForResume ();
-        }
-    }
-
-    // Now go through the threads and see if any thread wants to run just itself.
-    // if so then pick one and run it.
-    
-    ThreadList run_me_only_list (m_process);
-    
-    run_me_only_list.SetStopID(m_process->GetStopID());
-
-    bool run_only_current_thread = false;
-
-    for (pos = m_threads.begin(); pos != end; ++pos)
-    {
-        ThreadSP thread_sp(*pos);
-        if (thread_sp->GetResumeState() != eStateSuspended &&
-                 thread_sp->GetCurrentPlan()->StopOthers())
-        {
-            if ((*pos)->IsOperatingSystemPluginThread() && !(*pos)->GetBackingThread())
-                continue;
-
-            // You can't say "stop others" and also want yourself to be suspended.
-            assert (thread_sp->GetCurrentPlan()->RunState() != eStateSuspended);
-
-            if (thread_sp == GetSelectedThread())
-            {
-                run_only_current_thread = true;
-                run_me_only_list.Clear();
-                run_me_only_list.AddThread (thread_sp);
-                break;
-            }
-
-            run_me_only_list.AddThread (thread_sp);
-        }
-
-    }
-
-    bool need_to_resume = true;
-    
-    if (run_me_only_list.GetSize (false) == 0)
-    {
-        // Everybody runs as they wish:
-        for (pos = m_threads.begin(); pos != end; ++pos)
-        {
-            ThreadSP thread_sp(*pos);
-            StateType run_state;
-            if (thread_sp->GetResumeState() != eStateSuspended)
-                run_state = thread_sp->GetCurrentPlan()->RunState();
-            else
-                run_state = eStateSuspended;
-            if (!thread_sp->ShouldResume(run_state))
-                need_to_resume = false;
-        }
-    }
-    else
-    {
-        ThreadSP thread_to_run;
-
-        if (run_only_current_thread)
-        {
-            thread_to_run = GetSelectedThread();
-        }
-        else if (run_me_only_list.GetSize (false) == 1)
-        {
-            thread_to_run = run_me_only_list.GetThreadAtIndex (0);
-        }
-        else
-        {
-            int random_thread = (int)
-                    ((run_me_only_list.GetSize (false) * (double) rand ()) / (RAND_MAX + 1.0));
-            thread_to_run = run_me_only_list.GetThreadAtIndex (random_thread);
-        }
-
-        for (pos = m_threads.begin(); pos != end; ++pos)
-        {
-            ThreadSP thread_sp(*pos);
-            if (thread_sp == thread_to_run)
-            {
-                if (!thread_sp->ShouldResume(thread_sp->GetCurrentPlan()->RunState()))
-                    need_to_resume = false;
-            }
-            else
-                thread_sp->ShouldResume (eStateSuspended);
-        }
-    }
-
-    return need_to_resume;
-}
-
-void
-ThreadList::DidResume ()
-{
-    Mutex::Locker locker(GetMutex());
-    collection::iterator pos, end = m_threads.end();
-    for (pos = m_threads.begin(); pos != end; ++pos)
-    {
-        // Don't clear out threads that aren't going to get a chance to run, rather
-        // leave their state for the next time around.
-        ThreadSP thread_sp(*pos);
-        if (thread_sp->GetResumeState() != eStateSuspended)
-            thread_sp->DidResume ();
-    }
-}
-
-void
-ThreadList::DidStop ()
-{
-    Mutex::Locker locker(GetMutex());
-    collection::iterator pos, end = m_threads.end();
-    for (pos = m_threads.begin(); pos != end; ++pos)
-    {
-        // Notify threads that the process just stopped.
-        // Note, this currently assumes that all threads in the list
-        // stop when the process stops.  In the future we will want to support
-        // a debugging model where some threads continue to run while others
-        // are stopped.  We either need to handle that somehow here or
-        // create a special thread list containing only threads which will
-        // stop in the code that calls this method (currently
-        // Process::SetPrivateState).
-        ThreadSP thread_sp(*pos);
-        if (StateIsRunningState(thread_sp->GetState()))
-            thread_sp->DidStop ();
-    }
-}
-
-ThreadSP
-ThreadList::GetSelectedThread ()
-{
-    Mutex::Locker locker(GetMutex());
-    ThreadSP thread_sp = FindThreadByID(m_selected_tid);
-    if (!thread_sp.get())
-    {
-        if (m_threads.size() == 0)
-            return thread_sp;
-        m_selected_tid = m_threads[0]->GetID();
-        thread_sp = m_threads[0];
-    }
-    return thread_sp;
-}
-
-bool
-ThreadList::SetSelectedThreadByID (lldb::tid_t tid, bool notify)
-{
-    Mutex::Locker locker(GetMutex());
-    ThreadSP selected_thread_sp(FindThreadByID(tid));
-    if  (selected_thread_sp)
-    {
-        m_selected_tid = tid;
-        selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
-    }
-    else
-        m_selected_tid = LLDB_INVALID_THREAD_ID;
-
-    if (notify)
-        NotifySelectedThreadChanged(m_selected_tid);
-    
-    return m_selected_tid != LLDB_INVALID_THREAD_ID;
-}
-
-bool
-ThreadList::SetSelectedThreadByIndexID (uint32_t index_id, bool notify)
-{
-    Mutex::Locker locker(GetMutex());
-    ThreadSP selected_thread_sp (FindThreadByIndexID(index_id));
-    if  (selected_thread_sp.get())
-    {
-        m_selected_tid = selected_thread_sp->GetID();
-        selected_thread_sp->SetDefaultFileAndLineToSelectedFrame();
-    }
-    else
-        m_selected_tid = LLDB_INVALID_THREAD_ID;
-
-    if (notify)
-        NotifySelectedThreadChanged(m_selected_tid);
-    
-    return m_selected_tid != LLDB_INVALID_THREAD_ID;
-}
-
-void
-ThreadList::NotifySelectedThreadChanged (lldb::tid_t tid)
-{
-    ThreadSP selected_thread_sp (FindThreadByID(tid));
-    if (selected_thread_sp->EventTypeHasListeners(Thread::eBroadcastBitThreadSelected))
-        selected_thread_sp->BroadcastEvent(Thread::eBroadcastBitThreadSelected,
-                                           new Thread::ThreadEventData(selected_thread_sp));
-}
-
-void
-ThreadList::Update (ThreadList &rhs)
-{
-    if (this != &rhs)
-    {
-        // Lock both mutexes to make sure neither side changes anyone on us
-        // while the assignement occurs
-        Mutex::Locker locker(GetMutex());
-        m_process = rhs.m_process;
-        m_stop_id = rhs.m_stop_id;
-        m_threads.swap(rhs.m_threads);
-        m_selected_tid = rhs.m_selected_tid;
-        
-        
-        // Now we look for threads that we are done with and
-        // make sure to clear them up as much as possible so 
-        // anyone with a shared pointer will still have a reference,
-        // but the thread won't be of much use. Using std::weak_ptr
-        // for all backward references (such as a thread to a process)
-        // will eventually solve this issue for us, but for now, we
-        // need to work around the issue
-        collection::iterator rhs_pos, rhs_end = rhs.m_threads.end();
-        for (rhs_pos = rhs.m_threads.begin(); rhs_pos != rhs_end; ++rhs_pos)
-        {
-            const lldb::tid_t tid = (*rhs_pos)->GetID();
-            bool thread_is_alive = false;
-            const uint32_t num_threads = m_threads.size();
-            for (uint32_t idx = 0; idx < num_threads; ++idx)
-            {
-                if (m_threads[idx]->GetID() == tid)
-                {
-                    thread_is_alive = true;
-                    break;
-                }
-            }
-            if (!thread_is_alive)
-                (*rhs_pos)->DestroyThread();
-        }        
-    }
-}
-
-void
-ThreadList::Flush ()
-{
-    Mutex::Locker locker(GetMutex());
-    collection::iterator pos, end = m_threads.end();
-    for (pos = m_threads.begin(); pos != end; ++pos)
-        (*pos)->Flush ();
-}
-
-Mutex &
-ThreadList::GetMutex ()
-{
-    return m_process->m_thread_mutex;
-}
-
_______________________________________________
lldb-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/lldb-commits

Reply via email to