Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:42:55

0001 //===-- ThreadList.h --------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 
0009 #ifndef LLDB_TARGET_THREADLIST_H
0010 #define LLDB_TARGET_THREADLIST_H
0011 
0012 #include <mutex>
0013 #include <vector>
0014 
0015 #include "lldb/Target/Thread.h"
0016 #include "lldb/Target/ThreadCollection.h"
0017 #include "lldb/Utility/Iterable.h"
0018 #include "lldb/Utility/UserID.h"
0019 #include "lldb/lldb-private.h"
0020 
0021 namespace lldb_private {
0022 
0023 // This is a thread list with lots of functionality for use only by the process
0024 // for which this is the thread list.  A generic container class with iterator
0025 // functionality is ThreadCollection.
0026 class ThreadList : public ThreadCollection {
0027   friend class Process;
0028 
0029 public:
0030   ThreadList(Process &process);
0031 
0032   ThreadList(const ThreadList &rhs);
0033 
0034   ~ThreadList() override;
0035 
0036   /// Precondition: both thread lists must be belong to the same process.
0037   const ThreadList &operator=(const ThreadList &rhs);
0038 
0039   uint32_t GetSize(bool can_update = true);
0040 
0041   // Return the selected thread if there is one.  Otherwise, return the thread
0042   // selected at index 0.
0043   lldb::ThreadSP GetSelectedThread();
0044 
0045   // Manage the thread to use for running expressions.  This is usually the
0046   // Selected thread, but sometimes (e.g. when evaluating breakpoint conditions
0047   // & stop hooks) it isn't.
0048   class ExpressionExecutionThreadPusher {
0049   public:
0050     ExpressionExecutionThreadPusher(ThreadList &thread_list, lldb::tid_t tid)
0051         : m_thread_list(&thread_list), m_tid(tid) {
0052       m_thread_list->PushExpressionExecutionThread(m_tid);
0053     }
0054 
0055     ExpressionExecutionThreadPusher(lldb::ThreadSP thread_sp);
0056 
0057     ~ExpressionExecutionThreadPusher() {
0058       if (m_thread_list && m_tid != LLDB_INVALID_THREAD_ID)
0059         m_thread_list->PopExpressionExecutionThread(m_tid);
0060     }
0061 
0062   private:
0063     ThreadList *m_thread_list;
0064     lldb::tid_t m_tid;
0065   };
0066 
0067   lldb::ThreadSP GetExpressionExecutionThread();
0068 
0069 protected:
0070   void PushExpressionExecutionThread(lldb::tid_t tid);
0071 
0072   void PopExpressionExecutionThread(lldb::tid_t tid);
0073 
0074 public:
0075   bool SetSelectedThreadByID(lldb::tid_t tid, bool notify = false);
0076 
0077   bool SetSelectedThreadByIndexID(uint32_t index_id, bool notify = false);
0078 
0079   void Clear();
0080 
0081   void Flush();
0082 
0083   void Destroy();
0084 
0085   // Note that "idx" is not the same as the "thread_index". It is a zero based
0086   // index to accessing the current threads, whereas "thread_index" is a unique
0087   // index assigned
0088   lldb::ThreadSP GetThreadAtIndex(uint32_t idx, bool can_update = true);
0089 
0090   lldb::ThreadSP FindThreadByID(lldb::tid_t tid, bool can_update = true);
0091 
0092   lldb::ThreadSP FindThreadByProtocolID(lldb::tid_t tid,
0093                                         bool can_update = true);
0094 
0095   lldb::ThreadSP RemoveThreadByID(lldb::tid_t tid, bool can_update = true);
0096 
0097   lldb::ThreadSP RemoveThreadByProtocolID(lldb::tid_t tid,
0098                                           bool can_update = true);
0099 
0100   lldb::ThreadSP FindThreadByIndexID(uint32_t index_id, bool can_update = true);
0101 
0102   lldb::ThreadSP GetThreadSPForThreadPtr(Thread *thread_ptr);
0103 
0104   lldb::ThreadSP GetBackingThread(const lldb::ThreadSP &real_thread);
0105 
0106   bool ShouldStop(Event *event_ptr);
0107 
0108   Vote ShouldReportStop(Event *event_ptr);
0109 
0110   Vote ShouldReportRun(Event *event_ptr);
0111 
0112   void RefreshStateAfterStop();
0113 
0114   /// The thread list asks tells all the threads it is about to resume.
0115   /// If a thread can "resume" without having to resume the target, it
0116   /// will return false for WillResume, and then the process will not be
0117   /// restarted.
0118   ///
0119   /// \return
0120   ///    \b true instructs the process to resume normally,
0121   ///    \b false means start & stopped events will be generated, but
0122   ///    the process will not actually run.  The thread must then return
0123   ///    the correct StopInfo when asked.
0124   ///
0125   bool WillResume();
0126 
0127   void DidResume();
0128 
0129   void DidStop();
0130 
0131   void DiscardThreadPlans();
0132 
0133   uint32_t GetStopID() const;
0134 
0135   void SetStopID(uint32_t stop_id);
0136 
0137   std::recursive_mutex &GetMutex() const override;
0138 
0139   /// Precondition: both thread lists must be belong to the same process.
0140   void Update(ThreadList &rhs);
0141 
0142 protected:
0143   void SetShouldReportStop(Vote vote);
0144 
0145   void NotifySelectedThreadChanged(lldb::tid_t tid);
0146 
0147   // Classes that inherit from Process can see and modify these
0148   Process &m_process; ///< The process that manages this thread list.
0149   uint32_t
0150       m_stop_id; ///< The process stop ID that this thread list is valid for.
0151   lldb::tid_t
0152       m_selected_tid; ///< For targets that need the notion of a current thread.
0153   std::vector<lldb::tid_t> m_expression_tid_stack;
0154 
0155 private:
0156   ThreadList() = delete;
0157 };
0158 
0159 } // namespace lldb_private
0160 
0161 #endif // LLDB_TARGET_THREADLIST_H