This is the mail archive of the gdb-cvs@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[binutils-gdb] Use thread_info and inferior pointers more throughout


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=00431a78b28f913a9d5c912c49680e39cfd20847

commit 00431a78b28f913a9d5c912c49680e39cfd20847
Author: Pedro Alves <palves@redhat.com>
Date:   Thu Jun 21 17:09:31 2018 +0100

    Use thread_info and inferior pointers more throughout
    
    This is more preparation bits for multi-target support.
    
    In a multi-target scenario, we need to address the case of different
    processes/threads running on different targets that happen to have the
    same PID/PTID.  E.g., we can have both process 123 in target 1, and
    process 123 in target 2, while they're in reality different processes
    running on different machines.  Or maybe we've loaded multiple
    instances of the same core file.  Etc.
    
    To address this, in my WIP multi-target branch, threads and processes
    are uniquely identified by the (process_stratum target_ops *, ptid_t)
    and (process_stratum target_ops *, pid) tuples respectively.  I.e.,
    each process_stratum instance has its own thread/process number space.
    
    As you can imagine, that requires passing around target_ops * pointers
    in a number of functions where we're currently passing only a ptid_t
    or an int.  E.g., when we look up a thread_info object by ptid_t in
    find_thread_ptid, the ptid_t alone isn't sufficient.
    
    In many cases though, we already have the thread_info or inferior
    pointer handy, but we "lose" it somewhere along the call stack, only
    to look it up again by ptid_t/pid.  Since thread_info or inferior
    objects know their parent target, if we pass around thread_info or
    inferior pointers when possible, we avoid having to add extra
    target_ops parameters to many functions, and also, we eliminate a
    number of by ptid_t/int lookups.
    
    So that's what this patch does.  In a bit more detail:
    
    - Changes a number of functions and methods to take a thread_info or
      inferior pointer instead of a ptid_t or int parameter.
    
    - Changes a number of structure fields from ptid_t/int to inferior or
      thread_info pointers.
    
    - Uses the inferior_thread() function whenever possible instead of
      inferior_ptid.
    
    - Uses thread_info pointers directly when possible instead of the
      is_running/is_stopped etc. routines that require a lookup.
    
    - A number of functions are eliminated along the way, such as:
    
      int valid_gdb_inferior_id (int num);
      int pid_to_gdb_inferior_id (int pid);
      int gdb_inferior_id_to_pid (int num);
      int in_inferior_list (int pid);
    
    - A few structures and places hold a thread_info pointer across
      inferior execution, so now they take a strong reference to the
      (refcounted) thread_info object to avoid the thread_info pointer
      getting stale.  This is done in enable_thread_stack_temporaries and
      in the infcall.c code.
    
    - Related, there's a spot in infcall.c where using a RAII object to
      handle the refcount would be handy, so a gdb::ref_ptr specialization
      for thread_info is added (thread_info_ref, in gdbthread.h), along
      with a gdb_ref_ptr policy that works for all refcounted_object types
      (in common/refcounted-object.h).
    
    gdb/ChangeLog:
    2018-06-21  Pedro Alves  <palves@redhat.com>
    
    	* ada-lang.h (ada_get_task_number): Take a thread_info pointer
    	instead of a ptid_t.  All callers adjusted.
    	* ada-tasks.c (ada_get_task_number): Likewise.  All callers
    	adjusted.
    	(print_ada_task_info, display_current_task_id, task_command_1):
    	Adjust.
    	* breakpoint.c (watchpoint_in_thread_scope): Adjust to use
    	inferior_thread.
    	(breakpoint_kind): Adjust.
    	(remove_breakpoints_pid): Rename to ...
    	(remove_breakpoints_inf): ... this.  Adjust to take an inferior
    	pointer.  All callers adjusted.
    	(bpstat_clear_actions): Use inferior_thread.
    	(get_bpstat_thread): New.
    	(bpstat_do_actions): Use it.
    	(bpstat_check_breakpoint_conditions, bpstat_stop_status): Adjust
    	to take a thread_info pointer.  All callers adjusted.
    	(set_longjmp_breakpoint_for_call_dummy, set_momentary_breakpoint)
    	(breakpoint_re_set_thread): Use inferior_thread.
    	* breakpoint.h (struct inferior): Forward declare.
    	(bpstat_stop_status): Update.
    	(remove_breakpoints_pid): Delete.
    	(remove_breakpoints_inf): New.
    	* bsd-uthread.c (bsd_uthread_target::wait)
    	(bsd_uthread_target::update_thread_list): Use find_thread_ptid.
    	* btrace.c (btrace_add_pc, btrace_enable, btrace_fetch)
    	(maint_btrace_packet_history_cmd)
    	(maint_btrace_clear_packet_history_cmd): Adjust.
    	(maint_btrace_clear_cmd, maint_info_btrace_cmd): Adjust to use
    	inferior_thread.
    	* cli/cli-interp.c: Include "inferior.h".
    	* common/refcounted-object.h (struct
    	refcounted_object_ref_policy): New.
    	* compile/compile-object-load.c: Include gdbthread.h.
    	(store_regs): Use inferior_thread.
    	* corelow.c (core_target::close): Use current_inferior.
    	(core_target_open): Adjust to use first_thread_of_inferior and use
    	the current inferior.
    	* ctf.c (ctf_target::close): Adjust to use current_inferior.
    	* dummy-frame.c (dummy_frame_id) <ptid>: Delete, replaced by ...
    	<thread>: ... this new field.  All references adjusted.
    	(dummy_frame_pop, dummy_frame_discard, register_dummy_frame_dtor):
    	Take a thread_info pointer instead of a ptid_t.
    	* dummy-frame.h (dummy_frame_push, dummy_frame_pop)
    	(dummy_frame_discard, register_dummy_frame_dtor): Take a
    	thread_info pointer instead of a ptid_t.
    	* elfread.c: Include "inferior.h".
    	(elf_gnu_ifunc_resolver_stop, elf_gnu_ifunc_resolver_return_stop):
    	Use inferior_thread.
    	* eval.c (evaluate_subexp): Likewise.
    	* frame.c (frame_pop, has_stack_frames, find_frame_sal): Use
    	inferior_thread.
    	* gdb_proc_service.h (struct thread_info): Forward declare.
    	(struct ps_prochandle) <ptid>: Delete, replaced by ...
    	<thread>: ... this new field.  All references adjusted.
    	* gdbarch.h, gdbarch.c: Regenerate.
    	* gdbarch.sh (get_syscall_number): Replace 'ptid' parameter with a
    	'thread' parameter.  All implementations and callers adjusted.
    	* gdbthread.h (thread_info) <set_running>: New method.
    	(delete_thread, delete_thread_silent): Take a thread_info pointer
    	instead of a ptid.
    	(global_thread_id_to_ptid, ptid_to_global_thread_id): Delete.
    	(first_thread_of_process): Delete, replaced by ...
    	(first_thread_of_inferior): ... this new function.  All callers
    	adjusted.
    	(any_live_thread_of_process): Delete, replaced by ...
    	(any_live_thread_of_inferior): ... this new function.  All callers
    	adjusted.
    	(switch_to_thread, switch_to_no_thread): Declare.
    	(is_executing): Delete.
    	(enable_thread_stack_temporaries): Update comment.
    	<enable_thread_stack_temporaries>: Take a thread_info pointer
    	instead of a ptid_t.  Incref the thread.
    	<~enable_thread_stack_temporaries>: Decref the thread.
    	<m_ptid>: Delete
    	<m_thr>: New.
    	(thread_stack_temporaries_enabled_p, push_thread_stack_temporary)
    	(get_last_thread_stack_temporary)
    	(value_in_thread_stack_temporaries, can_access_registers_thread):
    	Take a thread_info pointer instead of a ptid_t.  All callers
    	adjusted.
    	* infcall.c (get_call_return_value): Use inferior_thread.
    	(run_inferior_call): Work with thread pointers instead of ptid_t.
    	(call_function_by_hand_dummy): Work with thread pointers instead
    	of ptid_t.  Use thread_info_ref.
    	* infcmd.c (proceed_thread_callback): Access thread's state
    	directly.
    	(ensure_valid_thread, ensure_not_running): Use inferior_thread,
    	access thread's state directly.
    	(continue_command): Use inferior_thread.
    	(info_program_command): Use find_thread_ptid and access thread
    	state directly.
    	(proceed_after_attach_callback): Use thread state directly.
    	(notice_new_inferior): Take a thread_info pointer instead of a
    	ptid_t.  All callers adjusted.
    	(exit_inferior): Take an inferior pointer instead of a pid.  All
    	callers adjusted.
    	(exit_inferior_silent): New.
    	(detach_inferior): Delete.
    	(valid_gdb_inferior_id, pid_to_gdb_inferior_id)
    	(gdb_inferior_id_to_pid, in_inferior_list): Delete.
    	(detach_inferior_command, kill_inferior_command): Use
    	find_inferior_id instead of valid_gdb_inferior_id and
    	gdb_inferior_id_to_pid.
    	(inferior_command): Use inferior and thread pointers.
    	* inferior.h (struct thread_info): Forward declare.
    	(notice_new_inferior): Take a thread_info pointer instead of a
    	ptid_t.  All callers adjusted.
    	(detach_inferior): Delete declaration.
    	(exit_inferior, exit_inferior_silent): Take an inferior pointer
    	instead of a pid.  All callers adjusted.
    	(gdb_inferior_id_to_pid, pid_to_gdb_inferior_id, in_inferior_list)
    	(valid_gdb_inferior_id): Delete.
    	* infrun.c (follow_fork_inferior, proceed_after_vfork_done)
    	(handle_vfork_child_exec_or_exit, follow_exec): Adjust.
    	(struct displaced_step_inferior_state) <pid>: Delete, replaced by
    	...
    	<inf>: ... this new field.
    	<step_ptid>: Delete, replaced by ...
    	<step_thread>: ... this new field.
    	(get_displaced_stepping_state): Take an inferior pointer instead
    	of a pid.  All callers adjusted.
    	(displaced_step_in_progress_any_inferior): Adjust.
    	(displaced_step_in_progress_thread): Take a thread pointer instead
    	of a ptid_t.  All callers adjusted.
    	(displaced_step_in_progress, add_displaced_stepping_state): Take
    	an inferior pointer instead of a pid.  All callers adjusted.
    	(get_displaced_step_closure_by_addr): Adjust.
    	(remove_displaced_stepping_state): Take an inferior pointer
    	instead of a pid.  All callers adjusted.
    	(displaced_step_prepare_throw, displaced_step_prepare)
    	(displaced_step_fixup): Take a thread pointer instead of a ptid_t.
    	All callers adjusted.
    	(start_step_over): Adjust.
    	(infrun_thread_ptid_changed): Remove bit updating ptids in the
    	displaced step queue.
    	(do_target_resume): Adjust.
    	(fetch_inferior_event): Use inferior_thread.
    	(context_switch, get_inferior_stop_soon): Take an
    	execution_control_state pointer instead of a ptid_t.  All callers
    	adjusted.
    	(switch_to_thread_cleanup): Delete.
    	(stop_all_threads): Use scoped_restore_current_thread.
    	* inline-frame.c: Include "gdbthread.h".
    	(inline_state) <inline_state>: Take a thread pointer instead of a
    	ptid_t.  All callers adjusted.
    	<ptid>: Delete, replaced by ...
    	<thread>: ... this new field.
    	(find_inline_frame_state): Take a thread pointer instead of a
    	ptid_t.  All callers adjusted.
    	(skip_inline_frames, step_into_inline_frame)
    	(inline_skipped_frames, inline_skipped_symbol): Take a thread
    	pointer instead of a ptid_t.  All callers adjusted.
    	* inline-frame.h (skip_inline_frames, step_into_inline_frame)
    	(inline_skipped_frames, inline_skipped_symbol): Likewise.
    	* linux-fork.c (delete_checkpoint_command): Adjust to use thread
    	pointers directly.
    	* linux-nat.c (get_detach_signal): Likewise.
    	* linux-thread-db.c (thread_from_lwp): New 'stopped' parameter.
    	(thread_db_notice_clone): Adjust.
    	(thread_db_find_new_threads_silently)
    	(thread_db_find_new_threads_2, thread_db_find_new_threads_1): Take
    	a thread pointer instead of a ptid_t.  All callers adjusted.
    	* mi/mi-cmd-var.c: Include "inferior.h".
    	(mi_cmd_var_update_iter): Update to use thread pointers.
    	* mi/mi-interp.c (mi_new_thread): Update to use the thread's
    	inferior directly.
    	(mi_output_running_pid, mi_inferior_count): Delete, bits factored
    	out to ...
    	(mi_output_running): ... this new function.
    	(mi_on_resume_1): Adjust to use it.
    	(mi_user_selected_context_changed): Adjust to use inferior_thread.
    	* mi/mi-main.c (proceed_thread): Adjust to use thread pointers
    	directly.
    	(interrupt_thread_callback): : Adjust to use thread and inferior
    	pointers.
    	* proc-service.c: Include "gdbthread.h".
    	(ps_pglobal_lookup): Adjust to use the thread's inferior directly.
    	* progspace-and-thread.c: Include "inferior.h".
    	* progspace.c: Include "inferior.h".
    	* python/py-exitedevent.c (create_exited_event_object): Adjust to
    	hold a reference to an inferior_object.
    	* python/py-finishbreakpoint.c (bpfinishpy_init): Adjust to use
    	inferior_thread.
    	* python/py-inferior.c (struct inferior_object): Give the type a
    	tag name instead of a typedef.
    	(python_on_normal_stop): No need to check if the current thread is
    	listed.
    	(inferior_to_inferior_object): Change return type to
    	inferior_object.  All callers adjusted.
    	(find_thread_object): Delete, bits factored out to ...
    	(thread_to_thread_object): ... this new function.
    	* python/py-infthread.c (create_thread_object): Use
    	inferior_to_inferior_object.
    	(thpy_is_stopped): Use thread pointer directly.
    	(gdbpy_selected_thread): Use inferior_thread.
    	* python/py-record-btrace.c (btpy_list_object) <ptid>: Delete
    	field, replaced with ...
    	<thread>: ... this new field.  All users adjusted.
    	(btpy_insn_or_gap_new): Drop const.
    	(btpy_list_new): Take a thread pointer instead of a ptid_t.  All
    	callers adjusted.
    	* python/py-record.c: Include "gdbthread.h".
    	(recpy_insn_new, recpy_func_new): Take a thread pointer instead of
    	a ptid_t.  All callers adjusted.
    	(gdbpy_current_recording): Use inferior_thread.
    	* python/py-record.h (recpy_record_object) <ptid>: Delete
    	field, replaced with ...
    	<thread>: ... this new field.  All users adjusted.
    	(recpy_element_object) <ptid>: Delete
    	field, replaced with ...
    	<thread>: ... this new field.  All users adjusted.
    	(recpy_insn_new, recpy_func_new): Take a thread pointer instead of
    	a ptid_t.  All callers adjusted.
    	* python/py-threadevent.c: Include "gdbthread.h".
    	(get_event_thread): Use thread_to_thread_object.
    	* python/python-internal.h (struct inferior_object): Forward
    	declare.
    	(find_thread_object, find_inferior_object): Delete declarations.
    	(thread_to_thread_object, inferior_to_inferior_object): New
    	declarations.
    	* record-btrace.c: Include "inferior.h".
    	(require_btrace_thread): Use inferior_thread.
    	(record_btrace_frame_sniffer)
    	(record_btrace_tailcall_frame_sniffer): Use inferior_thread.
    	(get_thread_current_frame): Use scoped_restore_current_thread and
    	switch_to_thread.
    	(get_thread_current_frame): Use thread pointer directly.
    	(record_btrace_replay_at_breakpoint): Use thread's inferior
    	pointer directly.
    	* record-full.c: Include "inferior.h".
    	* regcache.c: Include "gdbthread.h".
    	(get_thread_arch_regcache): Use the inferior's address space
    	directly.
    	(get_thread_regcache, registers_changed_thread): New.
    	* regcache.h (get_thread_regcache(thread_info *thread)): New
    	overload.
    	(registers_changed_thread): New.
    	(remote_target) <remote_detach_1>: Swap order of parameters.
    	(remote_add_thread): <remote_add_thread>: Return the new thread.
    	(get_remote_thread_info(ptid_t)): New overload.
    	(remote_target::remote_notice_new_inferior): Use thread pointers
    	directly.
    	(remote_target::process_initial_stop_replies): Use
    	thread_info::set_running.
    	(remote_target::remote_detach_1, remote_target::detach)
    	(extended_remote_target::detach): Adjust.
    	* stack.c (frame_show_address): Use inferior_thread.
    	* target-debug.h (target_debug_print_thread_info_pp): New.
    	* target-delegates.c: Regenerate.
    	* target.c (default_thread_address_space): Delete.
    	(memory_xfer_partial_1): Use current_inferior.
    	(target_detach): Use current_inferior.
    	(target_thread_address_space): Delete.
    	(generic_mourn_inferior): Use current_inferior.
    	* target.h (struct target_ops) <thread_address_space>: Delete.
    	(target_thread_address_space): Delete.
    	* thread.c (init_thread_list): Use ALL_THREADS_SAFE.  Use thread
    	pointers directly.
    	(delete_thread_1, delete_thread, delete_thread_silent): Take a
    	thread pointer instead of a ptid_t.  Adjust all callers.
    	(ptid_to_global_thread_id, global_thread_id_to_ptid): Delete.
    	(first_thread_of_process): Delete, replaced by ...
    	(first_thread_of_inferior): ... this new function.  All callers
    	adjusted.
    	(any_thread_of_process): Rename to ...
    	(any_thread_of_inferior): ... this, and take an inferior pointer.
    	(any_live_thread_of_process): Rename to ...
    	(any_live_thread_of_inferior): ... this, and take an inferior
    	pointer.
    	(thread_stack_temporaries_enabled_p, push_thread_stack_temporary)
    	(value_in_thread_stack_temporaries)
    	(get_last_thread_stack_temporary): Take a thread pointer instead
    	of a ptid_t.  Adjust all callers.
    	(thread_info::set_running): New.
    	(validate_registers_access): Use inferior_thread.
    	(can_access_registers_ptid): Rename to ...
    	(can_access_registers_thread): ... this, and take a thread
    	pointer.
    	(print_thread_info_1): Adjust to compare thread pointers instead
    	of ptids.
    	(switch_to_no_thread, switch_to_thread): Make extern.
    	(scoped_restore_current_thread::~scoped_restore_current_thread):
    	Use m_thread pointer directly.
    	(scoped_restore_current_thread::scoped_restore_current_thread):
    	Use inferior_thread.
    	(thread_command): Use thread pointer directly.
    	(thread_num_make_value_helper): Use inferior_thread.
    	* top.c (execute_command): Use inferior_thread.
    	* tui/tui-interp.c: Include "inferior.h".
    	* varobj.c (varobj_create): Use inferior_thread.
    	(value_of_root_1): Use find_thread_global_id instead of
    	global_thread_id_to_ptid.

