/* Multi-process/thread control defs for GDB, the GNU debugger.
   Copyright (C) 1987-2024 Free Software Foundation, Inc.
   Contributed by Lynx Real-Time Systems, Inc.  Los Gatos, CA.
   

   This file is part of GDB.

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

#ifndef GDB_GDBTHREAD_H
#define GDB_GDBTHREAD_H

struct symtab;

#include "breakpoint.h"
#include "frame.h"
#include "ui-out.h"
#include "btrace.h"
#include "target/waitstatus.h"
#include "target/target.h"
#include "cli/cli-utils.h"
#include "gdbsupport/refcounted-object.h"
#include "gdbsupport/common-gdbthread.h"
#include "gdbsupport/forward-scope-exit.h"
#include "displaced-stepping.h"
#include "gdbsupport/intrusive_list.h"
#include "thread-fsm.h"
#include "language.h"

struct inferior;
struct process_stratum_target;

/* When true, print debug messages related to GDB thread creation and
   deletion.  */

extern bool debug_threads;

/* Print a "threads" debug statement.  */

#define threads_debug_printf(fmt, ...) \
  debug_prefixed_printf_cond (debug_threads, "threads", fmt, ##__VA_ARGS__)

/* Frontend view of the thread state.  Possible extensions: stepping,
   finishing, until(ling),...

   NOTE: Since the thread state is not a boolean, most times, you do
   not want to check it with negation.  If you really want to check if
   the thread is stopped,

    use (good):

     if (tp->state == THREAD_STOPPED)

    instead of (bad):

     if (tp->state != THREAD_RUNNING)

   The latter is also true for exited threads, most likely not what
   you want.  */
enum thread_state
{
  /* In the frontend's perpective, the thread is stopped.  */
  THREAD_STOPPED,

  /* In the frontend's perpective, the thread is running.  */
  THREAD_RUNNING,

  /* The thread is listed, but known to have exited.  We keep it
     listed (but not visible) until it's safe to delete it.  */
  THREAD_EXITED,
};

/* STEP_OVER_ALL means step over all subroutine calls.
   STEP_OVER_UNDEBUGGABLE means step over calls to undebuggable functions.
   STEP_OVER_NONE means don't step over any subroutine calls.  */

enum step_over_calls_kind
  {
    STEP_OVER_NONE,
    STEP_OVER_ALL,
    STEP_OVER_UNDEBUGGABLE
  };

/* Inferior thread specific part of `struct infcall_control_state'.

   Inferior process counterpart is `struct inferior_control_state'.  */

struct thread_control_state
{
  /* User/external stepping state.  */

  /* Step-resume or longjmp-resume breakpoint.  */
  struct breakpoint *step_resume_breakpoint = nullptr;

  /* Exception-resume breakpoint.  */
  struct breakpoint *exception_resume_breakpoint = nullptr;

  /* Breakpoints used for software single stepping.  Plural, because
     it may have multiple locations.  E.g., if stepping over a
     conditional branch instruction we can't decode the condition for,
     we'll need to put a breakpoint at the branch destination, and
     another at the instruction after the branch.  */
  struct breakpoint *single_step_breakpoints = nullptr;

  /* Range to single step within.

     If this is nonzero, respond to a single-step signal by continuing
     to step if the pc is in this range.

     If step_range_start and step_range_end are both 1, it means to
     step for a single instruction (FIXME: it might clean up
     wait_for_inferior in a minor way if this were changed to the
     address of the instruction and that address plus one.  But maybe
     not).  */
  CORE_ADDR step_range_start = 0;	/* Inclusive */
  CORE_ADDR step_range_end = 0;		/* Exclusive */

  /* Function the thread was in as of last it started stepping.  */
  struct symbol *step_start_function = nullptr;

  /* If GDB issues a target step request, and this is nonzero, the
     target should single-step this thread once, and then continue
     single-stepping it without GDB core involvement as long as the
     thread stops in the step range above.  If this is zero, the
     target should ignore the step range, and only issue one single
     step.  */
  int may_range_step = 0;

  /* Stack frame address as of when stepping command was issued.
     This is how we know when we step into a subroutine call, and how
     to set the frame for the breakpoint used to step out.  */
  struct frame_id step_frame_id {};

  /* Similarly, the frame ID of the underlying stack frame (skipping
     any inlined frames).  */
  struct frame_id step_stack_frame_id {};

  /* True if the the thread is presently stepping over a breakpoint or
     a watchpoint, either with an inline step over or a displaced (out
     of line) step, and we're now expecting it to report a trap for
     the finished single step.  */
  int trap_expected = 0;

  /* Nonzero if the thread is being proceeded for a "finish" command
     or a similar situation when return value should be printed.  */
  int proceed_to_finish = 0;

  /* Nonzero if the thread is being proceeded for an inferior function
     call.  */
  int in_infcall = 0;

  enum step_over_calls_kind step_over_calls = STEP_OVER_NONE;

  /* Nonzero if stopped due to a step command.  */
  int stop_step = 0;

  /* Chain containing status of breakpoint(s) the thread stopped
     at.  */
  bpstat *stop_bpstat = nullptr;

  /* Whether the command that started the thread was a stepping
     command.  This is used to decide whether "set scheduler-locking
     step" behaves like "on" or "off".  */
  int stepping_command = 0;

  /* True if the thread is evaluating a BP condition.  */
  bool in_cond_eval = false;
};

/* Inferior thread specific part of `struct infcall_suspend_state'.  */

struct thread_suspend_state
{
  /* Last signal that the inferior received (why it stopped).  When
     the thread is resumed, this signal is delivered.  Note: the
     target should not check whether the signal is in pass state,
     because the signal may have been explicitly passed with the
     "signal" command, which overrides "handle nopass".  If the signal
     should be suppressed, the core will take care of clearing this
     before the target is resumed.  */
  enum gdb_signal stop_signal = GDB_SIGNAL_0;

  /* The reason the thread last stopped, if we need to track it
     (breakpoint, watchpoint, etc.)  */
  enum target_stop_reason stop_reason = TARGET_STOPPED_BY_NO_REASON;

  /* The waitstatus for this thread's last event.  */
  struct target_waitstatus waitstatus;
  /* If true WAITSTATUS hasn't been handled yet.  */
  int waitstatus_pending_p = 0;

  /* Record the pc of the thread the last time it stopped.  (This is
     not the current thread's PC as that may have changed since the
     last stop, e.g., "return" command, or "p $pc = 0xf000").

     - If the thread's PC has not changed since the thread last
       stopped, then proceed skips a breakpoint at the current PC,
       otherwise we let the thread run into the breakpoint.

     - If the thread has an unprocessed event pending, as indicated by
       waitstatus_pending_p, this is used in coordination with
       stop_reason: if the thread's PC has changed since the thread
       last stopped, a pending breakpoint waitstatus is discarded.

     - If the thread is running, then this field has its value removed by
       calling stop_pc.reset() (see thread_info::set_executing()).
       Attempting to read a std::optional with no value is undefined
       behavior and will trigger an assertion error when _GLIBCXX_DEBUG is
       defined, which should make error easier to track down.  */
  std::optional<CORE_ADDR> stop_pc;
};

/* Base class for target-specific thread data.  */
struct private_thread_info
{
  virtual ~private_thread_info () = 0;
};

/* Unique pointer wrapper for private_thread_info.  */
using private_thread_info_up = std::unique_ptr<private_thread_info>;

/* Threads are intrusively refcounted objects.  Being the
   user-selected thread is normally considered an implicit strong
   reference and is thus not accounted in the refcount, unlike
   inferior objects.  This is necessary, because there's no "current
   thread" pointer.  Instead the current thread is inferred from the
   inferior_ptid global.  However, when GDB needs to remember the
   selected thread to later restore it, GDB bumps the thread object's
   refcount, to prevent something deleting the thread object before
   reverting back (e.g., due to a "kill" command).  If the thread
   meanwhile exits before being re-selected, then the thread object is
   left listed in the thread list, but marked with state
   THREAD_EXITED.  (See scoped_restore_current_thread and
   delete_thread).  All other thread references are considered weak
   references.  Placing a thread in the thread list is an implicit
   strong reference, and is thus not accounted for in the thread's
   refcount.

   The intrusive_list_node base links threads in a per-inferior list.
   We place it first in the inherit order to work around PR gcc/113599.  */

class thread_info : public intrusive_list_node<thread_info>,
		    public refcounted_object
{
public:
  explicit thread_info (inferior *inf, ptid_t ptid);
  ~thread_info ();

  bool deletable () const;

  /* Mark this thread as running and notify observers.  */
  void set_running (bool running);

  ptid_t ptid;			/* "Actual process id";
				    In fact, this may be overloaded with 
				    kernel thread id, etc.  */

  /* Each thread has two GDB IDs.

     a) The thread ID (Id).  This consists of the pair of:

	- the number of the thread's inferior and,

	- the thread's thread number in its inferior, aka, the
	  per-inferior thread number.  This number is unique in the
	  inferior but not unique between inferiors.

     b) The global ID (GId).  This is a a single integer unique
	between all inferiors.

     E.g.:

      (gdb) info threads -gid
	Id    GId   Target Id   Frame
      * 1.1   1     Thread A    0x16a09237 in foo () at foo.c:10
	1.2   3     Thread B    0x15ebc6ed in bar () at foo.c:20
	1.3   5     Thread C    0x15ebc6ed in bar () at foo.c:20
	2.1   2     Thread A    0x16a09237 in foo () at foo.c:10
	2.2   4     Thread B    0x15ebc6ed in bar () at foo.c:20
	2.3   6     Thread C    0x15ebc6ed in bar () at foo.c:20

     Above, both inferiors 1 and 2 have threads numbered 1-3, but each
     thread has its own unique global ID.  */

  /* The thread's global GDB thread number.  This is exposed to MI,
     Python/Scheme, visible with "info threads -gid", and is also what
     the $_gthread convenience variable is bound to.  */
  int global_num;

  /* The per-inferior thread number.  This is unique in the inferior
     the thread belongs to, but not unique between inferiors.  This is
     what the $_thread convenience variable is bound to.  */
  int per_inf_num;

  /* The inferior this thread belongs to.  */
  struct inferior *inf;

  /* The user-given name of the thread.

     Returns nullptr if the thread does not have a user-given name.  */
  const char *name () const
  {
    return m_name.get ();
  }

  /* Set the user-given name of the thread.

     Pass nullptr to clear the name.  */
  void set_name (gdb::unique_xmalloc_ptr<char> name)
  {
    m_name = std::move (name);
  }

  bool executing () const
  { return m_executing; }

  /* Set the thread's 'm_executing' field from EXECUTING, and if EXECUTING
     is true also clears the thread's stop_pc.  */
  void set_executing (bool executing);

  bool resumed () const
  { return m_resumed; }

  /* Set the thread's 'm_resumed' field from RESUMED.  The thread may also
     be added to (when RESUMED is true), or removed from (when RESUMED is
     false), the list of threads with a pending wait status.  */
  void set_resumed (bool resumed);

  /* Frontend view of the thread state.  Note that the THREAD_RUNNING/
     THREAD_STOPPED states are different from EXECUTING.  When the
     thread is stopped internally while handling an internal event,
     like a software single-step breakpoint, EXECUTING will be false,
     but STATE will still be THREAD_RUNNING.  */
  enum thread_state state = THREAD_STOPPED;

  /* State of GDB control of inferior thread execution.
     See `struct thread_control_state'.  */
  thread_control_state control;

  /* Save M_SUSPEND to SUSPEND.  */

  void save_suspend_to (thread_suspend_state &suspend) const
  {
    suspend = m_suspend;
  }

  /* Restore M_SUSPEND from SUSPEND.  */

  void restore_suspend_from (const thread_suspend_state &suspend)
  {
    m_suspend = suspend;
  }

  /* Return this thread's stop PC.  This should only be called when it is
     known that stop_pc has a value.  If this function is being used in a
     situation where a thread may not have had a stop_pc assigned, then
     stop_pc_p() can be used to check if the stop_pc is defined.  */

  CORE_ADDR stop_pc () const
  {
    gdb_assert (m_suspend.stop_pc.has_value ());
    return *m_suspend.stop_pc;
  }

  /* Set this thread's stop PC.  */

  void set_stop_pc (CORE_ADDR stop_pc)
  {
    m_suspend.stop_pc = stop_pc;
  }

  /* Remove the stop_pc stored on this thread.  */

  void clear_stop_pc ()
  {
    m_suspend.stop_pc.reset ();
  }

  /* Return true if this thread has a cached stop pc value, otherwise
     return false.  */

  bool stop_pc_p () const
  {
    return m_suspend.stop_pc.has_value ();
  }

  /* Return true if this thread has a pending wait status.  */

  bool has_pending_waitstatus () const
  {
    return m_suspend.waitstatus_pending_p;
  }

  /* Get this thread's pending wait status.

     May only be called if has_pending_waitstatus returns true.  */

  const target_waitstatus &pending_waitstatus () const
  {
    gdb_assert (this->has_pending_waitstatus ());

    return m_suspend.waitstatus;
  }

  /* Set this thread's pending wait status.

     May only be called if has_pending_waitstatus returns false.  */

  void set_pending_waitstatus (const target_waitstatus &ws);

  /* Clear this thread's pending wait status.

     May only be called if has_pending_waitstatus returns true.  */

  void clear_pending_waitstatus ();

  /* Return this thread's stop signal.  */

  gdb_signal stop_signal () const
  {
    return m_suspend.stop_signal;
  }

  /* Set this thread's stop signal.  */

  void set_stop_signal (gdb_signal sig)
  {
    m_suspend.stop_signal = sig;
  }

  /* Return this thread's stop reason.  */

  target_stop_reason stop_reason () const
  {
    return m_suspend.stop_reason;
  }

  /* Set this thread's stop reason.  */

  void set_stop_reason (target_stop_reason reason)
  {
    m_suspend.stop_reason = reason;
  }

  /* Get the FSM associated with the thread.  */

  struct thread_fsm *thread_fsm () const
  {
    return m_thread_fsm.get ();
  }

  /* Get the owning reference to the FSM associated with the thread.

     After a call to this method, "thread_fsm () == nullptr".  */

  std::unique_ptr<struct thread_fsm> release_thread_fsm ()
  {
    return std::move (m_thread_fsm);
  }

  /* Set the FSM associated with the current thread.

     It is invalid to set the FSM if another FSM is already installed.  */

  void set_thread_fsm (std::unique_ptr<struct thread_fsm> fsm)
  {
    gdb_assert (m_thread_fsm == nullptr);
    m_thread_fsm = std::move (fsm);
  }

  /* Record the thread options last set for this thread.  */

  void set_thread_options (gdb_thread_options thread_options);

  /* Get the thread options last set for this thread.  */

  gdb_thread_options thread_options () const
  {
    return m_thread_options;
  }

  int current_line = 0;
  struct symtab *current_symtab = NULL;

  /* Internal stepping state.  */

  /* Record the pc of the thread the last time it was resumed.  (It
     can't be done on stop as the PC may change since the last stop,
     e.g., "return" command, or "p $pc = 0xf000").  This is maintained
     by proceed and keep_going, and among other things, it's used in
     adjust_pc_after_break to distinguish a hardware single-step
     SIGTRAP from a breakpoint SIGTRAP.  */
  CORE_ADDR prev_pc = 0;

  /* Did we set the thread stepping a breakpoint instruction?  This is
     used in conjunction with PREV_PC to decide whether to adjust the
     PC.  */
  int stepped_breakpoint = 0;

  /* Should we step over breakpoint next time keep_going is called?  */
  int stepping_over_breakpoint = 0;

  /* Should we step over a watchpoint next time keep_going is called?
     This is needed on targets with non-continuable, non-steppable
     watchpoints.  */
  int stepping_over_watchpoint = 0;

  /* Set to TRUE if we should finish single-stepping over a breakpoint
     after hitting the current step-resume breakpoint.  The context here
     is that GDB is to do `next' or `step' while signal arrives.
     When stepping over a breakpoint and signal arrives, GDB will attempt
     to skip signal handler, so it inserts a step_resume_breakpoint at the
     signal return address, and resume inferior.
     step_after_step_resume_breakpoint is set to TRUE at this moment in
     order to keep GDB in mind that there is still a breakpoint to step over
     when GDB gets back SIGTRAP from step_resume_breakpoint.  */
  int step_after_step_resume_breakpoint = 0;

  /* This is used to remember when a fork or vfork event was caught by
     a catchpoint, and thus the event is to be followed at the next
     resume of the thread, and not immediately.  */
  struct target_waitstatus pending_follow;

  /* True if this thread has been explicitly requested to stop.  */
  bool stop_requested = false;

  /* The initiating frame of a nexting operation, used for deciding
     which exceptions to intercept.  If it is null_frame_id no
     bp_longjmp or bp_exception but longjmp has been caught just for
     bp_longjmp_call_dummy.  */
  struct frame_id initiating_frame = null_frame_id;

  /* Private data used by the target vector implementation.  */
  private_thread_info_up priv;

  /* Branch trace information for this thread.  */
  struct btrace_thread_info btrace {};

  /* Flag which indicates that the stack temporaries should be stored while
     evaluating expressions.  */
  bool stack_temporaries_enabled = false;

  /* Values that are stored as temporaries on stack while evaluating
     expressions.  */
  std::vector<struct value *> stack_temporaries;

  /* Step-over chain.  A thread is in the step-over queue if this node is
     linked.  */
  intrusive_list_node<thread_info> step_over_list_node;

  /* Node for list of threads that are resumed and have a pending wait status.

     The list head for this is in process_stratum_target, hence all threads in
     this list belong to that process target.  */
  intrusive_list_node<thread_info> resumed_with_pending_wait_status_node;

  /* Displaced-step state for this thread.  */
  displaced_step_thread_state displaced_step_state;

private:
  /* True if this thread is resumed from infrun's perspective.
     Note that a thread can be marked both as not-executing and
     resumed at the same time.  This happens if we try to resume a
     thread that has a wait status pending.  We shouldn't let the
     thread really run until that wait status has been processed, but
     we should not process that wait status if we didn't try to let
     the thread run.  */
  bool m_resumed = false;

  /* True means the thread is executing.  Note: this is different
     from saying that there is an active target and we are stopped at
     a breakpoint, for instance.  This is a real indicator whether the
     thread is off and running.  */
  bool m_executing = false;

  /* State of inferior thread to restore after GDB is done with an inferior
     call.  See `struct thread_suspend_state'.  */
  thread_suspend_state m_suspend;

  /* The user-given name of the thread.

     Nullptr if the thread does not have a user-given name.  */
  gdb::unique_xmalloc_ptr<char> m_name;

  /* Pointer to the state machine manager object that handles what is
     left to do for the thread's execution command after the target
     stops.  Several execution commands use it.  */
  std::unique_ptr<struct thread_fsm> m_thread_fsm;

  /* The thread options as last set with a call to
     set_thread_options.  */
  gdb_thread_options m_thread_options;
};

using thread_info_resumed_with_pending_wait_status_node
  = intrusive_member_node<thread_info,
			  &thread_info::resumed_with_pending_wait_status_node>;
using thread_info_resumed_with_pending_wait_status_list
  = intrusive_list<thread_info,
		   thread_info_resumed_with_pending_wait_status_node>;

/* A gdb::ref_ptr pointer to a thread_info.  */

using thread_info_ref
  = gdb::ref_ptr<struct thread_info, refcounted_object_ref_policy>;

/* A gdb::ref_ptr pointer to an inferior.  This would ideally be in
   inferior.h, but it can't due to header dependencies (inferior.h
   includes gdbthread.h).  */

using inferior_ref
  = gdb::ref_ptr<struct inferior, refcounted_object_ref_policy>;

/* Create an empty thread list, or empty the existing one.  */
extern void init_thread_list (void);

/* Add a thread to the thread list, print a message
   that a new thread is found, and return the pointer to
   the new thread.  Caller my use this pointer to 
   initialize the private thread data.  */
extern struct thread_info *add_thread (process_stratum_target *targ,
				       ptid_t ptid);

/* Same as add_thread, but does not print a message about new
   thread.  */
extern struct thread_info *add_thread_silent (process_stratum_target *targ,
					      ptid_t ptid);

/* Same as add_thread, and sets the private info.  */
extern struct thread_info *add_thread_with_info (process_stratum_target *targ,
						 ptid_t ptid,
						 private_thread_info_up);

/* Delete thread THREAD and notify of thread exit.  If the thread is
   currently not deletable, don't actually delete it but still tag it
   as exited and do the notification.  EXIT_CODE is the thread's exit
   code.  If SILENT, don't actually notify the CLI.  THREAD must not
   be NULL or an assertion will fail.  */
extern void delete_thread_with_exit_code (thread_info *thread,
					  ULONGEST exit_code,
					  bool silent = false);

/* Delete thread THREAD and notify of thread exit.  If the thread is
   currently not deletable, don't actually delete it but still tag it
   as exited and do the notification.  THREAD must not be NULL or an
   assertion will fail.  */
extern void delete_thread (thread_info *thread);

/* Like delete_thread, but be quiet about it.  Used when the process
   this thread belonged to has already exited, for example.  */
extern void delete_thread_silent (struct thread_info *thread);

/* Mark the thread exited, but don't delete it or remove it from the
   inferior thread list.  EXIT_CODE is the thread's exit code, if
   available.  If SILENT, then don't inform the CLI about the
   exit.  */
extern void set_thread_exited (thread_info *tp,
			       std::optional<ULONGEST> exit_code = {},
			       bool silent = false);

/* Delete a step_resume_breakpoint from the thread database.  */
extern void delete_step_resume_breakpoint (struct thread_info *);

/* Delete an exception_resume_breakpoint from the thread database.  */
extern void delete_exception_resume_breakpoint (struct thread_info *);

/* Delete the single-step breakpoints of thread TP, if any.  */
extern void delete_single_step_breakpoints (struct thread_info *tp);

/* Check if the thread has software single stepping breakpoints
   set.  */
extern int thread_has_single_step_breakpoints_set (struct thread_info *tp);

/* Check whether the thread has software single stepping breakpoints
   set at PC.  */
extern int thread_has_single_step_breakpoint_here (struct thread_info *tp,
						   const address_space *aspace,
						   CORE_ADDR addr);

/* Returns whether to show inferior-qualified thread IDs, or plain
   thread numbers.  Inferior-qualified IDs are shown whenever we have
   multiple inferiors, or the only inferior left has number > 1.  */
extern int show_inferior_qualified_tids (void);

/* Return a string version of THR's thread ID.  If there are multiple
   inferiors, then this prints the inferior-qualifier form, otherwise
   it only prints the thread number.  The result is stored in a
   circular static buffer, NUMCELLS deep.  */
const char *print_thread_id (struct thread_info *thr);

/* Like print_thread_id, but always prints the inferior-qualified form,
   even when there is only a single inferior.  */
const char *print_full_thread_id (struct thread_info *thr);

/* Boolean test for an already-known ptid.  */
extern bool in_thread_list (process_stratum_target *targ, ptid_t ptid);

/* Boolean test for an already-known global thread id (GDB's homegrown
   global id, not the system's).  */
extern int valid_global_thread_id (int global_id);

/* Find thread by GDB global thread ID.  */
struct thread_info *find_thread_global_id (int global_id);

/* Find thread by thread library specific handle in inferior INF.  */
struct thread_info *find_thread_by_handle
  (gdb::array_view<const gdb_byte> handle, struct inferior *inf);

/* Finds the first thread of the specified inferior.  */
extern struct thread_info *first_thread_of_inferior (inferior *inf);

/* Returns any thread of inferior INF, giving preference to the
   current thread.  */
extern struct thread_info *any_thread_of_inferior (inferior *inf);

/* Returns any non-exited thread of inferior INF, giving preference to
   the current thread, and to not executing threads.  */
extern struct thread_info *any_live_thread_of_inferior (inferior *inf);

/* Change the ptid of thread OLD_PTID to NEW_PTID.  */
void thread_change_ptid (process_stratum_target *targ,
			 ptid_t old_ptid, ptid_t new_ptid);

/* Iterator function to call a user-provided callback function
   once for each known thread.  */
typedef gdb::function_view<bool (struct thread_info *)> thread_callback_func;
extern struct thread_info *iterate_over_threads (thread_callback_func);

/* Pull in the internals of the inferiors/threads ranges and
   iterators.  Must be done after struct thread_info is defined.  */
#include "thread-iter.h"

/* Return a range that can be used to walk over threads, with
   range-for.

   Used like this, it walks over all threads of all inferiors of all
   targets:

       for (thread_info *thr : all_threads ())
	 { .... }

   FILTER_PTID can be used to filter out threads that don't match.
   FILTER_PTID can be:

   - minus_one_ptid, meaning walk all threads of all inferiors of
     PROC_TARGET.  If PROC_TARGET is NULL, then of all targets.

   - A process ptid, in which case walk all threads of the specified
     process.  PROC_TARGET must be non-NULL in this case.

   - A thread ptid, in which case walk that thread only.  PROC_TARGET
     must be non-NULL in this case.
*/

inline all_matching_threads_range
all_threads (process_stratum_target *proc_target = nullptr,
	     ptid_t filter_ptid = minus_one_ptid)
{
  return all_matching_threads_range (proc_target, filter_ptid);
}

/* Return a range that can be used to walk over all non-exited threads
   of all inferiors, with range-for.  Arguments are like all_threads
   above.  */

inline all_non_exited_threads_range
all_non_exited_threads (process_stratum_target *proc_target = nullptr,
			ptid_t filter_ptid = minus_one_ptid)
{
  return all_non_exited_threads_range (proc_target, filter_ptid);
}

/* Return a range that can be used to walk over all threads of all
   inferiors, with range-for, safely.  I.e., it is safe to delete the
   currently-iterated thread.  When combined with range-for, this
   allow convenient patterns like this:

     for (thread_info *t : all_threads_safe ())
       if (some_condition ())
	 delete f;
*/

inline all_threads_safe_range
all_threads_safe ()
{
  return all_threads_safe_range (all_threads_iterator::begin_t {});
}

extern int thread_count (process_stratum_target *proc_target);

/* Return true if we have any thread in any inferior.  */
extern bool any_thread_p ();

/* Switch context to thread THR.  */
extern void switch_to_thread (struct thread_info *thr);

/* Switch context to no thread selected.  */
extern void switch_to_no_thread ();

/* Switch from one thread to another.  Does not read registers.  */
extern void switch_to_thread_no_regs (struct thread_info *thread);

/* Marks or clears thread(s) PTID of TARG as resumed.  If PTID is
   MINUS_ONE_PTID, applies to all threads of TARG.  If
   ptid_is_pid(PTID) is true, applies to all threads of the process
   pointed at by {TARG,PTID}.  */
extern void set_resumed (process_stratum_target *targ,
			 ptid_t ptid, bool resumed);

/* Marks thread PTID of TARG as running, or as stopped.  If PTID is
   minus_one_ptid, marks all threads of TARG.  */
extern void set_running (process_stratum_target *targ,
			 ptid_t ptid, bool running);

/* Marks or clears thread(s) PTID of TARG as having been requested to
   stop.  If PTID is MINUS_ONE_PTID, applies to all threads of TARG.
   If ptid_is_pid(PTID) is true, applies to all threads of the process
   pointed at by {TARG, PTID}.  If STOP, then the
   THREAD_STOP_REQUESTED observer is called with PTID as argument.  */
extern void set_stop_requested (process_stratum_target *targ,
				ptid_t ptid, bool stop);

/* Marks thread PTID of TARG as executing, or not.  If PTID is
   minus_one_ptid, marks all threads of TARG.

   Note that this is different from the running state.  See the
   description of state and executing fields of struct
   thread_info.  */
extern void set_executing (process_stratum_target *targ,
			   ptid_t ptid, bool executing);

/* True if any (known or unknown) thread of TARG is or may be
   executing.  */
extern bool threads_are_executing (process_stratum_target *targ);

/* Merge the executing property of thread PTID of TARG over to its
   thread state property (frontend running/stopped view).

   "not executing" -> "stopped"
   "executing"     -> "running"
   "exited"        -> "exited"

   If PTID is minus_one_ptid, go over all threads of TARG.

   Notifications are only emitted if the thread state did change.  */
extern void finish_thread_state (process_stratum_target *targ, ptid_t ptid);

/* Calls finish_thread_state on scope exit, unless release() is called
   to disengage.  */
using scoped_finish_thread_state
  = FORWARD_SCOPE_EXIT (finish_thread_state);

/* Commands with a prefix of `thread'.  */
extern struct cmd_list_element *thread_cmd_list;

extern void thread_command (const char *tidstr, int from_tty);

/* Print notices on thread events (attach, detach, etc.), set with
   `set print thread-events'.  */
extern bool print_thread_events;

/* Prints the list of threads and their details on UIOUT.  If
   REQUESTED_THREADS, a list of GDB ids/ranges, is not NULL, only
   print threads whose ID is included in the list.  If PID is not -1,
   only print threads from the process PID.  Otherwise, threads from
   all attached PIDs are printed.  If both REQUESTED_THREADS is not
   NULL and PID is not -1, then the thread is printed if it belongs to
   the specified process.  Otherwise, an error is raised.  */
extern void print_thread_info (struct ui_out *uiout,
			       const char *requested_threads,
			       int pid);

/* Save/restore current inferior/thread/frame.  */

class scoped_restore_current_thread
{
public:
  scoped_restore_current_thread ();
  ~scoped_restore_current_thread ();

  scoped_restore_current_thread (scoped_restore_current_thread &&rhs);

  DISABLE_COPY_AND_ASSIGN (scoped_restore_current_thread);

  /* Cancel restoring on scope exit.  */
  void dont_restore () { m_dont_restore = true; }

private:
  void restore ();

  bool m_dont_restore = false;
  thread_info_ref m_thread;
  inferior_ref m_inf;

  frame_id m_selected_frame_id;
  int m_selected_frame_level;
  bool m_was_stopped;
  /* Save/restore the language as well, because selecting a frame
     changes the current language to the frame's language if "set
     language auto".  */
  scoped_restore_current_language m_lang;
};

/* Returns a pointer into the thread_info corresponding to
   INFERIOR_PTID.  INFERIOR_PTID *must* be in the thread list.  */
extern struct thread_info* inferior_thread (void);

extern void update_thread_list (void);

/* Delete any thread the target says is no longer alive.  */

extern void prune_threads (void);

/* Delete threads marked THREAD_EXITED.  Unlike prune_threads, this
   does not consult the target about whether the thread is alive right
   now.  */
extern void delete_exited_threads (void);

/* Return true if PC is in the stepping range of THREAD.  */

bool pc_in_thread_step_range (CORE_ADDR pc, struct thread_info *thread);

/* Enable storing stack temporaries for thread THR and disable and
   clear the stack temporaries on destruction.  Holds a strong
   reference to THR.  */

class enable_thread_stack_temporaries
{
public:

  explicit enable_thread_stack_temporaries (struct thread_info *thr)
    : m_thr (thread_info_ref::new_reference (thr))
  {
    m_thr->stack_temporaries_enabled = true;
    m_thr->stack_temporaries.clear ();
  }

  ~enable_thread_stack_temporaries ()
  {
    m_thr->stack_temporaries_enabled = false;
    m_thr->stack_temporaries.clear ();
  }

  DISABLE_COPY_AND_ASSIGN (enable_thread_stack_temporaries);

private:

  thread_info_ref m_thr;
};

extern bool thread_stack_temporaries_enabled_p (struct thread_info *tp);

extern void push_thread_stack_temporary (struct thread_info *tp, struct value *v);

extern value *get_last_thread_stack_temporary (struct thread_info *tp);

extern bool value_in_thread_stack_temporaries (struct value *,
					       struct thread_info *thr);

/* Thread step-over list type.  */
using thread_step_over_list_node
  = intrusive_member_node<thread_info, &thread_info::step_over_list_node>;
using thread_step_over_list
  = intrusive_list<thread_info, thread_step_over_list_node>;
using thread_step_over_list_iterator
  = reference_to_pointer_iterator<thread_step_over_list::iterator>;
using thread_step_over_list_safe_iterator
  = basic_safe_iterator<thread_step_over_list_iterator>;
using thread_step_over_list_safe_range
  = iterator_range<thread_step_over_list_safe_iterator>;

static inline thread_step_over_list_safe_range
make_thread_step_over_list_safe_range (thread_step_over_list &list)
{
  return thread_step_over_list_safe_range
    (thread_step_over_list_safe_iterator (list.begin (),
					  list.end ()),
     thread_step_over_list_safe_iterator (list.end (),
					  list.end ()));
}

/* Add TP to the end of the global pending step-over chain.  */

extern void global_thread_step_over_chain_enqueue (thread_info *tp);

/* Append the thread step over list LIST to the global thread step over
   chain. */

extern void global_thread_step_over_chain_enqueue_chain
  (thread_step_over_list &&list);

/* Remove TP from the global pending step-over chain.  */

extern void global_thread_step_over_chain_remove (thread_info *tp);

/* Return true if TP is in any step-over chain.  */

extern int thread_is_in_step_over_chain (struct thread_info *tp);

/* Return the length of the the step over chain TP is in.

   If TP is non-nullptr, the thread must be in a step over chain.
   TP may be nullptr, in which case it denotes an empty list, so a length of
   0.  */

extern int thread_step_over_chain_length (const thread_step_over_list &l);

/* Cancel any ongoing execution command.  */

extern void thread_cancel_execution_command (struct thread_info *thr);

/* Check whether it makes sense to access a register of the current
   thread at this point.  If not, throw an error (e.g., the thread is
   executing).  */
extern void validate_registers_access (void);

/* Check whether it makes sense to access a register of THREAD at this point.
   Returns true if registers may be accessed; false otherwise.  */
extern bool can_access_registers_thread (struct thread_info *thread);

/* Returns whether to show which thread hit the breakpoint, received a
   signal, etc. and ended up causing a user-visible stop.  This is
   true iff we ever detected multiple threads.  */
extern int show_thread_that_caused_stop (void);

/* Print the message for a thread or/and frame selected.  */
extern void print_selected_thread_frame (struct ui_out *uiout,
					 user_selected_what selection);

/* Helper for the CLI's "thread" command and for MI's -thread-select.
   Selects thread THR.  TIDSTR is the original string the thread ID
   was parsed from.  This is used in the error message if THR is not
   alive anymore.  */
extern void thread_select (const char *tidstr, class thread_info *thr);

/* Return THREAD's name.

   If THREAD has a user-given name, return it.  Otherwise, query the thread's
   target to get the name.  May return nullptr.  */
extern const char *thread_name (thread_info *thread);

/* Switch to thread TP if it is alive.  Returns true if successfully
   switched, false otherwise.  */

extern bool switch_to_thread_if_alive (thread_info *thr);

/* Assuming that THR is the current thread, execute CMD.
   If ADA_TASK is not empty, it is the Ada task ID, and will
   be printed instead of the thread information.
   FLAGS.QUIET controls the printing of the thread information.
   FLAGS.CONT and FLAGS.SILENT control how to handle errors.  Can throw an
   exception if !FLAGS.SILENT and !FLAGS.CONT and CMD fails.  */

extern void thread_try_catch_cmd (thread_info *thr,
				  std::optional<int> ada_task,
				  const char *cmd, int from_tty,
				  const qcs_flags &flags);

/* Return a string representation of STATE.  */

extern const char *thread_state_string (enum thread_state state);

#endif /* GDB_GDBTHREAD_H */