Diff:
---
 gdb/ChangeLog                     | 296 +++++++++++++++++++++++++++++++++
 gdb/aarch64-linux-tdep.c          |   4 +-
 gdb/ada-lang.h                    |   2 +-
 gdb/ada-tasks.c                   |  21 +--
 gdb/amd64-linux-tdep.c            |   4 +-
 gdb/arm-linux-tdep.c              |   4 +-
 gdb/bfin-linux-tdep.c             |   4 +-
 gdb/breakpoint.c                  |  76 +++++----
 gdb/breakpoint.h                  |   5 +-
 gdb/bsd-uthread.c                 |   6 +-
 gdb/btrace.c                      |  30 ++--
 gdb/cli/cli-interp.c              |   1 +
 gdb/common/refcounted-object.h    |  16 ++
 gdb/compile/compile-object-load.c |   4 +-
 gdb/corelow.c                     |   8 +-
 gdb/ctf.c                         |   5 +-
 gdb/dummy-frame.c                 |  30 ++--
 gdb/dummy-frame.h                 |  20 ++-
 gdb/elfread.c                     |   6 +-
 gdb/eval.c                        |   6 +-
 gdb/fbsd-tdep.c                   |   3 +-
 gdb/frame.c                       |  11 +-
 gdb/gdb_proc_service.h            |   4 +-
 gdb/gdbarch.c                     |   4 +-
 gdb/gdbarch.h                     |   4 +-
 gdb/gdbarch.sh                    |   2 +-
 gdb/gdbthread.h                   |  91 +++++-----
 gdb/i386-linux-tdep.c             |   4 +-
 gdb/infcall.c                     |  66 ++++----
 gdb/infcmd.c                      |  41 ++---
 gdb/inferior.c                    | 115 ++++---------
 gdb/inferior.h                    |  25 +--
 gdb/infrun.c                      | 340 +++++++++++++++++---------------------
 gdb/inline-frame.c                |  48 +++---
 gdb/inline-frame.h                |   8 +-
 gdb/linux-fork.c                  |   7 +-
 gdb/linux-nat.c                   |  36 ++--
 gdb/linux-thread-db.c             |  54 +++---
 gdb/mi/mi-cmd-var.c               |  22 +--
 gdb/mi/mi-interp.c                |  63 ++++---
 gdb/mi/mi-main.c                  |  47 +++---
 gdb/mips-linux-tdep.c             |   4 +-
 gdb/ppc-linux-tdep.c              |   4 +-
 gdb/proc-service.c                |  23 +--
 gdb/progspace-and-thread.c        |   7 +-
 gdb/progspace.c                   |   1 +
 gdb/python/py-exitedevent.c       |   4 +-
 gdb/python/py-finishbreakpoint.c  |   5 +-
 gdb/python/py-inferior.c          |  49 +++---
 gdb/python/py-infthread.c         |  24 +--
 gdb/python/py-record-btrace.c     |  54 +++---
 gdb/python/py-record.c            |  17 +-
 gdb/python/py-record.h            |  12 +-
 gdb/python/py-threadevent.c       |   5 +-
 gdb/python/python-internal.h      |   9 +-
 gdb/record-btrace.c               |  50 +++---
 gdb/record-full.c                 |   1 +
 gdb/regcache.c                    |  19 ++-
 gdb/regcache.h                    |   9 +
 gdb/remote.c                      |  61 +++----
 gdb/s390-linux-tdep.c             |   4 +-
 gdb/sparc-linux-tdep.c            |   4 +-
 gdb/sparc64-linux-tdep.c          |   4 +-
 gdb/stack.c                       |   2 +-
 gdb/target-debug.h                |   2 +
 gdb/target.c                      |  24 +--
 gdb/thread.c                      | 229 ++++++++++++-------------
 gdb/top.c                         |   7 +-
 gdb/tracefile-tfile.c             |   5 +-
 gdb/tui/tui-interp.c              |   1 +
 gdb/varobj.c                      |   8 +-
 71 files changed, 1198 insertions(+), 993 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 6345d85..1221a54 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,299 @@
+2018-06-21  Pedro Alves  <palves@redhat.com>
+
+	* ada-lang.h (ada_get_task_number): Take a thread_info pointer
+	instead of a ptid_t.  All callers adjusted.
+	* ada-tasks.c (ada_get_task_number): Likewise.  All callers
+	adjusted.
+	(print_ada_task_info, display_current_task_id, task_command_1):
+	Adjust.
+	* breakpoint.c (watchpoint_in_thread_scope): Adjust to use
+	inferior_thread.
+	(breakpoint_kind): Adjust.
+	(remove_breakpoints_pid): Rename to ...
+	(remove_breakpoints_inf): ... this.  Adjust to take an inferior
+	pointer.  All callers adjusted.
+	(bpstat_clear_actions): Use inferior_thread.
+	(get_bpstat_thread): New.
+	(bpstat_do_actions): Use it.
+	(bpstat_check_breakpoint_conditions, bpstat_stop_status): Adjust
+	to take a thread_info pointer.  All callers adjusted.
+	(set_longjmp_breakpoint_for_call_dummy, set_momentary_breakpoint)
+	(breakpoint_re_set_thread): Use inferior_thread.
+	* breakpoint.h (struct inferior): Forward declare.
+	(bpstat_stop_status): Update.
+	(remove_breakpoints_pid): Delete.
+	(remove_breakpoints_inf): New.
+	* bsd-uthread.c (bsd_uthread_target::wait)
+	(bsd_uthread_target::update_thread_list): Use find_thread_ptid.
+	* btrace.c (btrace_add_pc, btrace_enable, btrace_fetch)
+	(maint_btrace_packet_history_cmd)
+	(maint_btrace_clear_packet_history_cmd): Adjust.
+	(maint_btrace_clear_cmd, maint_info_btrace_cmd): Adjust to use
+	inferior_thread.
+	* cli/cli-interp.c: Include "inferior.h".
+	* common/refcounted-object.h (struct
+	refcounted_object_ref_policy): New.
+	* compile/compile-object-load.c: Include gdbthread.h.
+	(store_regs): Use inferior_thread.
+	* corelow.c (core_target::close): Use current_inferior.
+	(core_target_open): Adjust to use first_thread_of_inferior and use
+	the current inferior.
+	* ctf.c (ctf_target::close): Adjust to use current_inferior.
+	* dummy-frame.c (dummy_frame_id) <ptid>: Delete, replaced by ...
+	<thread>: ... this new field.  All references adjusted.
+	(dummy_frame_pop, dummy_frame_discard, register_dummy_frame_dtor):
+	Take a thread_info pointer instead of a ptid_t.
+	* dummy-frame.h (dummy_frame_push, dummy_frame_pop)
+	(dummy_frame_discard, register_dummy_frame_dtor): Take a
+	thread_info pointer instead of a ptid_t.
+	* elfread.c: Include "inferior.h".
+	(elf_gnu_ifunc_resolver_stop, elf_gnu_ifunc_resolver_return_stop):
+	Use inferior_thread.
+	* eval.c (evaluate_subexp): Likewise.
+	* frame.c (frame_pop, has_stack_frames, find_frame_sal): Use
+	inferior_thread.
+	* gdb_proc_service.h (struct thread_info): Forward declare.
+	(struct ps_prochandle) <ptid>: Delete, replaced by ...
+	<thread>: ... this new field.  All references adjusted.
+	* gdbarch.h, gdbarch.c: Regenerate.
+	* gdbarch.sh (get_syscall_number): Replace 'ptid' parameter with a
+	'thread' parameter.  All implementations and callers adjusted.
+	* gdbthread.h (thread_info) <set_running>: New method.
+	(delete_thread, delete_thread_silent): Take a thread_info pointer
+	instead of a ptid.
+	(global_thread_id_to_ptid, ptid_to_global_thread_id): Delete.
+	(first_thread_of_process): Delete, replaced by ...
+	(first_thread_of_inferior): ... this new function.  All callers
+	adjusted.
+	(any_live_thread_of_process): Delete, replaced by ...
+	(any_live_thread_of_inferior): ... this new function.  All callers
+	adjusted.
+	(switch_to_thread, switch_to_no_thread): Declare.
+	(is_executing): Delete.
+	(enable_thread_stack_temporaries): Update comment.
+	<enable_thread_stack_temporaries>: Take a thread_info pointer
+	instead of a ptid_t.  Incref the thread.
+	<~enable_thread_stack_temporaries>: Decref the thread.
+	<m_ptid>: Delete
+	<m_thr>: New.
+	(thread_stack_temporaries_enabled_p, push_thread_stack_temporary)
+	(get_last_thread_stack_temporary)
+	(value_in_thread_stack_temporaries, can_access_registers_thread):
+	Take a thread_info pointer instead of a ptid_t.  All callers
+	adjusted.
+	* infcall.c (get_call_return_value): Use inferior_thread.
+	(run_inferior_call): Work with thread pointers instead of ptid_t.
+	(call_function_by_hand_dummy): Work with thread pointers instead
+	of ptid_t.  Use thread_info_ref.
+	* infcmd.c (proceed_thread_callback): Access thread's state
+	directly.
+	(ensure_valid_thread, ensure_not_running): Use inferior_thread,
+	access thread's state directly.
+	(continue_command): Use inferior_thread.
+	(info_program_command): Use find_thread_ptid and access thread
+	state directly.
+	(proceed_after_attach_callback): Use thread state directly.
+	(notice_new_inferior): Take a thread_info pointer instead of a
+	ptid_t.  All callers adjusted.
+	(exit_inferior): Take an inferior pointer instead of a pid.  All
+	callers adjusted.
+	(exit_inferior_silent): New.
+	(detach_inferior): Delete.
+	(valid_gdb_inferior_id, pid_to_gdb_inferior_id)
+	(gdb_inferior_id_to_pid, in_inferior_list): Delete.
+	(detach_inferior_command, kill_inferior_command): Use
+	find_inferior_id instead of valid_gdb_inferior_id and
+	gdb_inferior_id_to_pid.
+	(inferior_command): Use inferior and thread pointers.
+	* inferior.h (struct thread_info): Forward declare.
+	(notice_new_inferior): Take a thread_info pointer instead of a
+	ptid_t.  All callers adjusted.
+	(detach_inferior): Delete declaration.
+	(exit_inferior, exit_inferior_silent): Take an inferior pointer
+	instead of a pid.  All callers adjusted.
+	(gdb_inferior_id_to_pid, pid_to_gdb_inferior_id, in_inferior_list)
+	(valid_gdb_inferior_id): Delete.
+	* infrun.c (follow_fork_inferior, proceed_after_vfork_done)
+	(handle_vfork_child_exec_or_exit, follow_exec): Adjust.
+	(struct displaced_step_inferior_state) <pid>: Delete, replaced by
+	...
+	<inf>: ... this new field.
+	<step_ptid>: Delete, replaced by ...
+	<step_thread>: ... this new field.
+	(get_displaced_stepping_state): Take an inferior pointer instead
+	of a pid.  All callers adjusted.
+	(displaced_step_in_progress_any_inferior): Adjust.
+	(displaced_step_in_progress_thread): Take a thread pointer instead
+	of a ptid_t.  All callers adjusted.
+	(displaced_step_in_progress, add_displaced_stepping_state): Take
+	an inferior pointer instead of a pid.  All callers adjusted.
+	(get_displaced_step_closure_by_addr): Adjust.
+	(remove_displaced_stepping_state): Take an inferior pointer
+	instead of a pid.  All callers adjusted.
+	(displaced_step_prepare_throw, displaced_step_prepare)
+	(displaced_step_fixup): Take a thread pointer instead of a ptid_t.
+	All callers adjusted.
+	(start_step_over): Adjust.
+	(infrun_thread_ptid_changed): Remove bit updating ptids in the
+	displaced step queue.
+	(do_target_resume): Adjust.
+	(fetch_inferior_event): Use inferior_thread.
+	(context_switch, get_inferior_stop_soon): Take an
+	execution_control_state pointer instead of a ptid_t.  All callers
+	adjusted.
+	(switch_to_thread_cleanup): Delete.
+	(stop_all_threads): Use scoped_restore_current_thread.
+	* inline-frame.c: Include "gdbthread.h".
+	(inline_state) <inline_state>: Take a thread pointer instead of a
+	ptid_t.  All callers adjusted.
+	<ptid>: Delete, replaced by ...
+	<thread>: ... this new field.
+	(find_inline_frame_state): Take a thread pointer instead of a
+	ptid_t.  All callers adjusted.
+	(skip_inline_frames, step_into_inline_frame)
+	(inline_skipped_frames, inline_skipped_symbol): Take a thread
+	pointer instead of a ptid_t.  All callers adjusted.
+	* inline-frame.h (skip_inline_frames, step_into_inline_frame)
+	(inline_skipped_frames, inline_skipped_symbol): Likewise.
+	* linux-fork.c (delete_checkpoint_command): Adjust to use thread
+	pointers directly.
+	* linux-nat.c (get_detach_signal): Likewise.
+	* linux-thread-db.c (thread_from_lwp): New 'stopped' parameter.
+	(thread_db_notice_clone): Adjust.
+	(thread_db_find_new_threads_silently)
+	(thread_db_find_new_threads_2, thread_db_find_new_threads_1): Take
+	a thread pointer instead of a ptid_t.  All callers adjusted.
+	* mi/mi-cmd-var.c: Include "inferior.h".
+	(mi_cmd_var_update_iter): Update to use thread pointers.
+	* mi/mi-interp.c (mi_new_thread): Update to use the thread's
+	inferior directly.
+	(mi_output_running_pid, mi_inferior_count): Delete, bits factored
+	out to ...
+	(mi_output_running): ... this new function.
+	(mi_on_resume_1): Adjust to use it.
+	(mi_user_selected_context_changed): Adjust to use inferior_thread.
+	* mi/mi-main.c (proceed_thread): Adjust to use thread pointers
+	directly.
+	(interrupt_thread_callback): : Adjust to use thread and inferior
+	pointers.
+	* proc-service.c: Include "gdbthread.h".
+	(ps_pglobal_lookup): Adjust to use the thread's inferior directly.
+	* progspace-and-thread.c: Include "inferior.h".
+	* progspace.c: Include "inferior.h".
+	* python/py-exitedevent.c (create_exited_event_object): Adjust to
+	hold a reference to an inferior_object.
+	* python/py-finishbreakpoint.c (bpfinishpy_init): Adjust to use
+	inferior_thread.
+	* python/py-inferior.c (struct inferior_object): Give the type a
+	tag name instead of a typedef.
+	(python_on_normal_stop): No need to check if the current thread is
+	listed.
+	(inferior_to_inferior_object): Change return type to
+	inferior_object.  All callers adjusted.
+	(find_thread_object): Delete, bits factored out to ...
+	(thread_to_thread_object): ... this new function.
+	* python/py-infthread.c (create_thread_object): Use
+	inferior_to_inferior_object.
+	(thpy_is_stopped): Use thread pointer directly.
+	(gdbpy_selected_thread): Use inferior_thread.
+	* python/py-record-btrace.c (btpy_list_object) <ptid>: Delete
+	field, replaced with ...
+	<thread>: ... this new field.  All users adjusted.
+	(btpy_insn_or_gap_new): Drop const.
+	(btpy_list_new): Take a thread pointer instead of a ptid_t.  All
+	callers adjusted.
+	* python/py-record.c: Include "gdbthread.h".
+	(recpy_insn_new, recpy_func_new): Take a thread pointer instead of
+	a ptid_t.  All callers adjusted.
+	(gdbpy_current_recording): Use inferior_thread.
+	* python/py-record.h (recpy_record_object) <ptid>: Delete
+	field, replaced with ...
+	<thread>: ... this new field.  All users adjusted.
+	(recpy_element_object) <ptid>: Delete
+	field, replaced with ...
+	<thread>: ... this new field.  All users adjusted.
+	(recpy_insn_new, recpy_func_new): Take a thread pointer instead of
+	a ptid_t.  All callers adjusted.
+	* python/py-threadevent.c: Include "gdbthread.h".
+	(get_event_thread): Use thread_to_thread_object.
+	* python/python-internal.h (struct inferior_object): Forward
+	declare.
+	(find_thread_object, find_inferior_object): Delete declarations.
+	(thread_to_thread_object, inferior_to_inferior_object): New
+	declarations.
+	* record-btrace.c: Include "inferior.h".
+	(require_btrace_thread): Use inferior_thread.
+	(record_btrace_frame_sniffer)
+	(record_btrace_tailcall_frame_sniffer): Use inferior_thread.
+	(get_thread_current_frame): Use scoped_restore_current_thread and
+	switch_to_thread.
+	(get_thread_current_frame): Use thread pointer directly.
+	(record_btrace_replay_at_breakpoint): Use thread's inferior
+	pointer directly.
+	* record-full.c: Include "inferior.h".
+	* regcache.c: Include "gdbthread.h".
+	(get_thread_arch_regcache): Use the inferior's address space
+	directly.
+	(get_thread_regcache, registers_changed_thread): New.
+	* regcache.h (get_thread_regcache(thread_info *thread)): New
+	overload.
+	(registers_changed_thread): New.
+	(remote_target) <remote_detach_1>: Swap order of parameters.
+	(remote_add_thread): <remote_add_thread>: Return the new thread.
+	(get_remote_thread_info(ptid_t)): New overload.
+	(remote_target::remote_notice_new_inferior): Use thread pointers
+	directly.
+	(remote_target::process_initial_stop_replies): Use
+	thread_info::set_running.
+	(remote_target::remote_detach_1, remote_target::detach)
+	(extended_remote_target::detach): Adjust.
+	* stack.c (frame_show_address): Use inferior_thread.
+	* target-debug.h (target_debug_print_thread_info_pp): New.
+	* target-delegates.c: Regenerate.
+	* target.c (default_thread_address_space): Delete.
+	(memory_xfer_partial_1): Use current_inferior.
+	(target_detach): Use current_inferior.
+	(target_thread_address_space): Delete.
+	(generic_mourn_inferior): Use current_inferior.
+	* target.h (struct target_ops) <thread_address_space>: Delete.
+	(target_thread_address_space): Delete.
+	* thread.c (init_thread_list): Use ALL_THREADS_SAFE.  Use thread
+	pointers directly.
+	(delete_thread_1, delete_thread, delete_thread_silent): Take a
+	thread pointer instead of a ptid_t.  Adjust all callers.
+	(ptid_to_global_thread_id, global_thread_id_to_ptid): Delete.
+	(first_thread_of_process): Delete, replaced by ...
+	(first_thread_of_inferior): ... this new function.  All callers
+	adjusted.
+	(any_thread_of_process): Rename to ...
+	(any_thread_of_inferior): ... this, and take an inferior pointer.
+	(any_live_thread_of_process): Rename to ...
+	(any_live_thread_of_inferior): ... this, and take an inferior
+	pointer.
+	(thread_stack_temporaries_enabled_p, push_thread_stack_temporary)
+	(value_in_thread_stack_temporaries)
+	(get_last_thread_stack_temporary): Take a thread pointer instead
+	of a ptid_t.  Adjust all callers.
+	(thread_info::set_running): New.
+	(validate_registers_access): Use inferior_thread.
+	(can_access_registers_ptid): Rename to ...
+	(can_access_registers_thread): ... this, and take a thread
+	pointer.
+	(print_thread_info_1): Adjust to compare thread pointers instead
+	of ptids.
+	(switch_to_no_thread, switch_to_thread): Make extern.
+	(scoped_restore_current_thread::~scoped_restore_current_thread):
+	Use m_thread pointer directly.
+	(scoped_restore_current_thread::scoped_restore_current_thread):
+	Use inferior_thread.
+	(thread_command): Use thread pointer directly.
+	(thread_num_make_value_helper): Use inferior_thread.
+	* top.c (execute_command): Use inferior_thread.
+	* tui/tui-interp.c: Include "inferior.h".
+	* varobj.c (varobj_create): Use inferior_thread.
+	(value_of_root_1): Use find_thread_global_id instead of
+	global_thread_id_to_ptid.
+
 2018-06-21  Alan Hayward  <alan.hayward@arm.com>
 
         * regcache.c (readable_regcache::read_part): Avoid memcpy when
diff --git a/gdb/aarch64-linux-tdep.c b/gdb/aarch64-linux-tdep.c
index 96dc8a1..93b6d41 100644
--- a/gdb/aarch64-linux-tdep.c
+++ b/gdb/aarch64-linux-tdep.c
@@ -366,9 +366,9 @@ aarch64_stap_parse_special_token (struct gdbarch *gdbarch,
 
 static LONGEST
 aarch64_linux_get_syscall_number (struct gdbarch *gdbarch,
-				  ptid_t ptid)
+				  thread_info *thread)
 {
-  struct regcache *regs = get_thread_regcache (ptid);
+  struct regcache *regs = get_thread_regcache (thread);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
 
   /* The content of register x8.  */
diff --git a/gdb/ada-lang.h b/gdb/ada-lang.h
index 9dcc5de..90bfa0a 100644
--- a/gdb/ada-lang.h
+++ b/gdb/ada-lang.h
@@ -401,7 +401,7 @@ extern int valid_task_id (int);
 
 extern struct ada_task_info *ada_get_task_info_from_ptid (ptid_t ptid);
 
-extern int ada_get_task_number (ptid_t);
+extern int ada_get_task_number (thread_info *thread);
 
 typedef void (ada_task_list_iterator_ftype) (struct ada_task_info *task);
 extern void iterate_over_live_ada_tasks
diff --git a/gdb/ada-tasks.c b/gdb/ada-tasks.c
index bbc0375..7e57d24 100644
--- a/gdb/ada-tasks.c
+++ b/gdb/ada-tasks.c
@@ -288,14 +288,14 @@ get_ada_tasks_inferior_data (struct inferior *inf)
   return data;
 }
 
-/* Return the task number of the task whose ptid is PTID, or zero
+/* Return the task number of the task whose thread is THREAD, or zero
    if the task could not be found.  */
 
 int
-ada_get_task_number (ptid_t ptid)
+ada_get_task_number (thread_info *thread)
 {
   int i;
-  struct inferior *inf = find_inferior_ptid (ptid);
+  struct inferior *inf = thread->inf;
   struct ada_tasks_inferior_data *data;
 
   gdb_assert (inf != NULL);
@@ -303,7 +303,7 @@ ada_get_task_number (ptid_t ptid)
 
   for (i = 0; i < VEC_length (ada_task_info_s, data->task_list); i++)
     if (ptid_equal (VEC_index (ada_task_info_s, data->task_list, i)->ptid,
-		    ptid))
+		    thread->ptid))
       return i + 1;
 
   return 0;  /* No matching task found.  */
@@ -1125,10 +1125,10 @@ print_ada_task_info (struct ui_out *uiout,
       /* Print the associated Thread ID.  */
       if (uiout->is_mi_like_p ())
         {
-	  const int thread_id = ptid_to_global_thread_id (task_info->ptid);
+	  thread_info *thread = find_thread_ptid (task_info->ptid);
 
-	  if (thread_id != 0)
-	    uiout->field_int ("thread-id", thread_id);
+	  if (thread != NULL)
+	    uiout->field_int ("thread-id", thread->global_num);
 	  else
 	    /* This should never happen unless there is a bug somewhere,
 	       but be resilient when that happens.  */
@@ -1284,7 +1284,7 @@ info_tasks_command (const char *arg, int from_tty)
 static void
 display_current_task_id (void)
 {
-  const int current_task = ada_get_task_number (inferior_ptid);
+  const int current_task = ada_get_task_number (inferior_thread ());
 
   if (current_task == 0)
     printf_filtered (_("[Current task is unknown]\n"));
@@ -1327,12 +1327,13 @@ task_command_1 (const char *taskno_str, int from_tty, struct inferior *inf)
      computed if target_get_ada_task_ptid has not been implemented for
      our target (yet).  Rather than cause an assertion error in that case,
      it's nicer for the user to just refuse to perform the task switch.  */
-  if (!find_thread_ptid (task_info->ptid))
+  thread_info *tp = find_thread_ptid (task_info->ptid);
+  if (tp == NULL)
     error (_("Unable to compute thread ID for task %d.\n"
              "Cannot switch to this task."),
            taskno);
 
-  switch_to_thread (task_info->ptid);
+  switch_to_thread (tp);
   ada_find_printable_frame (get_selected_frame (NULL));
   printf_filtered (_("[Switching to task %d]\n"), taskno);
   print_stack_frame (get_selected_frame (NULL),
diff --git a/gdb/amd64-linux-tdep.c b/gdb/amd64-linux-tdep.c
index 521e32a..ef9248d 100644
--- a/gdb/amd64-linux-tdep.c
+++ b/gdb/amd64-linux-tdep.c
@@ -222,9 +222,9 @@ amd64_linux_sigcontext_addr (struct frame_info *this_frame)
 
 static LONGEST
 amd64_linux_get_syscall_number (struct gdbarch *gdbarch,
-                                ptid_t ptid)
+				thread_info *thread)
 {
-  struct regcache *regcache = get_thread_regcache (ptid);
+  struct regcache *regcache = get_thread_regcache (thread);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   /* The content of a register.  */
   gdb_byte buf[8];
diff --git a/gdb/arm-linux-tdep.c b/gdb/arm-linux-tdep.c
index eb4e206..264e8ca 100644
--- a/gdb/arm-linux-tdep.c
+++ b/gdb/arm-linux-tdep.c
@@ -819,9 +819,9 @@ arm_linux_sigreturn_next_pc (struct regcache *regcache,
 
 static LONGEST
 arm_linux_get_syscall_number (struct gdbarch *gdbarch,
-			      ptid_t ptid)
+			      thread_info *thread)
 {
-  struct regcache *regs = get_thread_regcache (ptid);
+  struct regcache *regs = get_thread_regcache (thread);
 
   ULONGEST pc;
   ULONGEST cpsr;
diff --git a/gdb/bfin-linux-tdep.c b/gdb/bfin-linux-tdep.c
index f84e2e0..e3bbb0f 100644
--- a/gdb/bfin-linux-tdep.c
+++ b/gdb/bfin-linux-tdep.c
@@ -128,9 +128,9 @@ static const struct tramp_frame bfin_linux_sigframe =
 
 static LONGEST
 bfin_linux_get_syscall_number (struct gdbarch *gdbarch,
-                               ptid_t ptid)
+			       thread_info *thread)
 {
-  struct regcache *regcache = get_thread_regcache (ptid);
+  struct regcache *regcache = get_thread_regcache (thread);
   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
   /* The content of a register.  */
   gdb_byte buf[4];
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index f20bc50..80df193 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -1548,7 +1548,7 @@ watchpoint_in_thread_scope (struct watchpoint *b)
   return (b->pspace == current_program_space
 	  && (ptid_equal (b->watchpoint_thread, null_ptid)
 	      || (ptid_equal (inferior_ptid, b->watchpoint_thread)
-		  && !is_executing (inferior_ptid))));
+		  && !inferior_thread ()->executing)));
 }
 
 /* Set watchpoint B to disp_del_at_next_stop, even including its possible
@@ -2408,7 +2408,7 @@ breakpoint_kind (struct bp_location *bl, CORE_ADDR *addr)
       struct thread_info *thr = find_thread_global_id (bl->owner->thread);
       struct regcache *regcache;
 
-      regcache = get_thread_regcache (thr->ptid);
+      regcache = get_thread_regcache (thr);
 
       return gdbarch_breakpoint_kind_from_current_state (bl->gdbarch,
 							 regcache, addr);
@@ -3061,14 +3061,13 @@ Thread-specific breakpoint %d deleted - thread %s no longer in the thread list.\
     }
 }
 
-/* Remove breakpoints of process PID.  */
+/* Remove breakpoints of inferior INF.  */
 
 int
-remove_breakpoints_pid (int pid)
+remove_breakpoints_inf (inferior *inf)
 {
   struct bp_location *bl, **blp_tmp;
   int val;
-  struct inferior *inf = find_inferior_pid (pid);
 
   ALL_BP_LOCATIONS (bl, blp_tmp)
   {
@@ -4329,16 +4328,12 @@ bpstat_num (bpstat *bsp, int *num)
 void
 bpstat_clear_actions (void)
 {
-  struct thread_info *tp;
   bpstat bs;
 
-  if (ptid_equal (inferior_ptid, null_ptid))
-    return;
-
-  tp = find_thread_ptid (inferior_ptid);
-  if (tp == NULL)
+  if (inferior_ptid == null_ptid)
     return;
 
+  thread_info *tp = inferior_thread ();
   for (bs = tp->control.stop_bpstat; bs != NULL; bs = bs->next)
     {
       bs->commands = NULL;
@@ -4466,22 +4461,37 @@ bpstat_do_actions_1 (bpstat *bsp)
   return again;
 }
 
+/* Helper for bpstat_do_actions.  Get the current thread, if there's
+   one, is alive and has execution.  Return NULL otherwise.  */
+
+static thread_info *
+get_bpstat_thread ()
+{
+  if (inferior_ptid == null_ptid || !target_has_execution)
+    return NULL;
+
+  thread_info *tp = inferior_thread ();
+  if (tp->state == THREAD_EXITED || tp->executing)
+    return NULL;
+  return tp;
+}
+
 void
 bpstat_do_actions (void)
 {
   struct cleanup *cleanup_if_error = make_bpstat_clear_actions_cleanup ();
+  thread_info *tp;
 
   /* Do any commands attached to breakpoint we are stopped at.  */
-  while (!ptid_equal (inferior_ptid, null_ptid)
-	 && target_has_execution
-	 && !is_exited (inferior_ptid)
-	 && !is_executing (inferior_ptid))
-    /* Since in sync mode, bpstat_do_actions may resume the inferior,
-       and only return when it is stopped at the next breakpoint, we
-       keep doing breakpoint actions until it returns false to
-       indicate the inferior was not resumed.  */
-    if (!bpstat_do_actions_1 (&inferior_thread ()->control.stop_bpstat))
-      break;
+  while ((tp = get_bpstat_thread ()) != NULL)
+    {
+      /* Since in sync mode, bpstat_do_actions may resume the
+	 inferior, and only return when it is stopped at the next
+	 breakpoint, we keep doing breakpoint actions until it returns
+	 false to indicate the inferior was not resumed.  */
+      if (!bpstat_do_actions_1 (&tp->control.stop_bpstat))
+	break;
+    }
 
   discard_cleanups (cleanup_if_error);
 }
@@ -5154,7 +5164,7 @@ bpstat_check_watchpoint (bpstat bs)
    breakpoint, set BS->stop to 0.  */
 
 static void
-bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
+bpstat_check_breakpoint_conditions (bpstat bs, thread_info *thread)
 {
   const struct bp_location *bl;
   struct breakpoint *b;
@@ -5184,9 +5194,8 @@ bpstat_check_breakpoint_conditions (bpstat bs, ptid_t ptid)
   /* If this is a thread/task-specific breakpoint, don't waste cpu
      evaluating the condition if this isn't the specified
      thread/task.  */
-  if ((b->thread != -1 && b->thread != ptid_to_global_thread_id (ptid))
-      || (b->task != 0 && b->task != ada_get_task_number (ptid)))
-
+  if ((b->thread != -1 && b->thread != thread->global_num)
+      || (b->task != 0 && b->task != ada_get_task_number (thread)))
     {
       bs->stop = 0;
       return;
@@ -5387,7 +5396,7 @@ build_bpstat_chain (const address_space *aspace, CORE_ADDR bp_addr,
 
 bpstat
 bpstat_stop_status (const address_space *aspace,
-		    CORE_ADDR bp_addr, ptid_t ptid,
+		    CORE_ADDR bp_addr, thread_info *thread,
 		    const struct target_waitstatus *ws,
 		    bpstat stop_chain)
 {
@@ -5435,7 +5444,7 @@ bpstat_stop_status (const address_space *aspace,
       b->ops->check_status (bs);
       if (bs->stop)
 	{
-	  bpstat_check_breakpoint_conditions (bs, ptid);
+	  bpstat_check_breakpoint_conditions (bs, thread);
 
 	  if (bs->stop)
 	    {
@@ -7316,7 +7325,7 @@ set_longjmp_breakpoint_for_call_dummy (void)
 	new_b = momentary_breakpoint_from_master (b, bp_longjmp_call_dummy,
 						  &momentary_breakpoint_ops,
 						  1);
-	new_b->thread = ptid_to_global_thread_id (inferior_ptid);
+	new_b->thread = inferior_thread ()->global_num;
 
 	/* Link NEW_B into the chain of RETVAL breakpoints.  */
 
@@ -7356,7 +7365,7 @@ check_longjmp_breakpoint_for_call_dummy (struct thread_info *tp)
 	    || frame_find_by_id (dummy_b->frame_id) != NULL)
 	  continue;
 	
-	dummy_frame_discard (dummy_b->frame_id, tp->ptid);
+	dummy_frame_discard (dummy_b->frame_id, tp);
 
 	while (b->related_breakpoint != b)
 	  {
@@ -8497,11 +8506,7 @@ set_momentary_breakpoint (struct gdbarch *gdbarch, struct symtab_and_line sal,
   b->disposition = disp_donttouch;
   b->frame_id = frame_id;
 
-  /* If we're debugging a multi-threaded program, then we want
-     momentary breakpoints to be active in only a single thread of
-     control.  */
-  if (in_thread_list (inferior_ptid))
-    b->thread = ptid_to_global_thread_id (inferior_ptid);
+  b->thread = inferior_thread ()->global_num;
 
   update_global_location_list_nothrow (UGLL_MAY_INSERT);
 
@@ -13923,8 +13928,7 @@ breakpoint_re_set_thread (struct breakpoint *b)
 {
   if (b->thread != -1)
     {
-      if (in_thread_list (inferior_ptid))
-	b->thread = ptid_to_global_thread_id (inferior_ptid);
+      b->thread = inferior_thread ()->global_num;
 
       /* We're being called after following a fork.  The new fork is
 	 selected as current, and unless this was a vfork will have a
diff --git a/gdb/breakpoint.h b/gdb/breakpoint.h
index 4223158..3f75aa4 100644
--- a/gdb/breakpoint.h
+++ b/gdb/breakpoint.h
@@ -40,6 +40,7 @@ struct bpstats;
 struct bp_location;
 struct linespec_result;
 struct linespec_sals;
+struct inferior;
 
 /* Why are we removing the breakpoint from the target?  */
 
@@ -948,7 +949,7 @@ extern bpstat build_bpstat_chain (const address_space *aspace,
    commands, FIXME??? fields.  */
 
 extern bpstat bpstat_stop_status (const address_space *aspace,
-				  CORE_ADDR pc, ptid_t ptid,
+				  CORE_ADDR pc, thread_info *thread,
 				  const struct target_waitstatus *ws,
 				  bpstat stop_chain = NULL);
 
@@ -1396,7 +1397,7 @@ extern void insert_breakpoints (void);
 
 extern int remove_breakpoints (void);
 
-extern int remove_breakpoints_pid (int pid);
+extern int remove_breakpoints_inf (inferior *inf);
 
 /* This function can be used to update the breakpoint package's state
    after an exec() system call has been executed.
diff --git a/gdb/bsd-uthread.c b/gdb/bsd-uthread.c
index ee2e5ad..6ae673f 100644
--- a/gdb/bsd-uthread.c
+++ b/gdb/bsd-uthread.c
@@ -419,7 +419,8 @@ bsd_uthread_target::wait (ptid_t ptid, struct target_waitstatus *status,
     thread_change_ptid (inferior_ptid, ptid);
 
   /* Don't let the core see a ptid without a corresponding thread.  */
-  if (!in_thread_list (ptid) || is_exited (ptid))
+  thread_info *thread = find_thread_ptid (ptid);
+  if (thread == NULL || thread->state == THREAD_EXITED)
     add_thread (ptid);
 
   return ptid;
@@ -467,7 +468,8 @@ bsd_uthread_target::update_thread_list ()
     {
       ptid_t ptid = ptid_build (pid, 0, addr);
 
-      if (!in_thread_list (ptid) || is_exited (ptid))
+      thread_info *thread = find_thread_ptid (ptid);
+      if (thread == nullptr || thread->state == THREAD_EXITED)
 	{
 	  /* If INFERIOR_PTID doesn't have a tid member yet, then ptid
 	     is still the initial thread of the process.  Notify GDB
diff --git a/gdb/btrace.c b/gdb/btrace.c
index b8894a2..35dc90e 100644
--- a/gdb/btrace.c
+++ b/gdb/btrace.c
@@ -1567,7 +1567,7 @@ btrace_add_pc (struct thread_info *tp)
   struct regcache *regcache;
   CORE_ADDR pc;
 
-  regcache = get_thread_regcache (tp->ptid);
+  regcache = get_thread_regcache (tp);
   pc = regcache_read_pc (regcache);
 
   btrace.format = BTRACE_FORMAT_BTS;
@@ -1615,7 +1615,7 @@ btrace_enable (struct thread_info *tp, const struct btrace_config *conf)
 	 This is not relevant for BTRACE_FORMAT_PT since the trace will already
 	 start at the PC at which tracing was enabled.  */
       if (conf->format != BTRACE_FORMAT_PT
-	  && can_access_registers_ptid (tp->ptid))
+	  && can_access_registers_thread (tp))
 	btrace_add_pc (tp);
     }
   CATCH (exception, RETURN_MASK_ALL)
@@ -1911,7 +1911,7 @@ btrace_fetch (struct thread_info *tp, const struct btrace_cpu *cpu)
   inferior_ptid = tp->ptid;
 
   /* We should not be called on running or exited threads.  */
-  gdb_assert (can_access_registers_ptid (tp->ptid));
+  gdb_assert (can_access_registers_thread (tp));
 
   /* Let's first try to extend the trace we already have.  */
   if (!btinfo->functions.empty ())
@@ -3231,10 +3231,9 @@ static void
 maint_btrace_packet_history_cmd (const char *arg, int from_tty)
 {
   struct btrace_thread_info *btinfo;
-  struct thread_info *tp;
   unsigned int size, begin, end, from, to;
 
-  tp = find_thread_ptid (inferior_ptid);
+  thread_info *tp = find_thread_ptid (inferior_ptid);
   if (tp == NULL)
     error (_("No thread."));
 
@@ -3335,17 +3334,14 @@ maint_btrace_packet_history_cmd (const char *arg, int from_tty)
 static void
 maint_btrace_clear_packet_history_cmd (const char *args, int from_tty)
 {
-  struct btrace_thread_info *btinfo;
-  struct thread_info *tp;
-
   if (args != NULL && *args != 0)
     error (_("Invalid argument."));
 
-  tp = find_thread_ptid (inferior_ptid);
-  if (tp == NULL)
+  if (inferior_ptid == null_ptid)
     error (_("No thread."));
 
-  btinfo = &tp->btrace;
+  thread_info *tp = inferior_thread ();
+  btrace_thread_info *btinfo = &tp->btrace;
 
   /* Must clear the maint data before - it depends on BTINFO->DATA.  */
   btrace_maint_clear (btinfo);
@@ -3357,15 +3353,13 @@ maint_btrace_clear_packet_history_cmd (const char *args, int from_tty)
 static void
 maint_btrace_clear_cmd (const char *args, int from_tty)
 {
-  struct thread_info *tp;
-
   if (args != NULL && *args != 0)
     error (_("Invalid argument."));
 
-  tp = find_thread_ptid (inferior_ptid);
-  if (tp == NULL)
+  if (inferior_ptid == null_ptid)
     error (_("No thread."));
 
+  thread_info *tp = inferior_thread ();
   btrace_clear (tp);
 }
 
@@ -3420,16 +3414,16 @@ static void
 maint_info_btrace_cmd (const char *args, int from_tty)
 {
   struct btrace_thread_info *btinfo;
-  struct thread_info *tp;
   const struct btrace_config *conf;
 
   if (args != NULL && *args != 0)
     error (_("Invalid argument."));
 
-  tp = find_thread_ptid (inferior_ptid);
-  if (tp == NULL)
+  if (inferior_ptid == null_ptid)
     error (_("No thread."));
 
+  thread_info *tp = inferior_thread ();
+
   btinfo = &tp->btrace;
 
   conf = btrace_conf (btinfo);
diff --git a/gdb/cli/cli-interp.c b/gdb/cli/cli-interp.c
index e12d45b..2aa41d6 100644
--- a/gdb/cli/cli-interp.c
+++ b/gdb/cli/cli-interp.c
@@ -29,6 +29,7 @@
 #include "observable.h"
 #include "gdbthread.h"
 #include "thread-fsm.h"
+#include "inferior.h"
 
 cli_interp_base::cli_interp_base (const char *name)
   : interp (name)
diff --git a/gdb/common/refcounted-object.h b/gdb/common/refcounted-object.h
index e9cdc04..a3799d8 100644
--- a/gdb/common/refcounted-object.h
+++ b/gdb/common/refcounted-object.h
@@ -51,4 +51,20 @@ private:
   int m_refcount = 0;
 };
 
+/* A policy class to interface gdb::ref_ptr with a
+   refcounted_object.  */
+
+struct refcounted_object_ref_policy
+{
+  static void incref (refcounted_object *ptr)
+  {
+    ptr->incref ();
+  }
+
+  static void decref (refcounted_object *ptr)
+  {
+    ptr->decref ();
+  }
+};
+
 #endif /* REFCOUNTED_OBJECT_H */
diff --git a/gdb/compile/compile-object-load.c b/gdb/compile/compile-object-load.c
index fac16d7..9b3c51f 100644
--- a/gdb/compile/compile-object-load.c
+++ b/gdb/compile/compile-object-load.c
@@ -28,6 +28,7 @@
 #include "gdbcmd.h"
 #include "regcache.h"
 #include "inferior.h"
+#include "gdbthread.h"
 #include "compile.h"
 #include "block.h"
 #include "arch-utils.h"
@@ -554,8 +555,9 @@ get_regs_type (struct symbol *func_sym, struct objfile *objfile)
 static void
 store_regs (struct type *regs_type, CORE_ADDR regs_base)
 {
+  thread_info *thread = inferior_thread ();
   struct gdbarch *gdbarch = target_gdbarch ();
-  struct regcache *regcache = get_thread_regcache (inferior_ptid);
+  struct regcache *regcache = get_thread_regcache (thread);
   int fieldno;
 
   for (fieldno = 0; fieldno < TYPE_NFIELDS (regs_type); fieldno++)
diff --git a/gdb/corelow.c b/gdb/corelow.c
index 2ae233e..ed20b53 100644
--- a/gdb/corelow.c
+++ b/gdb/corelow.c
@@ -260,11 +260,9 @@ core_target::close ()
 {
   if (core_bfd)
     {
-      int pid = ptid_get_pid (inferior_ptid);
       inferior_ptid = null_ptid;    /* Avoid confusion from thread
 				       stuff.  */
-      if (pid != 0)
-	exit_inferior_silent (pid);
+      exit_inferior_silent (current_inferior ());
 
       /* Clear out solib state while the bfd is still open.  See
          comments in clear_solib in solib.c.  */
@@ -454,7 +452,7 @@ core_target_open (const char *arg, int from_tty)
 	 which was the "main" thread.  The latter case shouldn't
 	 usually happen, but we're dealing with input here, which can
 	 always be broken in different ways.  */
-      struct thread_info *thread = first_thread_of_process (-1);
+      thread_info *thread = first_thread_of_inferior (current_inferior ());
 
       if (thread == NULL)
 	{
@@ -463,7 +461,7 @@ core_target_open (const char *arg, int from_tty)
 	  add_thread_silent (inferior_ptid);
 	}
       else
-	switch_to_thread (thread->ptid);
+	switch_to_thread (thread);
     }
 
   post_create_inferior (target, from_tty);
diff --git a/gdb/ctf.c b/gdb/ctf.c
index 7e22074..fd987c5 100644
--- a/gdb/ctf.c
+++ b/gdb/ctf.c
@@ -1175,15 +1175,12 @@ ctf_target_open (const char *dirname, int from_tty)
 void
 ctf_target::close ()
 {
-  int pid;
-
   ctf_destroy ();
   xfree (trace_dirname);
   trace_dirname = NULL;
 
-  pid = ptid_get_pid (inferior_ptid);
   inferior_ptid = null_ptid;	/* Avoid confusion from thread stuff.  */
-  exit_inferior_silent (pid);
+  exit_inferior_silent (current_inferior ());
 
   trace_reset_local_state ();
 }
diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c
index 82e7251..c6f874a 100644
--- a/gdb/dummy-frame.c
+++ b/gdb/dummy-frame.c
@@ -37,7 +37,7 @@ struct dummy_frame_id
   struct frame_id id;
 
   /* The thread this dummy_frame relates to.  */
-  ptid_t ptid;
+  thread_info *thread;
 };
 
 /* Return whether dummy_frame_id *ID1 and *ID2 are equal.  */
@@ -46,7 +46,7 @@ static int
 dummy_frame_id_eq (struct dummy_frame_id *id1,
 		   struct dummy_frame_id *id2)
 {
-  return frame_id_eq (id1->id, id2->id) && ptid_equal (id1->ptid, id2->ptid);
+  return frame_id_eq (id1->id, id2->id) && id1->thread == id2->thread;
 }
 
 /* List of dummy_frame destructors.  */
@@ -89,14 +89,14 @@ static struct dummy_frame *dummy_frame_stack = NULL;
 
 void
 dummy_frame_push (struct infcall_suspend_state *caller_state,
-		  const struct frame_id *dummy_id, ptid_t ptid)
+		  const frame_id *dummy_id, thread_info *thread)
 {
   struct dummy_frame *dummy_frame;
 
   dummy_frame = XCNEW (struct dummy_frame);
   dummy_frame->caller_state = caller_state;
   dummy_frame->id.id = (*dummy_id);
-  dummy_frame->id.ptid = ptid;
+  dummy_frame->id.thread = thread;
   dummy_frame->next = dummy_frame_stack;
   dummy_frame_stack = dummy_frame;
 }
@@ -130,7 +130,7 @@ pop_dummy_frame_bpt (struct breakpoint *b, void *dummy_voidp)
 {
   struct dummy_frame *dummy = (struct dummy_frame *) dummy_voidp;
 
-  if (b->thread == ptid_to_global_thread_id (dummy->id.ptid)
+  if (b->thread == dummy->id.thread->global_num
       && b->disposition == disp_del && frame_id_eq (b->frame_id, dummy->id.id))
     {
       while (b->related_breakpoint != b)
@@ -154,7 +154,7 @@ pop_dummy_frame (struct dummy_frame **dummy_ptr)
 {
   struct dummy_frame *dummy = *dummy_ptr;
 
-  gdb_assert (ptid_equal (dummy->id.ptid, inferior_ptid));
+  gdb_assert (dummy->id.thread == inferior_thread ());
 
   while (dummy->dtor_list != NULL)
     {
@@ -196,16 +196,16 @@ lookup_dummy_frame (struct dummy_frame_id *dummy_id)
   return NULL;
 }
 
-/* Find the dummy frame by DUMMY_ID and PTID, and pop it, restoring
+/* Find the dummy frame by DUMMY_ID and THREAD, and pop it, restoring
    program state to that before the frame was created.
    On return reinit_frame_cache has been called.
    If the frame isn't found, flag an internal error.  */
 
 void
-dummy_frame_pop (struct frame_id dummy_id, ptid_t ptid)
+dummy_frame_pop (frame_id dummy_id, thread_info *thread)
 {
   struct dummy_frame **dp;
-  struct dummy_frame_id id = { dummy_id, ptid };
+  struct dummy_frame_id id = { dummy_id, thread };
 
   dp = lookup_dummy_frame (&id);
   gdb_assert (dp != NULL);
@@ -218,10 +218,10 @@ dummy_frame_pop (struct frame_id dummy_id, ptid_t ptid)
    free its memory.  */
 
 void
-dummy_frame_discard (struct frame_id dummy_id, ptid_t ptid)
+dummy_frame_discard (struct frame_id dummy_id, thread_info *thread)
 {
   struct dummy_frame **dp;
-  struct dummy_frame_id id = { dummy_id, ptid };
+  struct dummy_frame_id id = { dummy_id, thread };
 
   dp = lookup_dummy_frame (&id);
   if (dp)
@@ -231,10 +231,10 @@ dummy_frame_discard (struct frame_id dummy_id, ptid_t ptid)
 /* See dummy-frame.h.  */
 
 void
-register_dummy_frame_dtor (struct frame_id dummy_id, ptid_t ptid,
+register_dummy_frame_dtor (frame_id dummy_id, thread_info *thread,
 			   dummy_frame_dtor_ftype *dtor, void *dtor_data)
 {
-  struct dummy_frame_id id = { dummy_id, ptid };
+  struct dummy_frame_id id = { dummy_id, thread };
   struct dummy_frame **dp, *d;
   struct dummy_frame_dtor_list *list;
 
@@ -306,7 +306,7 @@ dummy_frame_sniffer (const struct frame_unwind *self,
 	 dummy ID, assuming it is a dummy frame.  */
       struct frame_id this_id
 	= gdbarch_dummy_id (get_frame_arch (this_frame), this_frame);
-      struct dummy_frame_id dummy_id = { this_id, inferior_ptid };
+      struct dummy_frame_id dummy_id = { this_id, inferior_thread () };
 
       /* Use that ID to find the corresponding cache entry.  */
       for (dummyframe = dummy_frame_stack;
@@ -397,7 +397,7 @@ fprint_dummy_frames (struct ui_file *file)
       fprintf_unfiltered (file, " id=");
       fprint_frame_id (file, s->id.id);
       fprintf_unfiltered (file, ", ptid=%s",
-			  target_pid_to_str (s->id.ptid));
+			  target_pid_to_str (s->id.thread->ptid));
       fprintf_unfiltered (file, "\n");
     }
 }
diff --git a/gdb/dummy-frame.h b/gdb/dummy-frame.h
index cad9960..407f398 100644
--- a/gdb/dummy-frame.h
+++ b/gdb/dummy-frame.h
@@ -33,8 +33,9 @@ struct frame_unwind;
    be expanded so that it knowns the lower/upper extent of the dummy
    frame's code.  */
 
-extern void dummy_frame_push (struct infcall_suspend_state *caller_state,
-                              const struct frame_id *dummy_id, ptid_t ptid);
+extern void dummy_frame_push (infcall_suspend_state *caller_state,
+			      const frame_id *dummy_id,
+			      thread_info *thread);
 
 /* Pop the dummy frame DUMMY_ID, restoring program state to that before the
    frame was created.
@@ -45,9 +46,9 @@ extern void dummy_frame_push (struct infcall_suspend_state *caller_state,
    stack, because the other frames may be for different threads, and there's
    currently no way to tell which stack frame is for which thread.  */
 
-extern void dummy_frame_pop (struct frame_id dummy_id, ptid_t ptid);
+extern void dummy_frame_pop (frame_id dummy_id, thread_info *thread);
 
-extern void dummy_frame_discard (struct frame_id dummy_id, ptid_t ptid);
+extern void dummy_frame_discard (frame_id dummy_id, thread_info *thread);
 
 /* If the PC falls in a dummy frame, return a dummy frame
    unwinder.  */
@@ -58,11 +59,12 @@ extern const struct frame_unwind dummy_frame_unwind;
    REGISTERS_VALID is 1 for dummy_frame_pop, 0 for dummy_frame_discard.  */
 typedef void (dummy_frame_dtor_ftype) (void *data, int registers_valid);
 
-/* Call DTOR with DTOR_DATA when DUMMY_ID frame of thread PTID gets discarded.
-   Dummy frame with DUMMY_ID must exist.  Multiple destructors may be
-   registered, they will be called in the reverse order of registrations
-   (LIFO).  */
-extern void register_dummy_frame_dtor (struct frame_id dummy_id, ptid_t ptid,
+/* Call DTOR with DTOR_DATA when DUMMY_ID frame of thread THREAD gets
+   discarded.  Dummy frame with DUMMY_ID must exist.  Multiple
+   destructors may be registered, they will be called in the reverse
+   order of registrations (LIFO).  */
+extern void register_dummy_frame_dtor (frame_id dummy_id,
+				       thread_info *thread,
 				       dummy_frame_dtor_ftype *dtor,
 				       void *dtor_data);
 
diff --git a/gdb/elfread.c b/gdb/elfread.c
index 0d538e6..e11c051 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -41,6 +41,7 @@
 #include "value.h"
 #include "infcall.h"
 #include "gdbthread.h"
+#include "inferior.h"
 #include "regcache.h"
 #include "bcache.h"
 #include "gdb_bfd.h"
@@ -924,7 +925,7 @@ elf_gnu_ifunc_resolver_stop (struct breakpoint *b)
   struct frame_info *prev_frame = get_prev_frame (get_current_frame ());
   struct frame_id prev_frame_id = get_stack_frame_id (prev_frame);
   CORE_ADDR prev_pc = get_frame_pc (prev_frame);
-  int thread_id = ptid_to_global_thread_id (inferior_ptid);
+  int thread_id = inferior_thread ()->global_num;
 
   gdb_assert (b->type == bp_gnu_ifunc_resolver);
 
@@ -971,10 +972,11 @@ elf_gnu_ifunc_resolver_stop (struct breakpoint *b)
 static void
 elf_gnu_ifunc_resolver_return_stop (struct breakpoint *b)
 {
+  thread_info *thread = inferior_thread ();
   struct gdbarch *gdbarch = get_frame_arch (get_current_frame ());
   struct type *func_func_type = builtin_type (gdbarch)->builtin_func_func;
   struct type *value_type = TYPE_TARGET_TYPE (func_func_type);
-  struct regcache *regcache = get_thread_regcache (inferior_ptid);
+  struct regcache *regcache = get_thread_regcache (thread);
   struct value *func_func;
   struct value *value;
   CORE_ADDR resolved_address, resolved_pc;
diff --git a/gdb/eval.c b/gdb/eval.c
index 667169c..9db6e7c 100644
--- a/gdb/eval.c
+++ b/gdb/eval.c
@@ -74,14 +74,14 @@ evaluate_subexp (struct type *expect_type, struct expression *exp,
   gdb::optional<enable_thread_stack_temporaries> stack_temporaries;
   if (*pos == 0 && target_has_execution
       && exp->language_defn->la_language == language_cplus
-      && !thread_stack_temporaries_enabled_p (inferior_ptid))
-    stack_temporaries.emplace (inferior_ptid);
+      && !thread_stack_temporaries_enabled_p (inferior_thread ()))
+    stack_temporaries.emplace (inferior_thread ());
 
   retval = (*exp->language_defn->la_exp_desc->evaluate_exp)
     (expect_type, exp, pos, noside);
 
   if (stack_temporaries.has_value ()
-      && value_in_thread_stack_temporaries (retval, inferior_ptid))
+      && value_in_thread_stack_temporaries (retval, inferior_thread ()))
     retval = value_non_lval (retval);
 
   return retval;
diff --git a/gdb/fbsd-tdep.c b/gdb/fbsd-tdep.c
index e49a9af..455deb1 100644
--- a/gdb/fbsd-tdep.c
+++ b/gdb/fbsd-tdep.c
@@ -1146,8 +1146,7 @@ fbsd_get_siginfo_type (struct gdbarch *gdbarch)
 /* Implement the "get_syscall_number" gdbarch method.  */
 
 static LONGEST
-fbsd_get_syscall_number (struct gdbarch *gdbarch,
-			 ptid_t ptid)
+fbsd_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread)
 {
 
   /* FreeBSD doesn't use gdbarch_get_syscall_number since FreeBSD
diff --git a/gdb/frame.c b/gdb/frame.c
index 450bf3a..1fe882c 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1050,7 +1050,7 @@ frame_pop (struct frame_info *this_frame)
     {
       /* Popping a dummy frame involves restoring more than just registers.
 	 dummy_frame_pop does all the work.  */
-      dummy_frame_pop (get_frame_id (this_frame), inferior_ptid);
+      dummy_frame_pop (get_frame_id (this_frame), inferior_thread ());
       return;
     }
 
@@ -1622,15 +1622,16 @@ has_stack_frames (void)
   if (get_traceframe_number () < 0)
     {
       /* No current inferior, no frame.  */
-      if (ptid_equal (inferior_ptid, null_ptid))
+      if (inferior_ptid == null_ptid)
 	return 0;
 
+      thread_info *tp = inferior_thread ();
       /* Don't try to read from a dead thread.  */
-      if (is_exited (inferior_ptid))
+      if (tp->state == THREAD_EXITED)
 	return 0;
 
       /* ... or from a spinning thread.  */
-      if (is_executing (inferior_ptid))
+      if (tp->executing)
 	return 0;
     }
 
@@ -2497,7 +2498,7 @@ find_frame_sal (frame_info *frame)
       if (next_frame)
 	sym = get_frame_function (next_frame);
       else
-	sym = inline_skipped_symbol (inferior_ptid);
+	sym = inline_skipped_symbol (inferior_thread ());
 
       /* If frame is inline, it certainly has symbols.  */
       gdb_assert (sym);
diff --git a/gdb/gdb_proc_service.h b/gdb/gdb_proc_service.h
index b5ab0e5..41175a6 100644
--- a/gdb/gdb_proc_service.h
+++ b/gdb/gdb_proc_service.h
@@ -23,6 +23,8 @@
 
 #include "gregset.h"
 
+struct thread_info;
+
 #ifdef HAVE_PROC_SERVICE_H
 
 /* glibc's proc_service.h doesn't wrap itself with extern "C".  Need
@@ -179,7 +181,7 @@ typedef prfpregset_t gdb_prfpregset_t;
 struct ps_prochandle
 {
   /* The LWP we use for memory reads.  */
-  ptid_t ptid;
+  thread_info *thread;
 };
 
 #endif /* gdb_proc_service.h */
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index 558cc55..0c8d8ee 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -4269,13 +4269,13 @@ gdbarch_get_syscall_number_p (struct gdbarch *gdbarch)
 }
 
 LONGEST
-gdbarch_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid)
+gdbarch_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread)
 {
   gdb_assert (gdbarch != NULL);
   gdb_assert (gdbarch->get_syscall_number != NULL);
   if (gdbarch_debug >= 2)
     fprintf_unfiltered (gdb_stdlog, "gdbarch_get_syscall_number called\n");
-  return gdbarch->get_syscall_number (gdbarch, ptid);
+  return gdbarch->get_syscall_number (gdbarch, thread);
 }
 
 void
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 09edcd5..d13672bd 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -1168,8 +1168,8 @@ extern void set_gdbarch_record_special_symbol (struct gdbarch *gdbarch, gdbarch_
 
 extern int gdbarch_get_syscall_number_p (struct gdbarch *gdbarch);
 
-typedef LONGEST (gdbarch_get_syscall_number_ftype) (struct gdbarch *gdbarch, ptid_t ptid);
-extern LONGEST gdbarch_get_syscall_number (struct gdbarch *gdbarch, ptid_t ptid);
+typedef LONGEST (gdbarch_get_syscall_number_ftype) (struct gdbarch *gdbarch, thread_info *thread);
+extern LONGEST gdbarch_get_syscall_number (struct gdbarch *gdbarch, thread_info *thread);
 extern void set_gdbarch_get_syscall_number (struct gdbarch *gdbarch, gdbarch_get_syscall_number_ftype *get_syscall_number);
 
 /* The filename of the XML syscall for this architecture. */
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index 0a23b1e..c85444d 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -904,7 +904,7 @@ M;void;record_special_symbol;struct objfile *objfile, asymbol *sym;objfile, sym
 # Function for the 'catch syscall' feature.
 
 # Get architecture-specific system calls information from registers.
-M;LONGEST;get_syscall_number;ptid_t ptid;ptid
+M;LONGEST;get_syscall_number;thread_info *thread;thread
 
 # The filename of the XML syscall for this architecture.
 v;const char *;xml_syscall_file;;;0;0;;0;pstring (gdbarch->xml_syscall_file)
diff --git a/gdb/gdbthread.h b/gdb/gdbthread.h
index 09ea5ba..bd5ab91 100644
--- a/gdb/gdbthread.h
+++ b/gdb/gdbthread.h
@@ -211,6 +211,9 @@ public:
     return (refcount () == 0 && !ptid_equal (ptid, inferior_ptid));
   }
 
+  /* Mark this thread as running and notify observers.  */
+  void set_running (bool running);
+
   struct thread_info *next = NULL;
   ptid_t ptid;			/* "Actual process id";
 				    In fact, this may be overloaded with 
@@ -367,6 +370,11 @@ public:
   struct thread_info *step_over_next = NULL;
 };
 
+/* A gdb::ref_ptr pointer to a thread_info.  */
+
+using thread_info_ref
+  = gdb::ref_ptr<thread_info, refcounted_object_ref_policy>;
+
 /* Create an empty thread list, or empty the existing one.  */
 extern void init_thread_list (void);
 
@@ -385,12 +393,12 @@ extern struct thread_info *add_thread_with_info (ptid_t ptid,
 						 struct private_thread_info *);
 
 /* Delete an existing thread list entry.  */
-extern void delete_thread (ptid_t);
+extern void delete_thread (thread_info *thread);
 
 /* Delete an existing thread list entry, and be quiet about it.  Used
    after the process this thread having belonged to having already
    exited, for example.  */
-extern void delete_thread_silent (ptid_t);
+extern void delete_thread_silent (thread_info *thread);
 
 /* Delete a step_resume_breakpoint from the thread database.  */
 extern void delete_step_resume_breakpoint (struct thread_info *);
@@ -411,16 +419,6 @@ extern int thread_has_single_step_breakpoint_here (struct thread_info *tp,
 						   const address_space *aspace,
 						   CORE_ADDR addr);
 
-/* Translate the global integer thread id (GDB's homegrown id, not the
-   system's) into a "pid" (which may be overloaded with extra thread
-   information).  */
-extern ptid_t global_thread_id_to_ptid (int num);
-
-/* Translate a 'pid' (which may be overloaded with extra thread
-   information) into the global integer thread id (GDB's homegrown id,
-   not the system's).  */
-extern int ptid_to_global_thread_id (ptid_t ptid);
-
 /* 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.  */
@@ -432,8 +430,7 @@ extern int show_inferior_qualified_tids (void);
    circular static buffer, NUMCELLS deep.  */
 const char *print_thread_id (struct thread_info *thr);
 
-/* Boolean test for an already-known pid (which may be overloaded with
-   extra thread information).  */
+/* Boolean test for an already-known ptid.  */
 extern int in_thread_list (ptid_t ptid);
 
 /* Boolean test for an already-known global thread id (GDB's homegrown
@@ -450,17 +447,16 @@ struct thread_info *find_thread_global_id (int global_id);
 struct thread_info *find_thread_by_handle (struct value *thread_handle,
 					   struct inferior *inf);
 
-/* Finds the first thread of the inferior given by PID.  If PID is -1,
-   returns the first thread in the list.  */
-struct thread_info *first_thread_of_process (int pid);
+/* Finds the first thread of the specified inferior.  */
+extern thread_info *first_thread_of_inferior (inferior *inf);
 
-/* Returns any thread of process PID, giving preference to the current
-   thread.  */
-extern struct thread_info *any_thread_of_process (int pid);
+/* Returns any thread of inferior INF, giving preference to the
+   current thread.  */
+extern thread_info *any_thread_of_inferior (inferior *inf);
 
-/* Returns any non-exited thread of process PID, giving preference to
+/* 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_process (int pid);
+extern thread_info *any_live_thread_of_inferior (inferior *inf);
 
 /* Change the ptid of thread OLD_PTID to NEW_PTID.  */
 void thread_change_ptid (ptid_t old_ptid, ptid_t new_ptid);
@@ -496,6 +492,12 @@ extern struct thread_info *iterate_over_threads (thread_callback_func, void *);
 
 extern int thread_count (void);
 
+/* Switch context to thread THR.  Also sets the STOP_PC global.  */
+extern void switch_to_thread (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 and
    sets STOP_PC to -1.  */
 extern void switch_to_thread_no_regs (struct thread_info *thread);
@@ -549,9 +551,6 @@ extern int is_stopped (ptid_t ptid);
    thread_info.  */
 extern void set_executing (ptid_t ptid, int executing);
 
-/* Reports if thread PTID is executing.  */
-extern int is_executing (ptid_t ptid);
-
 /* True if any (known or unknown) thread is or may be executing.  */
 extern int threads_are_executing (void);
 
@@ -653,48 +652,48 @@ extern void delete_exited_threads (void);
 
 int pc_in_thread_step_range (CORE_ADDR pc, struct thread_info *thread);
 
-/* Enable storing stack temporaries for thread with id PTID and
-   disable and clear the stack temporaries on destruction.  */
+/* 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 (ptid_t ptid)
-    : m_ptid (ptid)
+  explicit enable_thread_stack_temporaries (thread_info *thr)
+    : m_thr (thr)
   {
-    struct thread_info *tp = find_thread_ptid (ptid);
+    gdb_assert (m_thr != NULL);
 
-    gdb_assert (tp != NULL);
-    tp->stack_temporaries_enabled = true;
-    tp->stack_temporaries.clear ();
+    m_thr->incref ();
+
+    m_thr->stack_temporaries_enabled = true;
+    m_thr->stack_temporaries.clear ();
   }
 
   ~enable_thread_stack_temporaries ()
   {
-    struct thread_info *tp = find_thread_ptid (m_ptid);
+    m_thr->stack_temporaries_enabled = false;
+    m_thr->stack_temporaries.clear ();
 
-    if (tp != NULL)
-      {
-	tp->stack_temporaries_enabled = false;
-	tp->stack_temporaries.clear ();
-      }
+    m_thr->decref ();
   }
 
   DISABLE_COPY_AND_ASSIGN (enable_thread_stack_temporaries);
 
 private:
 
-  ptid_t m_ptid;
+  thread_info *m_thr;
 };
 
-extern bool thread_stack_temporaries_enabled_p (ptid_t ptid);
+extern bool thread_stack_temporaries_enabled_p (thread_info *tp);
 
-extern void push_thread_stack_temporary (ptid_t ptid, struct value *v);
+extern void push_thread_stack_temporary (thread_info *tp, struct value *v);
 
-extern struct value *get_last_thread_stack_temporary (ptid_t);
+extern value *get_last_thread_stack_temporary (thread_info *tp);
 
-extern bool value_in_thread_stack_temporaries (struct value *, ptid_t);
+extern bool value_in_thread_stack_temporaries (struct value *,
+					       thread_info *thr);
 
 /* Add TP to the end of its inferior's pending step-over chain.  */
 
@@ -722,9 +721,9 @@ extern void thread_cancel_execution_command (struct thread_info *thr);
    executing).  */
 extern void validate_registers_access (void);
 
-/* Check whether it makes sense to access a register of PTID at this point.
+/* 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_ptid (ptid_t ptid);
+extern bool can_access_registers_thread (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
diff --git a/gdb/i386-linux-tdep.c b/gdb/i386-linux-tdep.c
index 1919c8b..f5b039b 100644
--- a/gdb/i386-linux-tdep.c
+++ b/gdb/i386-linux-tdep.c
@@ -559,9 +559,9 @@ i386_linux_get_syscall_number_from_regcache (struct regcache *regcache)
 
 static LONGEST
 i386_linux_get_syscall_number (struct gdbarch *gdbarch,
-                               ptid_t ptid)
+			       thread_info *thread)
 {
-  struct regcache *regcache = get_thread_regcache (ptid);
+  struct regcache *regcache = get_thread_regcache (thread);
 
   return i386_linux_get_syscall_number_from_regcache (regcache);
 }
diff --git a/gdb/infcall.c b/gdb/infcall.c
index c20ab6f..e1861dc 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -422,7 +422,8 @@ static struct value *
 get_call_return_value (struct call_return_meta_info *ri)
 {
   struct value *retval = NULL;
-  bool stack_temporaries = thread_stack_temporaries_enabled_p (inferior_ptid);
+  thread_info *thr = inferior_thread ();
+  bool stack_temporaries = thread_stack_temporaries_enabled_p (thr);
 
   if (TYPE_CODE (ri->value_type) == TYPE_CODE_VOID)
     retval = allocate_value (ri->value_type);
@@ -432,7 +433,7 @@ get_call_return_value (struct call_return_meta_info *ri)
 	{
 	  retval = value_from_contents_and_address (ri->value_type, NULL,
 						    ri->struct_addr);
-	  push_thread_stack_temporary (inferior_ptid, retval);
+	  push_thread_stack_temporary (thr, retval);
 	}
       else
 	{
@@ -458,7 +459,7 @@ get_call_return_value (struct call_return_meta_info *ri)
 	     the this pointer, GDB needs the memory address of the
 	     value.  */
 	  value_force_lval (retval, ri->struct_addr);
-	  push_thread_stack_temporary (inferior_ptid, retval);
+	  push_thread_stack_temporary (thr, retval);
 	}
     }
 
@@ -586,6 +587,7 @@ run_inferior_call (struct call_thread_fsm *sm,
   struct gdb_exception caught_error = exception_none;
   int saved_in_infcall = call_thread->control.in_infcall;
   ptid_t call_thread_ptid = call_thread->ptid;
+  inferior *call_thread_inf = call_thread->inf;
   enum prompt_state saved_prompt_state = current_ui->prompt_state;
   int was_running = call_thread->state == THREAD_RUNNING;
   int saved_ui_async = current_ui->async;
@@ -637,10 +639,6 @@ run_inferior_call (struct call_thread_fsm *sm,
     ui_register_input_event_handler (current_ui);
   current_ui->async = saved_ui_async;
 
-  /* At this point the current thread may have changed.  Refresh
-     CALL_THREAD as it could be invalid if its thread has exited.  */
-  call_thread = find_thread_ptid (call_thread_ptid);
-
   /* If the infcall does NOT succeed, normal_stop will have already
      finished the thread states.  However, on success, normal_stop
      defers here, so that we can set back the thread states to what
@@ -657,7 +655,7 @@ run_inferior_call (struct call_thread_fsm *sm,
      evaluates true and thus we'll present a user-visible stop is
      decided elsewhere.  */
   if (!was_running
-      && ptid_equal (call_thread_ptid, inferior_ptid)
+      && call_thread_ptid == inferior_ptid
       && stop_stack_dummy == STOP_STACK_DUMMY)
     finish_thread_state (user_visible_resume_ptid (0));
 
@@ -670,12 +668,11 @@ run_inferior_call (struct call_thread_fsm *sm,
      of error out of resume()), then we wouldn't need this.  */
   if (caught_error.reason < 0)
     {
-      if (call_thread != NULL)
+      if (call_thread->state != THREAD_EXITED)
 	breakpoint_auto_delete (call_thread->control.stop_bpstat);
     }
 
-  if (call_thread != NULL)
-    call_thread->control.in_infcall = saved_in_infcall;
+  call_thread->control.in_infcall = saved_in_infcall;
 
   return caught_error;
 }
@@ -739,7 +736,6 @@ call_function_by_hand_dummy (struct value *function,
   ptid_t call_thread_ptid;
   struct gdb_exception e;
   char name_buf[RAW_FUNCTION_ADDRESS_SIZE];
-  bool stack_temporaries = thread_stack_temporaries_enabled_p (inferior_ptid);
 
   if (!target_has_execution)
     noprocess ();
@@ -750,6 +746,14 @@ call_function_by_hand_dummy (struct value *function,
   if (execution_direction == EXEC_REVERSE)
     error (_("Cannot call functions in reverse mode."));
 
+  /* We're going to run the target, and inspect the thread's state
+     afterwards.  Hold a strong reference so that the pointer remains
+     valid even if the thread exits.  */
+  thread_info_ref call_thread
+    = thread_info_ref::new_reference (inferior_thread ());
+
+  bool stack_temporaries = thread_stack_temporaries_enabled_p (call_thread.get ());
+
   frame = get_current_frame ();
   gdbarch = get_frame_arch (frame);
 
@@ -842,7 +846,7 @@ call_function_by_hand_dummy (struct value *function,
       {
 	struct value *lastval;
 
-	lastval = get_last_thread_stack_temporary (inferior_ptid);
+	lastval = get_last_thread_stack_temporary (call_thread.get ());
         if (lastval != NULL)
 	  {
 	    CORE_ADDR lastval_addr = value_address (lastval);
@@ -1137,9 +1141,9 @@ call_function_by_hand_dummy (struct value *function,
   /* Everything's ready, push all the info needed to restore the
      caller (and identify the dummy-frame) onto the dummy-frame
      stack.  */
-  dummy_frame_push (caller_state, &dummy_id, inferior_ptid);
+  dummy_frame_push (caller_state, &dummy_id, call_thread.get ());
   if (dummy_dtor != NULL)
-    register_dummy_frame_dtor (dummy_id, inferior_ptid,
+    register_dummy_frame_dtor (dummy_id, call_thread.get (),
 			       dummy_dtor, dummy_dtor_data);
 
   /* Register a clean-up for unwind_on_terminating_exception_breakpoint.  */
@@ -1150,20 +1154,17 @@ call_function_by_hand_dummy (struct value *function,
      If you're looking to implement asynchronous dummy-frames, then
      just below is the place to chop this function in two..  */
 
-  /* TP is invalid after run_inferior_call returns, so enclose this
-     in a block so that it's only in scope during the time it's valid.  */
   {
-    struct thread_info *tp = inferior_thread ();
     struct thread_fsm *saved_sm;
     struct call_thread_fsm *sm;
 
     /* Save the current FSM.  We'll override it.  */
-    saved_sm = tp->thread_fsm;
-    tp->thread_fsm = NULL;
+    saved_sm = call_thread->thread_fsm;
+    call_thread->thread_fsm = NULL;
 
     /* Save this thread's ptid, we need it later but the thread
        may have exited.  */
-    call_thread_ptid = tp->ptid;
+    call_thread_ptid = call_thread->ptid;
 
     /* Run the inferior until it stops.  */
 
@@ -1177,17 +1178,16 @@ call_function_by_hand_dummy (struct value *function,
 			      struct_return || hidden_first_param_p,
 			      struct_addr);
 
-    e = run_inferior_call (sm, tp, real_pc);
+    e = run_inferior_call (sm, call_thread.get (), real_pc);
 
     gdb::observers::inferior_call_post.notify (call_thread_ptid, funaddr);
 
-    tp = find_thread_ptid (call_thread_ptid);
-    if (tp != NULL)
+    if (call_thread->state != THREAD_EXITED)
       {
 	/* The FSM should still be the same.  */
-	gdb_assert (tp->thread_fsm == &sm->thread_fsm);
+	gdb_assert (call_thread->thread_fsm == &sm->thread_fsm);
 
-	if (thread_fsm_finished_p (tp->thread_fsm))
+	if (thread_fsm_finished_p (call_thread->thread_fsm))
 	  {
 	    struct value *retval;
 
@@ -1195,7 +1195,7 @@ call_function_by_hand_dummy (struct value *function,
 	       which runs its destructors and restores the inferior's
 	       suspend state, and restore the inferior control
 	       state.  */
-	    dummy_frame_pop (dummy_id, call_thread_ptid);
+	    dummy_frame_pop (dummy_id, call_thread.get ());
 	    restore_infcall_control_state (inf_status);
 
 	    /* Get the return value.  */
@@ -1203,9 +1203,9 @@ call_function_by_hand_dummy (struct value *function,
 
 	    /* Clean up / destroy the call FSM, and restore the
 	       original one.  */
-	    thread_fsm_clean_up (tp->thread_fsm, tp);
-	    thread_fsm_delete (tp->thread_fsm);
-	    tp->thread_fsm = saved_sm;
+	    thread_fsm_clean_up (call_thread->thread_fsm, call_thread.get ());
+	    thread_fsm_delete (call_thread->thread_fsm);
+	    call_thread->thread_fsm = saved_sm;
 
 	    maybe_remove_breakpoints ();
 
@@ -1216,7 +1216,7 @@ call_function_by_hand_dummy (struct value *function,
 
 	/* Didn't complete.  Restore previous state machine, and
 	   handle the error.  */
-	tp->thread_fsm = saved_sm;
+	call_thread->thread_fsm = saved_sm;
       }
   }
 
@@ -1317,7 +1317,7 @@ When the function is done executing, GDB will silently stop."),
 
 	      /* We must get back to the frame we were before the
 		 dummy call.  */
-	      dummy_frame_pop (dummy_id, call_thread_ptid);
+	      dummy_frame_pop (dummy_id, call_thread.get ());
 
 	      /* We also need to restore inferior status to that before the
 		 dummy call.  */
@@ -1358,7 +1358,7 @@ When the function is done executing, GDB will silently stop."),
 	{
 	  /* We must get back to the frame we were before the dummy
 	     call.  */
-	  dummy_frame_pop (dummy_id, call_thread_ptid);
+	  dummy_frame_pop (dummy_id, call_thread.get ());
 
 	  /* We also need to restore inferior status to that before
 	     the dummy call.  */
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 5c5faf7..c6fd9ab 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -723,10 +723,10 @@ proceed_thread_callback (struct thread_info *thread, void *arg)
      much.  If/when GDB gains a way to tell the target `hold this
      thread stopped until I say otherwise', then we can optimize
      this.  */
-  if (!is_stopped (thread->ptid))
+  if (thread->state != THREAD_STOPPED)
     return 0;
 
-  switch_to_thread (thread->ptid);
+  switch_to_thread (thread);
   clear_proceed_status (0);
   proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
   return 0;
@@ -735,8 +735,8 @@ proceed_thread_callback (struct thread_info *thread, void *arg)
 static void
 ensure_valid_thread (void)
 {
-  if (ptid_equal (inferior_ptid, null_ptid)
-      || is_exited (inferior_ptid))
+  if (inferior_ptid == null_ptid
+      || inferior_thread ()->state == THREAD_EXITED)
     error (_("Cannot execute this command without a live selected thread."));
 }
 
@@ -765,7 +765,7 @@ error_is_running (void)
 static void
 ensure_not_running (void)
 {
-  if (is_running (inferior_ptid))
+  if (inferior_thread ()->state == THREAD_RUNNING)
     error_is_running ();
 }
 
@@ -855,7 +855,7 @@ continue_command (const char *args, int from_tty)
       struct thread_info *tp;
 
       if (non_stop)
-	tp = find_thread_ptid (inferior_ptid);
+	tp = inferior_thread ();
       else
 	{
 	  ptid_t last_ptid;
@@ -1148,7 +1148,7 @@ prepare_one_step (struct step_command_fsm *sm)
 
 	  /* Step at an inlined function behaves like "down".  */
 	  if (!sm->skip_subroutines
-	      && inline_skipped_frames (inferior_ptid))
+	      && inline_skipped_frames (tp))
 	    {
 	      ptid_t resume_ptid;
 
@@ -1156,7 +1156,7 @@ prepare_one_step (struct step_command_fsm *sm)
 	      resume_ptid = user_visible_resume_ptid (1);
 	      set_running (resume_ptid, 1);
 
-	      step_into_inline_frame (inferior_ptid);
+	      step_into_inline_frame (tp);
 	      sm->count--;
 	      return prepare_one_step (sm);
 	    }
@@ -2076,7 +2076,6 @@ info_program_command (const char *args, int from_tty)
 {
   bpstat bs;
   int num, stat;
-  struct thread_info *tp;
   ptid_t ptid;
 
   if (!target_has_execution)
@@ -2094,12 +2093,16 @@ info_program_command (const char *args, int from_tty)
       get_last_target_status (&ptid, &ws);
     }
 
-  if (ptid_equal (ptid, null_ptid) || is_exited (ptid))
+  if (ptid == null_ptid)
+    error (_("No selected thread."));
+
+  thread_info *tp = find_thread_ptid (ptid);
+
+  if (tp->state == THREAD_EXITED)
     error (_("Invalid selected thread."));
-  else if (is_running (ptid))
+  else if (tp->state == THREAD_RUNNING)
     error (_("Selected thread is running."));
 
-  tp = find_thread_ptid (ptid);
   bs = tp->control.stop_bpstat;
   stat = bpstat_num (&bs, &num);
 
@@ -2638,12 +2641,12 @@ proceed_after_attach_callback (struct thread_info *thread,
   int pid = * (int *) arg;
 
   if (ptid_get_pid (thread->ptid) == pid
-      && !is_exited (thread->ptid)
-      && !is_executing (thread->ptid)
+      && thread->state != THREAD_EXITED
+      && !thread->executing
       && !thread->stop_requested
       && thread->suspend.stop_signal == GDB_SIGNAL_0)
     {
-      switch_to_thread (thread->ptid);
+      switch_to_thread (thread);
       clear_proceed_status (0);
       proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
     }
@@ -2773,7 +2776,7 @@ attach_post_wait (const char *args, int from_tty, enum attach_post_wait_mode mod
 		}
 	    }
 
-	  switch_to_thread (lowest->ptid);
+	  switch_to_thread (lowest);
 	}
 
       /* Tell the user/frontend where we're stopped.  */
@@ -2939,7 +2942,7 @@ attach_command (const char *args, int from_tty)
    as stopped.  */
 
 void
-notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
+notice_new_inferior (thread_info *thr, int leave_running, int from_tty)
 {
   enum attach_post_wait_mode mode
     = leave_running ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_NOTHING;
@@ -2951,12 +2954,12 @@ notice_new_inferior (ptid_t ptid, int leave_running, int from_tty)
 
   /* Avoid reading registers -- we haven't fetched the target
      description yet.  */
-  switch_to_thread_no_regs (find_thread_ptid (ptid));
+  switch_to_thread_no_regs (thr);
 
   /* When we "notice" a new inferior we need to do all the things we
      would normally do if we had just attached to it.  */
 
-  if (is_executing (inferior_ptid))
+  if (thr->executing)
     {
       struct attach_command_continuation_args *a;
       struct inferior *inferior = current_inferior ();
diff --git a/gdb/inferior.c b/gdb/inferior.c
index ec2f985..ab506f6 100644
--- a/gdb/inferior.c
+++ b/gdb/inferior.c
@@ -144,9 +144,9 @@ delete_thread_of_inferior (struct thread_info *tp, void *data)
   if (ptid_get_pid (tp->ptid) == arg->pid)
     {
       if (arg->silent)
-	delete_thread_silent (tp->ptid);
+	delete_thread_silent (tp);
       else
-	delete_thread (tp->ptid);
+	delete_thread (tp);
     }
 
   return 0;
@@ -230,10 +230,9 @@ exit_inferior_1 (struct inferior *inftoex, int silent)
 }
 
 void
-exit_inferior (int pid)
+exit_inferior (inferior *inf)
 {
-  struct inferior *inf = find_inferior_pid (pid);
-
+  int pid = inf->pid;
   exit_inferior_1 (inf, 0);
 }
 
@@ -246,6 +245,12 @@ exit_inferior_silent (int pid)
 }
 
 void
+exit_inferior_silent (inferior *inf)
+{
+  exit_inferior_1 (inf, 1);
+}
+
+void
 exit_inferior_num_silent (int num)
 {
   struct inferior *inf = find_inferior_id (num);
@@ -269,14 +274,6 @@ detach_inferior (inferior *inf)
 		       target_pid_to_str (pid_to_ptid (pid)));
 }
 
-/* See inferior.h.  */
-
-void
-detach_inferior (int pid)
-{
-  detach_inferior (find_inferior_pid (pid));
-}
-
 void
 inferior_appeared (struct inferior *inf, int pid)
 {
@@ -295,7 +292,7 @@ discard_all_inferiors (void)
   for (inf = inferior_list; inf; inf = inf->next)
     {
       if (inf->pid != 0)
-	exit_inferior_silent (inf->pid);
+	exit_inferior_silent (inf);
     }
 }
 
@@ -372,52 +369,6 @@ iterate_over_inferiors (int (*callback) (struct inferior *, void *),
 }
 
 int
-valid_gdb_inferior_id (int num)
-{
-  struct inferior *inf;
-
-  for (inf = inferior_list; inf; inf = inf->next)
-    if (inf->num == num)
-      return 1;
-
-  return 0;
-}
-
-int
-pid_to_gdb_inferior_id (int pid)
-{
-  struct inferior *inf;
-
-  for (inf = inferior_list; inf; inf = inf->next)
-    if (inf->pid == pid)
-      return inf->num;
-
-  return 0;
-}
-
-int
-gdb_inferior_id_to_pid (int num)
-{
-  struct inferior *inferior = find_inferior_id (num);
-  if (inferior)
-    return inferior->pid;
-  else
-    return -1;
-}
-
-int
-in_inferior_list (int pid)
-{
-  struct inferior *inf;
-
-  for (inf = inferior_list; inf; inf = inf->next)
-    if (inf->pid == pid)
-      return 1;
-
-  return 0;
-}
-
-int
 have_inferiors (void)
 {
   struct inferior *inf;
@@ -611,8 +562,6 @@ print_inferior (struct ui_out *uiout, const char *requested_inferiors)
 static void
 detach_inferior_command (const char *args, int from_tty)
 {
-  struct thread_info *tp;
-
   if (!args || !*args)
     error (_("Requires argument (inferior id(s) to detach)"));
 
@@ -621,27 +570,27 @@ detach_inferior_command (const char *args, int from_tty)
     {
       int num = parser.get_number ();
 
-      if (!valid_gdb_inferior_id (num))
+      inferior *inf = find_inferior_id (num);
+      if (inf == NULL)
 	{
 	  warning (_("Inferior ID %d not known."), num);
 	  continue;
 	}
 
-      int pid = gdb_inferior_id_to_pid (num);
-      if (pid == 0)
+      if (inf->pid == 0)
 	{
 	  warning (_("Inferior ID %d is not running."), num);
 	  continue;
 	}
 
-      tp = any_thread_of_process (pid);
-      if (!tp)
+      thread_info *tp = any_thread_of_inferior (inf);
+      if (tp == NULL)
 	{
 	  warning (_("Inferior ID %d has no threads."), num);
 	  continue;
 	}
 
-      switch_to_thread (tp->ptid);
+      switch_to_thread (tp);
 
       detach_command (NULL, from_tty);
     }
@@ -650,8 +599,6 @@ detach_inferior_command (const char *args, int from_tty)
 static void
 kill_inferior_command (const char *args, int from_tty)
 {
-  struct thread_info *tp;
-
   if (!args || !*args)
     error (_("Requires argument (inferior id(s) to kill)"));
 
@@ -660,27 +607,27 @@ kill_inferior_command (const char *args, int from_tty)
     {
       int num = parser.get_number ();
 
-      if (!valid_gdb_inferior_id (num))
+      inferior *inf = find_inferior_id (num);
+      if (inf == NULL)
 	{
 	  warning (_("Inferior ID %d not known."), num);
 	  continue;
 	}
 
-      int pid = gdb_inferior_id_to_pid (num);
-      if (pid == 0)
+      if (inf->pid == 0)
 	{
 	  warning (_("Inferior ID %d is not running."), num);
 	  continue;
 	}
 
-      tp = any_thread_of_process (pid);
-      if (!tp)
+      thread_info *tp = any_thread_of_inferior (inf);
+      if (tp == NULL)
 	{
 	  warning (_("Inferior ID %d has no threads."), num);
 	  continue;
 	}
 
-      switch_to_thread (tp->ptid);
+      switch_to_thread (tp);
 
       target_kill ();
     }
@@ -702,15 +649,13 @@ inferior_command (const char *args, int from_tty)
 
   if (inf->pid != 0)
     {
-      if (inf->pid != ptid_get_pid (inferior_ptid))
+      if (inf != current_inferior ())
 	{
-	  struct thread_info *tp;
-
-	  tp = any_thread_of_process (inf->pid);
-	  if (!tp)
+	  thread_info *tp = any_thread_of_inferior (inf);
+	  if (tp == NULL)
 	    error (_("Inferior has no threads."));
 
-	  switch_to_thread (tp->ptid);
+	  switch_to_thread (tp);
 	}
 
       gdb::observers::user_selected_context_changed.notify
@@ -721,7 +666,7 @@ inferior_command (const char *args, int from_tty)
   else
     {
       set_current_inferior (inf);
-      switch_to_thread (null_ptid);
+      switch_to_no_thread ();
       set_current_program_space (inf->pspace);
 
       gdb::observers::user_selected_context_changed.notify
@@ -855,7 +800,7 @@ add_inferior_command (const char *args, int from_tty)
 	     symbols.q.  */
 	  set_current_program_space (inf->pspace);
 	  set_current_inferior (inf);
-	  switch_to_thread (null_ptid);
+	  switch_to_no_thread ();
 
 	  exec_file_attach (exec.get (), from_tty);
 	  symbol_file_add_main (exec.get (), add_flags);
@@ -943,7 +888,7 @@ clone_inferior_command (const char *args, int from_tty)
       printf_filtered (_("Added inferior %d.\n"), inf->num);
 
       set_current_inferior (inf);
-      switch_to_thread (null_ptid);
+      switch_to_no_thread ();
       clone_program_space (pspace, orginf->pspace);
     }
 }
diff --git a/gdb/inferior.h b/gdb/inferior.h
index bd26c8a..3f4d7a5 100644
--- a/gdb/inferior.h
+++ b/gdb/inferior.h
@@ -32,6 +32,7 @@ struct terminal_info;
 struct target_desc_info;
 struct continuation;
 struct inferior;
+struct thread_info;
 
 /* For bpstat.  */
 #include "breakpoint.h"
@@ -176,7 +177,7 @@ extern void delete_longjmp_breakpoint_cleanup (void *arg);
 
 extern void detach_command (const char *, int);
 
-extern void notice_new_inferior (ptid_t, int, int);
+extern void notice_new_inferior (thread_info *, int, int);
 
 extern struct value *get_return_value (struct value *function,
 				       struct type *value_type);
@@ -474,12 +475,9 @@ extern void delete_inferior (struct inferior *todel);
 /* Delete an existing inferior list entry, due to inferior detaching.  */
 extern void detach_inferior (inferior *inf);
 
-/* Same as the above, but with the inferior specified by PID.  */
-extern void detach_inferior (int pid);
+extern void exit_inferior (inferior *inf);
 
-extern void exit_inferior (int pid);
-
-extern void exit_inferior_silent (int pid);
+extern void exit_inferior_silent (inferior *inf);
 
 extern void exit_inferior_num_silent (int num);
 
@@ -488,21 +486,6 @@ extern void inferior_appeared (struct inferior *inf, int pid);
 /* Get rid of all inferiors.  */
 extern void discard_all_inferiors (void);
 
-/* Translate the integer inferior id (GDB's homegrown id, not the system's)
-   into a "pid" (which may be overloaded with extra inferior information).  */
-extern int gdb_inferior_id_to_pid (int);
-
-/* Translate a target 'pid' into the integer inferior id (GDB's
-   homegrown id, not the system's).  */
-extern int pid_to_gdb_inferior_id (int pid);
-
-/* Boolean test for an already-known pid.  */
-extern int in_inferior_list (int pid);
-
-/* Boolean test for an already-known inferior id (GDB's homegrown id,
-   not the system's).  */
-extern int valid_gdb_inferior_id (int num);
-
 /* Search function to lookup an inferior by target 'pid'.  */
 extern struct inferior *find_inferior_pid (int pid);
 
diff --git a/gdb/infrun.c b/gdb/infrun.c
index f455af2..9548f9c 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -383,8 +383,6 @@ static int stop_print_frame;
 static ptid_t target_last_wait_ptid;
 static struct target_waitstatus target_last_waitstatus;
 
-static void context_switch (ptid_t ptid);
-
 void init_thread_stepping_state (struct thread_info *tss);
 
 static const char follow_fork_mode_child[] = "child";
@@ -458,7 +456,7 @@ holding the child stopped.  Try \"set detach-on-fork\" or \
 	  if (has_vforked)
 	    {
 	      /* Keep breakpoints list in sync.  */
-	      remove_breakpoints_pid (ptid_get_pid (inferior_ptid));
+	      remove_breakpoints_inf (current_inferior ());
 	    }
 
 	  if (print_inferior_events)
@@ -689,14 +687,16 @@ follow_fork (void)
 
       /* Check if we switched over from WAIT_PTID, since the event was
 	 reported.  */
-      if (!ptid_equal (wait_ptid, minus_one_ptid)
-	  && !ptid_equal (inferior_ptid, wait_ptid))
+      if (wait_ptid != minus_one_ptid
+	  && inferior_ptid != wait_ptid)
 	{
 	  /* We did.  Switch back to WAIT_PTID thread, to tell the
 	     target to follow it (in either direction).  We'll
 	     afterwards refuse to resume, and inform the user what
 	     happened.  */
-	  switch_to_thread (wait_ptid);
+	  thread_info *wait_thread
+	    = find_thread_ptid (wait_ptid);
+	  switch_to_thread (wait_thread);
 	  should_resume = 0;
 	}
     }
@@ -767,7 +767,8 @@ follow_fork (void)
 	    /* If we followed the child, switch to it...  */
 	    if (follow_child)
 	      {
-		switch_to_thread (child);
+		thread_info *child_thr = find_thread_ptid (child);
+		switch_to_thread (child_thr);
 
 		/* ... and preserve the stepping state, in case the
 		   user was stepping over the fork call.  */
@@ -798,8 +799,6 @@ follow_fork (void)
 		/* Reset breakpoints in the child as appropriate.  */
 		follow_inferior_reset_breakpoints ();
 	      }
-	    else
-	      switch_to_thread (parent);
 	  }
       }
       break;
@@ -865,9 +864,9 @@ proceed_after_vfork_done (struct thread_info *thread,
 {
   int pid = * (int *) arg;
 
-  if (ptid_get_pid (thread->ptid) == pid
-      && is_running (thread->ptid)
-      && !is_executing (thread->ptid)
+  if (thread->ptid.pid () == pid
+      && thread->state == THREAD_RUNNING
+      && !thread->executing
       && !thread->stop_requested
       && thread->suspend.stop_signal == GDB_SIGNAL_0)
     {
@@ -876,7 +875,7 @@ proceed_after_vfork_done (struct thread_info *thread,
 			    "infrun: resuming vfork parent thread %s\n",
 			    target_pid_to_str (thread->ptid));
 
-      switch_to_thread (thread->ptid);
+      switch_to_thread (thread);
       clear_proceed_status (0);
       proceed ((CORE_ADDR) -1, GDB_SIGNAL_DEFAULT);
     }
@@ -939,8 +938,8 @@ handle_vfork_child_exec_or_exit (int exec)
 	    maybe_restore_thread.emplace ();
 
 	  /* We're letting loose of the parent.  */
-	  tp = any_live_thread_of_process (inf->vfork_parent->pid);
-	  switch_to_thread (tp->ptid);
+	  tp = any_live_thread_of_inferior (inf->vfork_parent);
+	  switch_to_thread (tp);
 
 	  /* We're about to detach from the parent, which implicitly
 	     removes breakpoints from its address space.  There's a
@@ -1130,7 +1129,7 @@ follow_exec (ptid_t ptid, char *exec_file_target)
      notifications.  */
   ALL_THREADS_SAFE (th, tmp)
     if (ptid_get_pid (th->ptid) == pid && !ptid_equal (th->ptid, ptid))
-      delete_thread (th->ptid);
+      delete_thread (th);
 
   /* We also need to clear any left over stale state for the
      leader/event thread.  E.g., if there was any step-resume
@@ -1485,16 +1484,16 @@ struct displaced_step_inferior_state
   struct displaced_step_inferior_state *next;
 
   /* The process this displaced step state refers to.  */
-  int pid;
+  inferior *inf;
 
   /* True if preparing a displaced step ever failed.  If so, we won't
      try displaced stepping for this inferior again.  */
   int failed_before;
 
-  /* If this is not null_ptid, this is the thread carrying out a
+  /* If this is not nullptr, this is the thread carrying out a
      displaced single-step in process PID.  This thread's state will
      require fixing up once it has completed its step.  */
-  ptid_t step_ptid;
+  thread_info *step_thread;
 
   /* The architecture the thread had when we stepped it.  */
   struct gdbarch *step_gdbarch;
@@ -1518,14 +1517,14 @@ static struct displaced_step_inferior_state *displaced_step_inferior_states;
 /* Get the displaced stepping state of process PID.  */
 
 static struct displaced_step_inferior_state *
-get_displaced_stepping_state (int pid)
+get_displaced_stepping_state (inferior *inf)
 {
   struct displaced_step_inferior_state *state;
 
   for (state = displaced_step_inferior_states;
        state != NULL;
        state = state->next)
-    if (state->pid == pid)
+    if (state->inf == inf)
       return state;
 
   return NULL;
@@ -1542,7 +1541,7 @@ displaced_step_in_progress_any_inferior (void)
   for (state = displaced_step_inferior_states;
        state != NULL;
        state = state->next)
-    if (!ptid_equal (state->step_ptid, null_ptid))
+    if (state->step_thread != nullptr)
       return 1;
 
   return 0;
@@ -1552,26 +1551,26 @@ displaced_step_in_progress_any_inferior (void)
    step.  */
 
 static int
-displaced_step_in_progress_thread (ptid_t ptid)
+displaced_step_in_progress_thread (thread_info *thread)
 {
   struct displaced_step_inferior_state *displaced;
 
-  gdb_assert (!ptid_equal (ptid, null_ptid));
+  gdb_assert (thread != NULL);
 
-  displaced = get_displaced_stepping_state (ptid_get_pid (ptid));
+  displaced = get_displaced_stepping_state (thread->inf);
 
-  return (displaced != NULL && ptid_equal (displaced->step_ptid, ptid));
+  return (displaced != NULL && displaced->step_thread == thread);
 }
 
 /* Return true if process PID has a thread doing a displaced step.  */
 
 static int
-displaced_step_in_progress (int pid)
+displaced_step_in_progress (inferior *inf)
 {
   struct displaced_step_inferior_state *displaced;
 
-  displaced = get_displaced_stepping_state (pid);
-  if (displaced != NULL && !ptid_equal (displaced->step_ptid, null_ptid))
+  displaced = get_displaced_stepping_state (inf);
+  if (displaced != NULL && displaced->step_thread != nullptr)
     return 1;
 
   return 0;
@@ -1582,18 +1581,18 @@ displaced_step_in_progress (int pid)
    entry, if it already exists.  Never returns NULL.  */
 
 static struct displaced_step_inferior_state *
-add_displaced_stepping_state (int pid)
+add_displaced_stepping_state (inferior *inf)
 {
   struct displaced_step_inferior_state *state;
 
   for (state = displaced_step_inferior_states;
        state != NULL;
        state = state->next)
-    if (state->pid == pid)
+    if (state->inf == inf)
       return state;
 
   state = XCNEW (struct displaced_step_inferior_state);
-  state->pid = pid;
+  state->inf = inf;
   state->next = displaced_step_inferior_states;
   displaced_step_inferior_states = state;
 
@@ -1608,11 +1607,12 @@ struct displaced_step_closure*
 get_displaced_step_closure_by_addr (CORE_ADDR addr)
 {
   struct displaced_step_inferior_state *displaced
-    = get_displaced_stepping_state (ptid_get_pid (inferior_ptid));
+    = get_displaced_stepping_state (current_inferior ());
 
   /* If checking the mode of displaced instruction in copy area.  */
-  if (displaced && !ptid_equal (displaced->step_ptid, null_ptid)
-     && (displaced->step_copy == addr))
+  if (displaced != NULL
+      && displaced->step_thread != nullptr
+      && displaced->step_copy == addr)
     return displaced->step_closure;
 
   return NULL;
@@ -1621,17 +1621,17 @@ get_displaced_step_closure_by_addr (CORE_ADDR addr)
 /* Remove the displaced stepping state of process PID.  */
 
 static void
-remove_displaced_stepping_state (int pid)
+remove_displaced_stepping_state (inferior *inf)
 {
   struct displaced_step_inferior_state *it, **prev_next_p;
 
-  gdb_assert (pid != 0);
+  gdb_assert (inf != nullptr);
 
   it = displaced_step_inferior_states;
   prev_next_p = &displaced_step_inferior_states;
   while (it)
     {
-      if (it->pid == pid)
+      if (it->inf == inf)
 	{
 	  *prev_next_p = it->next;
 	  xfree (it);
@@ -1646,7 +1646,7 @@ remove_displaced_stepping_state (int pid)
 static void
 infrun_inferior_exit (struct inferior *inf)
 {
-  remove_displaced_stepping_state (inf->pid);
+  remove_displaced_stepping_state (inf);
 }
 
 /* If ON, and the architecture supports it, GDB will use displaced
@@ -1681,11 +1681,11 @@ show_can_use_displaced_stepping (struct ui_file *file, int from_tty,
 static int
 use_displaced_stepping (struct thread_info *tp)
 {
-  struct regcache *regcache = get_thread_regcache (tp->ptid);
+  struct regcache *regcache = get_thread_regcache (tp);
   struct gdbarch *gdbarch = regcache->arch ();
   struct displaced_step_inferior_state *displaced_state;
 
-  displaced_state = get_displaced_stepping_state (ptid_get_pid (tp->ptid));
+  displaced_state = get_displaced_stepping_state (tp->inf);
 
   return (((can_use_displaced_stepping == AUTO_BOOLEAN_AUTO
 	    && target_is_non_stop_p ())
@@ -1701,7 +1701,7 @@ static void
 displaced_step_clear (struct displaced_step_inferior_state *displaced)
 {
   /* Indicate that there is no cleanup pending.  */
-  displaced->step_ptid = null_ptid;
+  displaced->step_thread = nullptr;
 
   delete displaced->step_closure;
   displaced->step_closure = NULL;
@@ -1746,11 +1746,10 @@ displaced_step_dump_bytes (struct ui_file *file,
    if this instruction can't be displaced stepped.  */
 
 static int
-displaced_step_prepare_throw (ptid_t ptid)
+displaced_step_prepare_throw (thread_info *tp)
 {
   struct cleanup *ignore_cleanups;
-  struct thread_info *tp = find_thread_ptid (ptid);
-  struct regcache *regcache = get_thread_regcache (ptid);
+  regcache *regcache = get_thread_regcache (tp);
   struct gdbarch *gdbarch = regcache->arch ();
   const address_space *aspace = regcache->aspace ();
   CORE_ADDR original, copy;
@@ -1775,9 +1774,9 @@ displaced_step_prepare_throw (ptid_t ptid)
   /* We have to displaced step one thread at a time, as we only have
      access to a single scratch space per inferior.  */
 
-  displaced = add_displaced_stepping_state (ptid_get_pid (ptid));
+  displaced = add_displaced_stepping_state (tp->inf);
 
-  if (!ptid_equal (displaced->step_ptid, null_ptid))
+  if (displaced->step_thread != nullptr)
     {
       /* Already waiting for a displaced step to finish.  Defer this
 	 request and place in queue.  */
@@ -1785,7 +1784,7 @@ displaced_step_prepare_throw (ptid_t ptid)
       if (debug_displaced)
 	fprintf_unfiltered (gdb_stdlog,
 			    "displaced: deferring step of %s\n",
-			    target_pid_to_str (ptid));
+			    target_pid_to_str (tp->ptid));
 
       thread_step_over_chain_enqueue (tp);
       return 0;
@@ -1795,13 +1794,14 @@ displaced_step_prepare_throw (ptid_t ptid)
       if (debug_displaced)
 	fprintf_unfiltered (gdb_stdlog,
 			    "displaced: stepping %s now\n",
-			    target_pid_to_str (ptid));
+			    target_pid_to_str (tp->ptid));
     }
 
   displaced_step_clear (displaced);
 
-  scoped_restore save_inferior_ptid = make_scoped_restore (&inferior_ptid);
-  inferior_ptid = ptid;
+  scoped_restore_current_thread restore_thread;
+
+  switch_to_thread (tp);
 
   original = regcache_read_pc (regcache);
 
@@ -1861,7 +1861,7 @@ displaced_step_prepare_throw (ptid_t ptid)
 
   /* Save the information we need to fix things up if the step
      succeeds.  */
-  displaced->step_ptid = ptid;
+  displaced->step_thread = tp;
   displaced->step_gdbarch = gdbarch;
   displaced->step_closure = closure;
   displaced->step_original = original;
@@ -1885,13 +1885,13 @@ displaced_step_prepare_throw (ptid_t ptid)
    attempts at displaced stepping if we get a memory error.  */
 
 static int
-displaced_step_prepare (ptid_t ptid)
+displaced_step_prepare (thread_info *thread)
 {
   int prepared = -1;
 
   TRY
     {
-      prepared = displaced_step_prepare_throw (ptid);
+      prepared = displaced_step_prepare_throw (thread);
     }
   CATCH (ex, RETURN_MASK_ERROR)
     {
@@ -1918,7 +1918,7 @@ displaced_step_prepare (ptid_t ptid)
 
       /* Disable further displaced stepping attempts.  */
       displaced_state
-	= get_displaced_stepping_state (ptid_get_pid (ptid));
+	= get_displaced_stepping_state (thread->inf);
       displaced_state->failed_before = 1;
     }
   END_CATCH
@@ -1960,30 +1960,29 @@ displaced_step_restore (struct displaced_step_inferior_state *displaced,
    -1.  If the thread wasn't displaced stepping, return 0.  */
 
 static int
-displaced_step_fixup (ptid_t event_ptid, enum gdb_signal signal)
+displaced_step_fixup (thread_info *event_thread, enum gdb_signal signal)
 {
   struct cleanup *old_cleanups;
   struct displaced_step_inferior_state *displaced
-    = get_displaced_stepping_state (ptid_get_pid (event_ptid));
+    = get_displaced_stepping_state (event_thread->inf);
   int ret;
 
   /* Was any thread of this process doing a displaced step?  */
   if (displaced == NULL)
     return 0;
 
-  /* Was this event for the pid we displaced?  */
-  if (ptid_equal (displaced->step_ptid, null_ptid)
-      || ! ptid_equal (displaced->step_ptid, event_ptid))
+  /* Was this event for the thread we displaced?  */
+  if (displaced->step_thread != event_thread)
     return 0;
 
   old_cleanups = make_cleanup (displaced_step_clear_cleanup, displaced);
 
-  displaced_step_restore (displaced, displaced->step_ptid);
+  displaced_step_restore (displaced, displaced->step_thread->ptid);
 
   /* Fixup may need to read memory/registers.  Switch to the thread
      that we're fixing up.  Also, target_stopped_by_watchpoint checks
      the current thread.  */
-  switch_to_thread (event_ptid);
+  switch_to_thread (event_thread);
 
   /* Did the instruction complete successfully?  */
   if (signal == GDB_SIGNAL_TRAP
@@ -1996,14 +1995,14 @@ displaced_step_fixup (ptid_t event_ptid, enum gdb_signal signal)
                                     displaced->step_closure,
                                     displaced->step_original,
                                     displaced->step_copy,
-                                    get_thread_regcache (displaced->step_ptid));
+                                    get_thread_regcache (displaced->step_thread));
       ret = 1;
     }
   else
     {
       /* Since the instruction didn't complete, all we can do is
          relocate the PC.  */
-      struct regcache *regcache = get_thread_regcache (event_ptid);
+      struct regcache *regcache = get_thread_regcache (event_thread);
       CORE_ADDR pc = regcache_read_pc (regcache);
 
       pc = displaced->step_original + (pc - displaced->step_copy);
@@ -2013,7 +2012,7 @@ displaced_step_fixup (ptid_t event_ptid, enum gdb_signal signal)
 
   do_cleanups (old_cleanups);
 
-  displaced->step_ptid = null_ptid;
+  displaced->step_thread = nullptr;
 
   return ret;
 }
@@ -2082,7 +2081,7 @@ start_step_over (void)
 
       /* If this inferior already has a displaced step in process,
 	 don't start a new one.  */
-      if (displaced_step_in_progress (ptid_get_pid (tp->ptid)))
+      if (displaced_step_in_progress (tp->inf))
 	continue;
 
       step_what = thread_still_needs_step_over (tp);
@@ -2132,7 +2131,7 @@ start_step_over (void)
       if (!target_is_non_stop_p () && !step_what)
 	continue;
 
-      switch_to_thread (tp->ptid);
+      switch_to_thread (tp);
       reset_ecs (ecs, tp);
       keep_going_pass_signal (ecs);
 
@@ -2179,14 +2178,6 @@ infrun_thread_ptid_changed (ptid_t old_ptid, ptid_t new_ptid)
 
   if (ptid_equal (inferior_ptid, old_ptid))
     inferior_ptid = new_ptid;
-
-  for (displaced = displaced_step_inferior_states;
-       displaced;
-       displaced = displaced->next)
-    {
-      if (ptid_equal (displaced->step_ptid, old_ptid))
-	displaced->step_ptid = new_ptid;
-    }
 }
 
 
@@ -2344,7 +2335,7 @@ do_target_resume (ptid_t resume_ptid, int step, enum gdb_signal sig)
        return to the scratch pad area, which would no longer be
        valid.  */
   if (step_over_info_valid_p ()
-      || displaced_step_in_progress (ptid_get_pid (tp->ptid)))
+      || displaced_step_in_progress (tp->inf))
     target_pass_signals (0, NULL);
   else
     target_pass_signals ((int) GDB_SIGNAL_LAST, signal_pass);
@@ -2549,7 +2540,7 @@ resume_1 (enum gdb_signal sig)
       && sig == GDB_SIGNAL_0
       && !current_inferior ()->waiting_for_vfork_done)
     {
-      int prepared = displaced_step_prepare (inferior_ptid);
+      int prepared = displaced_step_prepare (tp);
 
       if (prepared == 0)
 	{
@@ -2580,9 +2571,9 @@ resume_1 (enum gdb_signal sig)
 
 	  /* Update pc to reflect the new address from which we will
 	     execute instructions due to displaced stepping.  */
-	  pc = regcache_read_pc (get_thread_regcache (inferior_ptid));
+	  pc = regcache_read_pc (get_thread_regcache (tp));
 
-	  displaced = get_displaced_stepping_state (ptid_get_pid (inferior_ptid));
+	  displaced = get_displaced_stepping_state (tp->inf);
 	  step = gdbarch_displaced_step_hw_singlestep (gdbarch,
 						       displaced->step_closure);
 	}
@@ -2711,7 +2702,7 @@ resume_1 (enum gdb_signal sig)
       && use_displaced_stepping (tp)
       && !step_over_info_valid_p ())
     {
-      struct regcache *resume_regcache = get_thread_regcache (tp->ptid);
+      struct regcache *resume_regcache = get_thread_regcache (tp);
       struct gdbarch *resume_gdbarch = resume_regcache->arch ();
       CORE_ADDR actual_pc = regcache_read_pc (resume_regcache);
       gdb_byte buf[4];
@@ -2919,7 +2910,7 @@ thread_still_needs_step_over_bp (struct thread_info *tp)
 {
   if (tp->stepping_over_breakpoint)
     {
-      struct regcache *regcache = get_thread_regcache (tp->ptid);
+      struct regcache *regcache = get_thread_regcache (tp);
 
       if (breakpoint_here_p (regcache->aspace (),
 			     regcache_read_pc (regcache))
@@ -3186,7 +3177,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
 				target_pid_to_str (tp->ptid));
 
 	  reset_ecs (ecs, tp);
-	  switch_to_thread (tp->ptid);
+	  switch_to_thread (tp);
 	  keep_going_pass_signal (ecs);
 	  if (!ecs->wait_some_more)
 	    error (_("Command aborted."));
@@ -3196,7 +3187,7 @@ proceed (CORE_ADDR addr, enum gdb_signal siggnal)
       {
 	/* The thread wasn't started, and isn't queued, run it now.  */
 	reset_ecs (ecs, tp);
-	switch_to_thread (tp->ptid);
+	switch_to_thread (tp);
 	keep_going_pass_signal (ecs);
 	if (!ecs->wait_some_more)
 	  error (_("Command aborted."));
@@ -3524,7 +3515,7 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
       && (tp->suspend.stop_reason == TARGET_STOPPED_BY_SW_BREAKPOINT
 	  || tp->suspend.stop_reason == TARGET_STOPPED_BY_HW_BREAKPOINT))
     {
-      struct regcache *regcache = get_thread_regcache (tp->ptid);
+      struct regcache *regcache = get_thread_regcache (tp);
       struct gdbarch *gdbarch = regcache->arch ();
       CORE_ADDR pc;
       int discard = 0;
@@ -3587,7 +3578,7 @@ do_target_wait (ptid_t ptid, struct target_waitstatus *status, int options)
 	  struct gdbarch *gdbarch;
 	  int decr_pc;
 
-	  regcache = get_thread_regcache (tp->ptid);
+	  regcache = get_thread_regcache (tp);
 	  gdbarch = regcache->arch ();
 
 	  decr_pc = gdbarch_decr_pc_after_break (gdbarch);
@@ -3631,13 +3622,12 @@ prepare_for_detach (void)
 {
   struct inferior *inf = current_inferior ();
   ptid_t pid_ptid = pid_to_ptid (inf->pid);
-  struct displaced_step_inferior_state *displaced;
 
-  displaced = get_displaced_stepping_state (inf->pid);
+  displaced_step_inferior_state *displaced = get_displaced_stepping_state (inf);
 
   /* Is any thread of this process displaced stepping?  If not,
      there's nothing else to do.  */
-  if (displaced == NULL || ptid_equal (displaced->step_ptid, null_ptid))
+[...]

[diff truncated at 100000 bytes]


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]