Patchwork [3/3] gdbserver: use std::list for all_threads

login
register
mail settings
Submitter Simon Marchi
Date Oct. 9, 2017, 2:30 p.m.
Message ID <20171009143036.10215-4-simon.marchi@polymtl.ca>
Download mbox | patch
Permalink /patch/23411/
State New
Headers show

Comments

Simon Marchi - Oct. 9, 2017, 2:30 p.m.
Remove the usage of inferior_list for the all_threads list in
gdbserver.  The entry field in thread_info is removed, and replaced by a
simple ptid field.

I added some functions to iterate (for_each_thread) and find threads
(find_thread).  However, changing all the users of find_inferior & co to
use these new functions would have made the patch way too big.  So I
opted instead to make find_inferior & co some shims, so that the
existing code only needs to be updated minimally.  We can then update
the existing code to use the new functions incrementally (I've started
to do the work, but I'll post it afterwards, see [1] if you want a peek).

This patch has been built-tested on all relevant platforms, except
lynx.  I also regtested using the native-gdbserver and
native-extended-gdbserver boards on x86.

[1] https://github.com/simark/binutils-gdb/commits/kill-inferior-list-entry

gdb/gdbserver/ChangeLog:

	* inferiors.h: (struct inferior_list): Remove.
	(struct inferior_list_entry); Remove.
	(add_inferior_to_list, clear_inferior_list, one_inferior_p,
	A_I_NEXT, ALL_INFERIORS_TYPE, ALL_INFERIORS, remove_inferior,
	get_first_inferior): Remove.
	(for_each_inferior, for_each_inferior_with_data, find_inferior,
	find_inferior_id, find_inferior_in_random): Change signature.
	* inferiors.c (all_threads): Change type to
	std::list<thread_info *>.
	(get_thread): Remove macro.
	(find_inferior, find_inferior_id): Change signature, implement
	using find_thread.
	(find_inferior_in_random): Change signature, implement using
	find_thread_in_random.
	(for_each_inferior, for_each_inferior_with_data): Change
	signature, implement using for_each_thread.
	(add_inferior_to_list, remove_inferior): Remove.
	(add_thread, get_first_thread, thread_of_pid,
	find_any_thread_of_pid, free_one_thread, remove_thread): Update.
	(get_first_inferior, one_inferior_p, clear_inferior_list):
	Remove.
	(clear_inferiors, get_thread_process): Update.
	* gdbthread.h: Include <list>.
	(struct thread_info) <entry>: Remove field.
	<id>: New field.
	(all_threads): Change type to std::list<thread_info *>.
	(get_first_inferior): Add doc.
	(find_thread, for_each_thread, find_thread_in_random): New
	functions.
	(current_ptid, pid_of, ptid_of, lwpid_of): Update.
	* linux-arm-low.c (update_registers_callback): Update.
	* linux-low.c (second_thread_of_pid_p): Update.
	(kill_one_lwp_callback, linux_detach_lwp_callback,
	delete_lwp_callback, status_pending_p_callback, same_lwp,
	find_lwp_pid, num_lwps, iterate_over_lwps_filter,
	iterate_over_lwps, not_stopped_callback,
	resume_stopped_resumed_lwps, count_events_callback,
	select_singlestep_lwp_callback, select_event_lwp_callback,
	unsuspend_one_lwp, linux_wait_1, send_sigstop_callback,
	suspend_and_send_sigstop_callback, wait_for_sigstop,
	stuck_in_jump_pad_callback, move_out_of_jump_pad_callback,
	lwp_running, linux_set_resume_request, resume_status_pending_p,
	need_step_over_p, start_step_over, linux_resume_one_thread,
	proceed_one_lwp, unsuspend_and_proceed_one_lwp,
	reset_lwp_ptrace_options_callback): Update.
	* linux-mips-low.c (update_watch_registers_callback): Update.
	* regcache.c (regcache_invalidate_one, regcache_invalidate):
	Update.
	(free_register_cache_thread_one): Remove.
	(regcache_release): Update.
	* server.c (handle_btrace_enable_bts, handle_btrace_enable_pt,
	handle_qxfer_threads_worker): Update.
	(handle_query): Update, use list iterator.
	(visit_actioned_threads, handle_pending_status,
	queue_stop_reply_callback, gdb_wants_all_threads_stopped,
	clear_pending_status_callback, set_pending_status_callback,
	find_status_pending_thread_callback, handle_status,
	process_serial_event): Update.
	* target.c (thread_search_callback): Update.
	* thread-db.c (thread_db_get_tls_address): Update.
	* tracepoint.c (tracepoint_finished_step, tracepoint_was_hit):
	Update.
	* win32-i386-low.c (update_debug_registers_callback): Update.
	* win32-low.c (delete_thread_info, child_delete_thread,
	continue_one_thread, suspend_one_thread,
	get_child_debug_event): Adjust.
---
 gdb/gdbserver/gdbthread.h      |  91 +++++++++++++--
 gdb/gdbserver/inferiors.c      | 244 ++++++++++-------------------------------
 gdb/gdbserver/inferiors.h      |  74 +++----------
 gdb/gdbserver/linux-arm-low.c  |   3 +-
 gdb/gdbserver/linux-low.c      | 172 ++++++++++++-----------------
 gdb/gdbserver/linux-mips-low.c |   4 +-
 gdb/gdbserver/lynx-low.c       |  10 +-
 gdb/gdbserver/regcache.c       |  18 +--
 gdb/gdbserver/server.c         |  75 ++++++-------
 gdb/gdbserver/target.c         |   7 +-
 gdb/gdbserver/thread-db.c      |   4 +-
 gdb/gdbserver/tracepoint.c     |   8 +-
 gdb/gdbserver/win32-i386-low.c |   4 +-
 gdb/gdbserver/win32-low.c      |  16 +--
 14 files changed, 276 insertions(+), 454 deletions(-)

Patch

diff --git a/gdb/gdbserver/gdbthread.h b/gdb/gdbserver/gdbthread.h
index 93688a36e4..8ace051036 100644
--- a/gdb/gdbserver/gdbthread.h
+++ b/gdb/gdbserver/gdbthread.h
@@ -22,14 +22,15 @@ 
 #include "common-gdbthread.h"
 #include "inferiors.h"
 
+#include <list>
+
 struct btrace_target_info;
 struct regcache;
 
 struct thread_info
 {
-  /* This must appear first.  See inferiors.h.
-     The list iterator functions assume it.  */
-  struct inferior_list_entry entry;
+  /* The id of this thread.  */
+  ptid_t id;
 
   void *target_data;
   struct regcache *regcache_data;
@@ -72,11 +73,13 @@  struct thread_info
   struct btrace_target_info *btrace;
 };
 
-extern struct inferior_list all_threads;
+extern std::list<thread_info *> all_threads;
 
 void remove_thread (struct thread_info *thread);
 struct thread_info *add_thread (ptid_t ptid, void *target_data);
 
+/* Return a pointer to the first thread, or NULL if there isn't one.  */
+
 struct thread_info *get_first_thread (void);
 
 struct thread_info *find_thread_ptid (ptid_t ptid);
@@ -85,15 +88,87 @@  struct thread_info *find_thread_ptid (ptid_t ptid);
    found.  */
 struct thread_info *find_any_thread_of_pid (int pid);
 
+/* Find the first thread for which FUNC returns true.  Return NULL if no thread
+   satisfying FUNC is found.  */
+
+template <typename Func>
+static thread_info *
+find_thread (Func func)
+{
+  std::list<thread_info *>::iterator next, cur = all_threads.begin ();
+
+  while (cur != all_threads.end ())
+    {
+      next = cur;
+      next++;
+
+      if (func (*cur))
+	return *cur;
+
+      cur = next;
+    }
+
+  return NULL;
+}
+
+/* Invoke FUNC for each thread.  */
+
+template <typename Func>
+static void
+for_each_thread (Func func)
+{
+  std::list<thread_info *>::iterator next, cur = all_threads.begin ();
+
+  while (cur != all_threads.end ())
+    {
+      next = cur;
+      next++;
+      func (*cur);
+      cur = next;
+    }
+}
+
+/* Find the a random thread for which FUNC (THREAD) returns true.  If
+   no entry is found then return NULL.  */
+
+template <typename Func>
+static thread_info *
+find_thread_in_random (Func func)
+{
+  int count = 0;
+  int random_selector;
+
+  /* First count how many interesting entries we have.  */
+  for_each_thread ([&] (thread_info *thread) {
+    if (func (thread))
+      count++;
+  });
+
+  if (count == 0)
+    return NULL;
+
+  /* Now randomly pick an entry out of those.  */
+  random_selector = (int)
+    ((count * (double) rand ()) / (RAND_MAX + 1.0));
+
+  thread_info *thread = find_thread ([&] (thread_info *thread) {
+    return func (thread) && (random_selector-- == 0);
+  });
+
+  gdb_assert (thread != NULL);
+
+  return thread;
+}
+
 /* Get current thread ID (Linux task ID).  */
-#define current_ptid (current_thread->entry.id)
+#define current_ptid (current_thread->id)
 
 /* Get the ptid of THREAD.  */
 
 static inline ptid_t
 ptid_of (const thread_info *thread)
 {
-  return thread->entry.id;
+  return thread->id;
 }
 
 /* Get the pid of THREAD.  */
@@ -101,7 +176,7 @@  ptid_of (const thread_info *thread)
 static inline int
 pid_of (const thread_info *thread)
 {
-  return thread->entry.id.pid ();
+  return thread->id.pid ();
 }
 
 /* Get the lwp of THREAD.  */
@@ -109,7 +184,7 @@  pid_of (const thread_info *thread)
 static inline long
 lwpid_of (const thread_info *thread)
 {
-  return thread->entry.id.lwp ();
+  return thread->id.lwp ();
 }
 
 /* Create a cleanup to restore current_thread.  */
diff --git a/gdb/gdbserver/inferiors.c b/gdb/gdbserver/inferiors.c
index 13ee8c97eb..564121fdd9 100644
--- a/gdb/gdbserver/inferiors.c
+++ b/gdb/gdbserver/inferiors.c
@@ -23,86 +23,68 @@ 
 #include "dll.h"
 
 std::list<process_info *> all_processes;
-struct inferior_list all_threads;
+std::list<thread_info *> all_threads;
 
 struct thread_info *current_thread;
 
-#define get_thread(inf) ((struct thread_info *)(inf))
-
 /* The current working directory used to start the inferior.  */
 static const char *current_inferior_cwd = NULL;
 
-void
-add_inferior_to_list (struct inferior_list *list,
-		      struct inferior_list_entry *new_inferior)
+thread_info *
+find_inferior (std::list<thread_info *> *thread_list,
+	       int (*func) (thread_info *, void *),
+	       void *arg)
 {
-  new_inferior->next = NULL;
-  if (list->tail != NULL)
-    list->tail->next = new_inferior;
-  else
-    list->head = new_inferior;
-  list->tail = new_inferior;
-}
+  gdb_assert (thread_list == &all_threads);
 
-/* Invoke ACTION for each inferior in LIST.  */
+  return find_thread ([&] (thread_info *thread) {
+    return func (thread, arg);
+  });
+}
 
-void
-for_each_inferior (struct inferior_list *list,
-		   void (*action) (struct inferior_list_entry *))
+thread_info *
+find_inferior_id (std::list<thread_info *> *thread_list, ptid_t id)
 {
-  struct inferior_list_entry *cur = list->head, *next;
-
-  while (cur != NULL)
-    {
-      next = cur->next;
-      (*action) (cur);
-      cur = next;
-    }
-}
+  gdb_assert (thread_list == &all_threads);
 
-/* Invoke ACTION for each inferior in LIST, passing DATA to ACTION.  */
+  return find_thread ([&] (thread_info *thread) {
+    return thread->id == id;
+  });
+}
 
-void
-for_each_inferior_with_data (struct inferior_list *list,
-			     void (*action) (struct inferior_list_entry *,
-					     void *),
-			     void *data)
+thread_info *
+find_inferior_in_random (std::list<thread_info *> *thread_list,
+			 int (*func) (thread_info *, void *),
+			 void *arg)
 {
-  struct inferior_list_entry *cur = list->head, *next;
-
-  while (cur != NULL)
-    {
-      next = cur->next;
-      (*action) (cur, data);
-      cur = next;
-    }
+  gdb_assert (thread_list == &all_threads);
+
+  return find_thread_in_random ([&] (thread_info *thread) {
+    return func (thread, arg);
+  });
 }
 
 void
-remove_inferior (struct inferior_list *list,
-		 struct inferior_list_entry *entry)
+for_each_inferior (std::list<thread_info *> *thread_list,
+		   void (*action) (thread_info *))
 {
-  struct inferior_list_entry **cur;
-
-  if (list->head == entry)
-    {
-      list->head = entry->next;
-      if (list->tail == entry)
-	list->tail = list->head;
-      return;
-    }
+  gdb_assert (thread_list == &all_threads);
 
-  cur = &list->head;
-  while (*cur && (*cur)->next != entry)
-    cur = &(*cur)->next;
-
-  if (*cur == NULL)
-    return;
+  for_each_thread ([&] (thread_info *thread) {
+    action (thread);
+  });
+}
 
-  (*cur)->next = entry->next;
+void
+for_each_inferior_with_data (std::list<thread_info *> *thread_list,
+			     void (*action) (thread_info *, void *),
+			     void *data)
+{
+  gdb_assert (thread_list == &all_threads);
 
-  if (list->tail == entry)
-    list->tail = *cur;
+  for_each_thread ([&] (thread_info *thread) {
+    action (thread, data);
+  });
 }
 
 struct thread_info *
@@ -110,11 +92,11 @@  add_thread (ptid_t thread_id, void *target_data)
 {
   struct thread_info *new_thread = XCNEW (struct thread_info);
 
-  new_thread->entry.id = thread_id;
+  new_thread->id = thread_id;
   new_thread->last_resume_kind = resume_continue;
   new_thread->last_status.kind = TARGET_WAITKIND_IGNORE;
 
-  add_inferior_to_list (&all_threads, &new_thread->entry);
+  all_threads.push_back (new_thread);
 
   if (current_thread == NULL)
     current_thread = new_thread;
@@ -124,12 +106,15 @@  add_thread (ptid_t thread_id, void *target_data)
   return new_thread;
 }
 
-/* Wrapper around get_first_inferior to return a struct thread_info *.  */
+/* See gdbthread.h.  */
 
 struct thread_info *
 get_first_thread (void)
 {
-  return (struct thread_info *) get_first_inferior (&all_threads);
+  if (!all_threads.empty ())
+    return all_threads.front ();
+  else
+    return NULL;
 }
 
 struct thread_info *
@@ -151,7 +136,7 @@  find_thread_process (const struct process_info *const process)
    matches a PID.  */
 
 static int
-thread_of_pid (struct inferior_list_entry *entry, void *pid_p)
+thread_of_pid (thread_info *entry, void *pid_p)
 {
   int pid = *(int *) pid_p;
 
@@ -163,17 +148,12 @@  thread_of_pid (struct inferior_list_entry *entry, void *pid_p)
 struct thread_info *
 find_any_thread_of_pid (int pid)
 {
-  struct inferior_list_entry *entry;
-
-  entry = find_inferior (&all_threads, thread_of_pid, &pid);
-
-  return (struct thread_info *) entry;
+  return find_inferior (&all_threads, thread_of_pid, &pid);
 }
 
 static void
-free_one_thread (struct inferior_list_entry *inf)
+free_one_thread (thread_info *thread)
 {
-  struct thread_info *thread = get_thread (inf);
   free_register_cache (thread_regcache_data (thread));
   free (thread);
 }
@@ -185,106 +165,12 @@  remove_thread (struct thread_info *thread)
     target_disable_btrace (thread->btrace);
 
   discard_queued_stop_replies (ptid_of (thread));
-  remove_inferior (&all_threads, (struct inferior_list_entry *) thread);
-  free_one_thread (&thread->entry);
+  all_threads.remove (thread);
+  free_one_thread (thread);
   if (current_thread == thread)
     current_thread = NULL;
 }
 
-/* Return a pointer to the first inferior in LIST, or NULL if there isn't one.
-   This is for cases where the caller needs a thread, but doesn't care
-   which one.  */
-
-struct inferior_list_entry *
-get_first_inferior (struct inferior_list *list)
-{
-  if (list->head != NULL)
-    return list->head;
-  return NULL;
-}
-
-/* Find the first inferior_list_entry E in LIST for which FUNC (E, ARG)
-   returns non-zero.  If no entry is found then return NULL.  */
-
-struct inferior_list_entry *
-find_inferior (struct inferior_list *list,
-	       int (*func) (struct inferior_list_entry *, void *), void *arg)
-{
-  struct inferior_list_entry *inf = list->head;
-
-  while (inf != NULL)
-    {
-      struct inferior_list_entry *next;
-
-      next = inf->next;
-      if ((*func) (inf, arg))
-	return inf;
-      inf = next;
-    }
-
-  return NULL;
-}
-
-/* Find the random inferior_list_entry E in LIST for which FUNC (E, ARG)
-   returns non-zero.  If no entry is found then return NULL.  */
-
-struct inferior_list_entry *
-find_inferior_in_random (struct inferior_list *list,
-			 int (*func) (struct inferior_list_entry *, void *),
-			 void *arg)
-{
-  struct inferior_list_entry *inf = list->head;
-  int count = 0;
-  int random_selector;
-
-  /* First count how many interesting entries we have.  */
-  while (inf != NULL)
-    {
-      struct inferior_list_entry *next;
-
-      next = inf->next;
-      if ((*func) (inf, arg))
-	count++;
-      inf = next;
-    }
-
-  if (count == 0)
-    return NULL;
-
-  /* Now randomly pick an entry out of those.  */
-  random_selector = (int)
-    ((count * (double) rand ()) / (RAND_MAX + 1.0));
-
-  inf = list->head;
-  while (inf != NULL)
-    {
-      struct inferior_list_entry *next;
-
-      next = inf->next;
-      if ((*func) (inf, arg) && (random_selector-- == 0))
-	return inf;
-      inf = next;
-    }
-
-  gdb_assert_not_reached ("failed to find an inferior in random.");
-  return NULL;
-}
-
-struct inferior_list_entry *
-find_inferior_id (struct inferior_list *list, ptid_t id)
-{
-  struct inferior_list_entry *inf = list->head;
-
-  while (inf != NULL)
-    {
-      if (ptid_equal (inf->id, id))
-	return inf;
-      inf = inf->next;
-    }
-
-  return NULL;
-}
-
 void *
 thread_target_data (struct thread_info *thread)
 {
@@ -303,28 +189,11 @@  set_thread_regcache_data (struct thread_info *thread, struct regcache *data)
   thread->regcache_data = data;
 }
 
-/* Return true if LIST has exactly one entry.  */
-
-int
-one_inferior_p (struct inferior_list *list)
-{
-  return list->head != NULL && list->head == list->tail;
-}
-
-/* Reset head,tail of LIST, assuming all entries have already been freed.  */
-
-void
-clear_inferior_list (struct inferior_list *list)
-{
-  list->head = NULL;
-  list->tail = NULL;
-}
-
 void
 clear_inferiors (void)
 {
   for_each_inferior (&all_threads, free_one_thread);
-  clear_inferior_list (&all_threads);
+  all_threads.clear ();
 
   clear_dlls ();
 
@@ -402,8 +271,7 @@  have_attached_inferiors_p (void)
 struct process_info *
 get_thread_process (const struct thread_info *thread)
 {
-  int pid = ptid_get_pid (thread->entry.id);
-  return find_process_pid (pid);
+  return find_process_pid (thread->id.pid ());
 }
 
 struct process_info *
diff --git a/gdb/gdbserver/inferiors.h b/gdb/gdbserver/inferiors.h
index 674b8c6dcb..fb0e2fda81 100644
--- a/gdb/gdbserver/inferiors.h
+++ b/gdb/gdbserver/inferiors.h
@@ -22,19 +22,6 @@ 
 #include "gdb_vecs.h"
 #include <list>
 
-/* Generic information for tracking a list of ``inferiors'' - threads,
-   processes, etc.  */
-struct inferior_list
-{
-  struct inferior_list_entry *head;
-  struct inferior_list_entry *tail;
-};
-struct inferior_list_entry
-{
-  ptid_t id;
-  struct inferior_list_entry *next;
-};
-
 struct thread_info;
 struct regcache;
 struct target_desc;
@@ -96,38 +83,6 @@  struct process_info *get_thread_process (const struct thread_info *);
 
 extern std::list<process_info *> all_processes;
 
-void add_inferior_to_list (struct inferior_list *list,
-			   struct inferior_list_entry *new_inferior);
-void for_each_inferior (struct inferior_list *list,
-			void (*action) (struct inferior_list_entry *));
-
-void for_each_inferior_with_data
-  (struct inferior_list *list,
-   void (*action) (struct inferior_list_entry *, void *),
-   void *data);
-
-void clear_inferior_list (struct inferior_list *list);
-
-int one_inferior_p (struct inferior_list *list);
-
-/* Helper for ALL_INFERIORS_TYPE.  Gets the next element starting at
-   CUR, if CUR is not NULL.  */
-#define A_I_NEXT(type, list, cur)					\
-  ((cur) != NULL							\
-   ? (type *) ((struct inferior_list_entry *) cur)->next		\
-   : NULL)
-
-/* Iterate over all inferiors of type TYPE in LIST, open loop
-   style.  */
-#define ALL_INFERIORS_TYPE(type, list, cur, tmp)				\
-  for ((cur) = (type *) (list)->head, (tmp) = A_I_NEXT (type, list, cur); \
-       (cur) != NULL;							\
-       (cur) = (tmp), (tmp) = A_I_NEXT (type, list, cur))
-
-/* Iterate over all inferiors in LIST, open loop style.  */
-#define ALL_INFERIORS(list, cur, tmp)				\
-  ALL_INFERIORS_TYPE (struct inferior_list_entry, list, cur, tmp)
-
 /* Invoke FUNC for each process.  */
 
 template <typename Func>
@@ -169,10 +124,6 @@  find_process (Func func)
 }
 
 extern struct thread_info *current_thread;
-void remove_inferior (struct inferior_list *list,
-		      struct inferior_list_entry *entry);
-
-struct inferior_list_entry *get_first_inferior (struct inferior_list *list);
 
 /* Return the first process in the processes list.  */
 struct process_info *get_first_process (void);
@@ -184,18 +135,19 @@  int have_started_inferiors_p (void);
 int have_attached_inferiors_p (void);
 
 void clear_inferiors (void);
-struct inferior_list_entry *find_inferior
-     (struct inferior_list *,
-      int (*func) (struct inferior_list_entry *,
-		   void *),
-      void *arg);
-struct inferior_list_entry *find_inferior_id (struct inferior_list *list,
-					      ptid_t id);
-struct inferior_list_entry *
-  find_inferior_in_random (struct inferior_list *,
-			   int (*func) (struct inferior_list_entry *,
-					void *),
-			   void *arg);
+
+thread_info *find_inferior (std::list<thread_info *> *thread_list,
+			    int (*func) (thread_info *, void *), void *arg);
+thread_info *find_inferior_id (std::list<thread_info *> *thread_list,
+			       ptid_t id);
+thread_info *find_inferior_in_random (std::list<thread_info *> *thread_list,
+				      int (*func) (thread_info *, void *),
+				      void *arg);
+void for_each_inferior (std::list<thread_info *> *thread_list,
+			void (*action) (thread_info *));
+void for_each_inferior_with_data (std::list<thread_info *> *thread_list,
+				  void (*action) (thread_info *, void *),
+				  void *data);
 
 void *thread_target_data (struct thread_info *);
 struct regcache *thread_regcache_data (struct thread_info *);
diff --git a/gdb/gdbserver/linux-arm-low.c b/gdb/gdbserver/linux-arm-low.c
index cb59c2a130..c60661dc33 100644
--- a/gdb/gdbserver/linux-arm-low.c
+++ b/gdb/gdbserver/linux-arm-low.c
@@ -467,9 +467,8 @@  struct update_registers_data
 };
 
 static int
-update_registers_callback (struct inferior_list_entry *entry, void *arg)
+update_registers_callback (thread_info *thread, void *arg)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
   struct update_registers_data *data = (struct update_registers_data *) arg;
 
diff --git a/gdb/gdbserver/linux-low.c b/gdb/gdbserver/linux-low.c
index dc0ad85734..58dcec1cb9 100644
--- a/gdb/gdbserver/linux-low.c
+++ b/gdb/gdbserver/linux-low.c
@@ -279,7 +279,7 @@  static void enqueue_pending_signal (struct lwp_info *lwp, int signal, siginfo_t
 static void complete_ongoing_step_over (void);
 static int linux_low_ptrace_options (int attached);
 static int check_ptrace_stopped_lwp_gone (struct lwp_info *lp);
-static int proceed_one_lwp (struct inferior_list_entry *entry, void *except);
+static int proceed_one_lwp (thread_info *thread, void *except);
 
 /* When the event-loop is doing a step-over, this points at the thread
    being stepped.  */
@@ -1243,11 +1243,11 @@  struct counter
 };
 
 static int
-second_thread_of_pid_p (struct inferior_list_entry *entry, void *args)
+second_thread_of_pid_p (thread_info *thread, void *args)
 {
   struct counter *counter = (struct counter *) args;
 
-  if (ptid_get_pid (entry->id) == counter->pid)
+  if (thread->id.pid () == counter->pid)
     {
       if (++counter->count > 1)
 	return 1;
@@ -1356,13 +1356,12 @@  kill_wait_lwp (struct lwp_info *lwp)
    except the leader.  */
 
 static int
-kill_one_lwp_callback (struct inferior_list_entry *entry, void *args)
+kill_one_lwp_callback (thread_info *thread, void *args)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
   int pid = * (int *) args;
 
-  if (ptid_get_pid (entry->id) != pid)
+  if (thread->id.pid () != pid)
     return 0;
 
   /* We avoid killing the first thread here, because of a Linux kernel (at
@@ -1374,7 +1373,7 @@  kill_one_lwp_callback (struct inferior_list_entry *entry, void *args)
     {
       if (debug_threads)
 	debug_printf ("lkop: is last of process %s\n",
-		      target_pid_to_str (entry->id));
+		      target_pid_to_str (thread->id));
       return 0;
     }
 
@@ -1589,21 +1588,20 @@  linux_detach_one_lwp (struct lwp_info *lwp)
    given process.  */
 
 static int
-linux_detach_lwp_callback (struct inferior_list_entry *entry, void *args)
+linux_detach_lwp_callback (thread_info *thread, void *args)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
   int pid = *(int *) args;
   int lwpid = lwpid_of (thread);
 
   /* Skip other processes.  */
-  if (ptid_get_pid (entry->id) != pid)
+  if (thread->id.pid () != pid)
     return 0;
 
   /* We don't actually detach from the thread group leader just yet.
      If the thread group exits, we must reap the zombie clone lwps
      before we're able to reap the leader.  */
-  if (ptid_get_pid (entry->id) == lwpid)
+  if (thread->id.pid () == lwpid)
     return 0;
 
   linux_detach_one_lwp (lwp);
@@ -1657,9 +1655,8 @@  linux_detach (int pid)
 /* Remove all LWPs that belong to process PROC from the lwp list.  */
 
 static int
-delete_lwp_callback (struct inferior_list_entry *entry, void *proc)
+delete_lwp_callback (thread_info *thread, void *proc)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
   struct process_info *process = (struct process_info *) proc;
 
@@ -1806,9 +1803,8 @@  lwp_resumed (struct lwp_info *lwp)
 
 /* Return 1 if this lwp has an interesting status pending.  */
 static int
-status_pending_p_callback (struct inferior_list_entry *entry, void *arg)
+status_pending_p_callback (thread_info *thread, void *arg)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lp = get_thread_lwp (thread);
   ptid_t ptid = * (ptid_t *) arg;
 
@@ -1831,7 +1827,7 @@  status_pending_p_callback (struct inferior_list_entry *entry, void *arg)
 }
 
 static int
-same_lwp (struct inferior_list_entry *entry, void *data)
+same_lwp (thread_info *thread, void *data)
 {
   ptid_t ptid = *(ptid_t *) data;
   int lwp;
@@ -1841,7 +1837,7 @@  same_lwp (struct inferior_list_entry *entry, void *data)
   else
     lwp = ptid_get_pid (ptid);
 
-  if (ptid_get_lwp (entry->id) == lwp)
+  if (thread->id.lwp () == lwp)
     return 1;
 
   return 0;
@@ -1850,13 +1846,12 @@  same_lwp (struct inferior_list_entry *entry, void *data)
 struct lwp_info *
 find_lwp_pid (ptid_t ptid)
 {
-  struct inferior_list_entry *thread
-    = find_inferior (&all_threads, same_lwp, &ptid);
+  thread_info *thread = find_inferior (&all_threads, same_lwp, &ptid);
 
   if (thread == NULL)
     return NULL;
 
-  return get_thread_lwp ((struct thread_info *) thread);
+  return get_thread_lwp (thread);
 }
 
 /* Return the number of known LWPs in the tgid given by PID.  */
@@ -1864,14 +1859,12 @@  find_lwp_pid (ptid_t ptid)
 static int
 num_lwps (int pid)
 {
-  struct inferior_list_entry *inf, *tmp;
   int count = 0;
 
-  ALL_INFERIORS (&all_threads, inf, tmp)
-    {
-      if (ptid_get_pid (inf->id) == pid)
-	count++;
-    }
+  for_each_thread ([&] (thread_info *thread) {
+    if (thread->id.pid () == pid)
+      count++;
+  });
 
   return count;
 }
@@ -1897,15 +1890,14 @@  struct iterate_over_lwps_args
    find_inferiors should continue iterating.  */
 
 static int
-iterate_over_lwps_filter (struct inferior_list_entry *entry, void *args_p)
+iterate_over_lwps_filter (thread_info *thread, void *args_p)
 {
   struct iterate_over_lwps_args *args
     = (struct iterate_over_lwps_args *) args_p;
 
-  if (ptid_match (entry->id, args->filter))
+  if (thread->id.matches (args->filter))
     {
-      struct thread_info *thr = (struct thread_info *) entry;
-      struct lwp_info *lwp = get_thread_lwp (thr);
+      struct lwp_info *lwp = get_thread_lwp (thread);
 
       return (*args->callback) (lwp, args->data);
     }
@@ -1921,13 +1913,13 @@  iterate_over_lwps (ptid_t filter,
 		   void *data)
 {
   struct iterate_over_lwps_args args = {filter, callback, data};
-  struct inferior_list_entry *entry;
 
-  entry = find_inferior (&all_threads, iterate_over_lwps_filter, &args);
-  if (entry == NULL)
+  thread_info *thread = find_inferior (&all_threads, iterate_over_lwps_filter,
+				       &args);
+  if (thread == NULL)
     return NULL;
 
-  return get_thread_lwp ((struct thread_info *) entry);
+  return get_thread_lwp (thread);
 }
 
 /* Detect zombie thread group leaders, and "exit" them.  We can't reap
@@ -1996,16 +1988,15 @@  check_zombie_leaders (void)
    stopped.  ARG is a PTID filter.  */
 
 static int
-not_stopped_callback (struct inferior_list_entry *entry, void *arg)
+not_stopped_callback (thread_info *thread, void *arg)
 {
-  struct thread_info *thr = (struct thread_info *) entry;
   struct lwp_info *lwp;
   ptid_t filter = *(ptid_t *) arg;
 
-  if (!ptid_match (ptid_of (thr), filter))
+  if (!ptid_match (ptid_of (thread), filter))
     return 0;
 
-  lwp = get_thread_lwp (thr);
+  lwp = get_thread_lwp (thread);
   if (!lwp->stopped)
     return 1;
 
@@ -2651,9 +2642,8 @@  maybe_hw_step (struct thread_info *thread)
    to report, but are resumed from the core's perspective.  */
 
 static void
-resume_stopped_resumed_lwps (struct inferior_list_entry *entry)
+resume_stopped_resumed_lwps (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lp = get_thread_lwp (thread);
 
   if (lp->stopped
@@ -2893,9 +2883,8 @@  linux_wait_for_event (ptid_t ptid, int *wstatp, int options)
 /* Count the LWP's that have had events.  */
 
 static int
-count_events_callback (struct inferior_list_entry *entry, void *data)
+count_events_callback (thread_info *thread, void *data)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lp = get_thread_lwp (thread);
   int *count = (int *) data;
 
@@ -2912,9 +2901,8 @@  count_events_callback (struct inferior_list_entry *entry, void *data)
 /* Select the LWP (if any) that is currently being single-stepped.  */
 
 static int
-select_singlestep_lwp_callback (struct inferior_list_entry *entry, void *data)
+select_singlestep_lwp_callback (thread_info *thread, void *data)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lp = get_thread_lwp (thread);
 
   if (thread->last_status.kind == TARGET_WAITKIND_IGNORE
@@ -2928,9 +2916,8 @@  select_singlestep_lwp_callback (struct inferior_list_entry *entry, void *data)
 /* Select the Nth LWP that has had an event.  */
 
 static int
-select_event_lwp_callback (struct inferior_list_entry *entry, void *data)
+select_event_lwp_callback (thread_info *thread, void *data)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lp = get_thread_lwp (thread);
   int *selector = (int *) data;
 
@@ -3011,9 +2998,8 @@  select_event_lwp (struct lwp_info **orig_lp)
 /* Decrement the suspend count of an LWP.  */
 
 static int
-unsuspend_one_lwp (struct inferior_list_entry *entry, void *except)
+unsuspend_one_lwp (thread_info *thread, void *except)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   /* Ignore EXCEPT.  */
@@ -3033,10 +3019,9 @@  unsuspend_all_lwps (struct lwp_info *except)
   find_inferior (&all_threads, unsuspend_one_lwp, except);
 }
 
-static void move_out_of_jump_pad_callback (struct inferior_list_entry *entry);
-static int stuck_in_jump_pad_callback (struct inferior_list_entry *entry,
-				       void *data);
-static int lwp_running (struct inferior_list_entry *entry, void *data);
+static void move_out_of_jump_pad_callback (thread_info *thread);
+static int stuck_in_jump_pad_callback (thread_info *thread, void *data);
+static int lwp_running (thread_info *thread, void *data);
 static ptid_t linux_wait_1 (ptid_t ptid,
 			    struct target_waitstatus *ourstatus,
 			    int target_options);
@@ -3772,18 +3757,16 @@  linux_wait_1 (ptid_t ptid,
 	{
 	  /* In all-stop, a stop reply cancels all previous resume
 	     requests.  Delete all single-step breakpoints.  */
-	  struct inferior_list_entry *inf, *tmp;
 
-	  ALL_INFERIORS (&all_threads, inf, tmp)
-	    {
-	      struct thread_info *thread = (struct thread_info *) inf;
+	  find_thread ([&] (thread_info *thread) {
+	    if (has_single_step_breakpoints (thread))
+	      {
+		remove_single_step_breakpoints_p = 1;
+		return true;
+	      }
 
-	      if (has_single_step_breakpoints (thread))
-		{
-		  remove_single_step_breakpoints_p = 1;
-		  break;
-		}
-	    }
+	    return false;
+	  });
 	}
 
       if (remove_single_step_breakpoints_p)
@@ -3800,15 +3783,10 @@  linux_wait_1 (ptid_t ptid,
 	    }
 	  else
 	    {
-	      struct inferior_list_entry *inf, *tmp;
-
-	      ALL_INFERIORS (&all_threads, inf, tmp)
-		{
-		  struct thread_info *thread = (struct thread_info *) inf;
-
-		  if (has_single_step_breakpoints (thread))
-		    delete_single_step_breakpoints (thread);
-		}
+	      for_each_thread ([] (thread_info *thread){
+		if (has_single_step_breakpoints (thread))
+		  delete_single_step_breakpoints (thread);
+	      });
 	    }
 
 	  unstop_all_lwps (0, event_child);
@@ -4061,9 +4039,8 @@  send_sigstop (struct lwp_info *lwp)
 }
 
 static int
-send_sigstop_callback (struct inferior_list_entry *entry, void *except)
+send_sigstop_callback (thread_info *thread, void *except)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   /* Ignore EXCEPT.  */
@@ -4080,10 +4057,8 @@  send_sigstop_callback (struct inferior_list_entry *entry, void *except)
 /* Increment the suspend count of an LWP, and stop it, if not stopped
    yet.  */
 static int
-suspend_and_send_sigstop_callback (struct inferior_list_entry *entry,
-				   void *except)
+suspend_and_send_sigstop_callback (thread_info *thread, void *except)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   /* Ignore EXCEPT.  */
@@ -4092,7 +4067,7 @@  suspend_and_send_sigstop_callback (struct inferior_list_entry *entry,
 
   lwp_suspended_inc (lwp);
 
-  return send_sigstop_callback (entry, except);
+  return send_sigstop_callback (thread, except);
 }
 
 static void
@@ -4145,7 +4120,7 @@  wait_for_sigstop (void)
 
   saved_thread = current_thread;
   if (saved_thread != NULL)
-    saved_tid = saved_thread->entry.id;
+    saved_tid = saved_thread->id;
   else
     saved_tid = null_ptid; /* avoid bogus unused warning */
 
@@ -4179,9 +4154,8 @@  wait_for_sigstop (void)
    because she wants to debug it.  */
 
 static int
-stuck_in_jump_pad_callback (struct inferior_list_entry *entry, void *data)
+stuck_in_jump_pad_callback (thread_info *thread, void *data)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   if (lwp->suspended != 0)
@@ -4203,9 +4177,8 @@  stuck_in_jump_pad_callback (struct inferior_list_entry *entry, void *data)
 }
 
 static void
-move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
+move_out_of_jump_pad_callback (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct thread_info *saved_thread;
   struct lwp_info *lwp = get_thread_lwp (thread);
   int *wstat;
@@ -4254,9 +4227,8 @@  move_out_of_jump_pad_callback (struct inferior_list_entry *entry)
 }
 
 static int
-lwp_running (struct inferior_list_entry *entry, void *data)
+lwp_running (thread_info *thread, void *data)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   if (lwp_is_marked_dead (lwp))
@@ -4657,9 +4629,8 @@  struct thread_resume_array
    suspension).  */
 
 static int
-linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
+linux_set_resume_request (thread_info *thread, void *arg)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
   int ndx;
   struct thread_resume_array *r;
@@ -4670,7 +4641,7 @@  linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
     {
       ptid_t ptid = r->resume[ndx].thread;
       if (ptid_equal (ptid, minus_one_ptid)
-	  || ptid_equal (ptid, entry->id)
+	  || ptid == thread->id
 	  /* Handle both 'pPID' and 'pPID.-1' as meaning 'all threads
 	     of PID'.  */
 	  || (ptid_get_pid (ptid) == pid_of (thread)
@@ -4727,7 +4698,7 @@  linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
 	     reported to GDBserver core, but GDB has not pulled the
 	     event out of the vStopped queue yet, likewise, ignore the
 	     (wildcard) resume request.  */
-	  if (in_queued_stop_replies (entry->id))
+	  if (in_queued_stop_replies (thread->id))
 	    {
 	      if (debug_threads)
 		debug_printf ("not resuming LWP %ld: has queued stop reply\n",
@@ -4771,9 +4742,8 @@  linux_set_resume_request (struct inferior_list_entry *entry, void *arg)
    Set *FLAG_P if this lwp has an interesting status pending.  */
 
 static int
-resume_status_pending_p (struct inferior_list_entry *entry, void *flag_p)
+resume_status_pending_p (thread_info *thread, void *flag_p)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   /* LWPs which will not be resumed are not interesting, because
@@ -4793,9 +4763,8 @@  resume_status_pending_p (struct inferior_list_entry *entry, void *flag_p)
    inferior's regcache.  */
 
 static int
-need_step_over_p (struct inferior_list_entry *entry, void *dummy)
+need_step_over_p (thread_info *thread, void *dummy)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
   struct thread_info *saved_thread;
   CORE_ADDR pc;
@@ -4978,7 +4947,7 @@  start_step_over (struct lwp_info *lwp)
   linux_resume_one_lwp (lwp, step, 0, NULL);
 
   /* Require next event from this LWP.  */
-  step_over_bkpt = thread->entry.id;
+  step_over_bkpt = thread->id;
   return 1;
 }
 
@@ -5071,9 +5040,8 @@  complete_ongoing_step_over (void)
    they should be re-issued if necessary.  */
 
 static int
-linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
+linux_resume_one_thread (thread_info *thread, void *arg)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
   int leave_all_stopped = * (int *) arg;
   int leave_pending;
@@ -5164,7 +5132,7 @@  linux_resume_one_thread (struct inferior_list_entry *entry, void *arg)
       if (debug_threads)
 	debug_printf ("resuming LWP %ld\n", lwpid_of (thread));
 
-      proceed_one_lwp (entry, NULL);
+      proceed_one_lwp (thread, NULL);
     }
   else
     {
@@ -5256,9 +5224,8 @@  linux_resume (struct thread_resume *resume_info, size_t n)
    on that particular thread, and leave all others stopped.  */
 
 static int
-proceed_one_lwp (struct inferior_list_entry *entry, void *except)
+proceed_one_lwp (thread_info *thread, void *except)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
   int step;
 
@@ -5355,9 +5322,8 @@  proceed_one_lwp (struct inferior_list_entry *entry, void *except)
 }
 
 static int
-unsuspend_and_proceed_one_lwp (struct inferior_list_entry *entry, void *except)
+unsuspend_and_proceed_one_lwp (thread_info *thread, void *except)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   if (lwp == except)
@@ -5365,7 +5331,7 @@  unsuspend_and_proceed_one_lwp (struct inferior_list_entry *entry, void *except)
 
   lwp_suspended_decr (lwp);
 
-  return proceed_one_lwp (entry, except);
+  return proceed_one_lwp (thread, except);
 }
 
 /* When we finish a step-over, set threads running again.  If there's
@@ -6467,10 +6433,8 @@  linux_supports_exec_events (void)
    options for the specified lwp.  */
 
 static int
-reset_lwp_ptrace_options_callback (struct inferior_list_entry *entry,
-				   void *args)
+reset_lwp_ptrace_options_callback (thread_info *thread, void *args)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
 
   if (!lwp->stopped)
diff --git a/gdb/gdbserver/linux-mips-low.c b/gdb/gdbserver/linux-mips-low.c
index b4a83b0e21..cee20eda67 100644
--- a/gdb/gdbserver/linux-mips-low.c
+++ b/gdb/gdbserver/linux-mips-low.c
@@ -293,10 +293,8 @@  mips_breakpoint_at (CORE_ADDR where)
    if the lwp's process id is *PID_P.  */
 
 static int
-update_watch_registers_callback (struct inferior_list_entry *entry,
-				 void *pid_p)
+update_watch_registers_callback (thread_info *thread, void *pid_p)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct lwp_info *lwp = get_thread_lwp (thread);
   int pid = *(int *) pid_p;
 
diff --git a/gdb/gdbserver/lynx-low.c b/gdb/gdbserver/lynx-low.c
index f074dd50b3..ca9adc446b 100644
--- a/gdb/gdbserver/lynx-low.c
+++ b/gdb/gdbserver/lynx-low.c
@@ -559,16 +559,12 @@  lynx_detach (int pid)
    all threads belonging to process PROC.  */
 
 static int
-lynx_delete_thread_callback (struct inferior_list_entry *entry, void *proc)
+lynx_delete_thread_callback (thread_info *thread, void *proc)
 {
   struct process_info *process = (struct process_info *) proc;
 
-  if (ptid_get_pid (entry->id) == pid_of (process))
-    {
-      struct thread_info *thr = find_thread_ptid (entry->id);
-
-      remove_thread (thr);
-    }
+  if (thread->id.pid () == pid_of (process))
+    remove_thread (thread);
 
   return 0;
 }
diff --git a/gdb/gdbserver/regcache.c b/gdb/gdbserver/regcache.c
index 75480912fb..e45e60e5ca 100644
--- a/gdb/gdbserver/regcache.c
+++ b/gdb/gdbserver/regcache.c
@@ -94,14 +94,12 @@  regcache_invalidate_thread (struct thread_info *thread)
 }
 
 static int
-regcache_invalidate_one (struct inferior_list_entry *entry,
-			 void *pid_p)
+regcache_invalidate_one (thread_info *thread, void *pid_p)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   int pid = *(int *) pid_p;
 
   /* Only invalidate the regcaches of threads of this process.  */
-  if (ptid_get_pid (entry->id) == pid)
+  if (thread->id.pid () == pid)
     regcache_invalidate_thread (thread);
 
   return 0;
@@ -121,7 +119,7 @@  void
 regcache_invalidate (void)
 {
   /* Only update the threads of the current process.  */
-  int pid = ptid_get_pid (current_thread->entry.id);
+  int pid = current_thread->id.pid ();
 
   regcache_invalidate_pid (pid);
 }
@@ -290,19 +288,11 @@  free_register_cache_thread (struct thread_info *thread)
     }
 }
 
-static void
-free_register_cache_thread_one (struct inferior_list_entry *entry)
-{
-  struct thread_info *thread = (struct thread_info *) entry;
-
-  free_register_cache_thread (thread);
-}
-
 void
 regcache_release (void)
 {
   /* Flush and release all pre-existing register caches.  */
-  for_each_inferior (&all_threads, free_register_cache_thread_one);
+  for_each_inferior (&all_threads, free_register_cache_thread);
 }
 #endif
 
diff --git a/gdb/gdbserver/server.c b/gdb/gdbserver/server.c
index 14811c0390..f8ec8b4955 100644
--- a/gdb/gdbserver/server.c
+++ b/gdb/gdbserver/server.c
@@ -387,8 +387,7 @@  handle_btrace_enable_bts (struct thread_info *thread)
     return "E.Btrace already enabled.";
 
   current_btrace_conf.format = BTRACE_FORMAT_BTS;
-  thread->btrace = target_enable_btrace (thread->entry.id,
-					 &current_btrace_conf);
+  thread->btrace = target_enable_btrace (thread->id, &current_btrace_conf);
   if (thread->btrace == NULL)
     return "E.Could not enable btrace.";
 
@@ -404,8 +403,7 @@  handle_btrace_enable_pt (struct thread_info *thread)
     return "E.Btrace already enabled.";
 
   current_btrace_conf.format = BTRACE_FORMAT_PT;
-  thread->btrace = target_enable_btrace (thread->entry.id,
-					 &current_btrace_conf);
+  thread->btrace = target_enable_btrace (thread->id, &current_btrace_conf);
   if (thread->btrace == NULL)
     return "E.Could not enable btrace.";
 
@@ -1652,9 +1650,8 @@  handle_qxfer_statictrace (const char *annex,
    Emit the XML to describe the thread of INF.  */
 
 static void
-handle_qxfer_threads_worker (struct inferior_list_entry *inf, void *arg)
+handle_qxfer_threads_worker (thread_info *thread, void *arg)
 {
-  struct thread_info *thread = (struct thread_info *) inf;
   struct buffer *buffer = (struct buffer *) arg;
   ptid_t ptid = ptid_of (thread);
   char ptid_s[100];
@@ -2145,7 +2142,7 @@  supported_btrace_packets (char *buf)
 static void
 handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
 {
-  static struct inferior_list_entry *thread_ptr;
+  static std::list<thread_info *>::const_iterator thread_iter;
 
   /* Reply the current thread id.  */
   if (strcmp ("qC", own_buf) == 0 && !disable_packet_qC)
@@ -2157,8 +2154,8 @@  handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
 	ptid = general_thread;
       else
 	{
-	  thread_ptr = get_first_inferior (&all_threads);
-	  ptid = thread_ptr->id;
+	  thread_iter = all_threads.begin ();
+	  ptid = (*thread_iter)->id;
 	}
 
       sprintf (own_buf, "QC");
@@ -2220,22 +2217,24 @@  handle_query (char *own_buf, int packet_len, int *new_packet_len_p)
       if (strcmp ("qfThreadInfo", own_buf) == 0)
 	{
 	  require_running_or_return (own_buf);
-	  thread_ptr = get_first_inferior (&all_threads);
+	  thread_iter = all_threads.begin ();
 
 	  *own_buf++ = 'm';
-	  write_ptid (own_buf, thread_ptr->id);
-	  thread_ptr = thread_ptr->next;
+	  ptid_t ptid = (*thread_iter)->id;
+	  write_ptid (own_buf, ptid);
+	  thread_iter++;
 	  return;
 	}
 
       if (strcmp ("qsThreadInfo", own_buf) == 0)
 	{
 	  require_running_or_return (own_buf);
-	  if (thread_ptr != NULL)
+	  if (thread_iter != all_threads.end ())
 	    {
 	      *own_buf++ = 'm';
-	      write_ptid (own_buf, thread_ptr->id);
-	      thread_ptr = thread_ptr->next;
+	      ptid_t ptid = (*thread_iter)->id;
+	      write_ptid (own_buf, ptid);
+	      thread_iter++;
 	      return;
 	    }
 	  else
@@ -2693,7 +2692,7 @@  struct visit_actioned_threads_data
    Note: This function is itself a callback for find_inferior.  */
 
 static int
-visit_actioned_threads (struct inferior_list_entry *entry, void *datap)
+visit_actioned_threads (thread_info *thread, void *datap)
 {
   struct visit_actioned_threads_data *data
     = (struct visit_actioned_threads_data *) datap;
@@ -2707,13 +2706,11 @@  visit_actioned_threads (struct inferior_list_entry *entry, void *datap)
       const struct thread_resume *action = &actions[i];
 
       if (ptid_equal (action->thread, minus_one_ptid)
-	  || ptid_equal (action->thread, entry->id)
+	  || ptid_equal (action->thread, thread->id)
 	  || ((ptid_get_pid (action->thread)
-	       == ptid_get_pid (entry->id))
+	       == thread->id.pid ())
 	      && ptid_get_lwp (action->thread) == -1))
 	{
-	  struct thread_info *thread = (struct thread_info *) entry;
-
 	  if ((*callback) (action, thread))
 	    return 1;
 	}
@@ -2734,7 +2731,7 @@  handle_pending_status (const struct thread_resume *resumption,
       thread->status_pending_p = 0;
 
       last_status = thread->last_status;
-      last_ptid = thread->entry.id;
+      last_ptid = thread->id;
       prepare_resume_reply (own_buf, last_ptid, &last_status);
       return 1;
     }
@@ -3234,17 +3231,15 @@  myresume (char *own_buf, int step, int sig)
    stopped thread.  */
 
 static int
-queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg)
+queue_stop_reply_callback (thread_info *thread, void *arg)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
-
   /* For now, assume targets that don't have this callback also don't
      manage the thread's last_status field.  */
   if (the_target->thread_stopped == NULL)
     {
       struct vstop_notif *new_notif = XNEW (struct vstop_notif);
 
-      new_notif->ptid = entry->id;
+      new_notif->ptid = thread->id;
       new_notif->status = thread->last_status;
       /* Pass the last stop reply back to GDB, but don't notify
 	 yet.  */
@@ -3261,7 +3256,7 @@  queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg)
 		= target_waitstatus_to_string (&thread->last_status);
 
 	      debug_printf ("Reporting thread %s as already stopped with %s\n",
-			    target_pid_to_str (entry->id),
+			    target_pid_to_str (thread->id),
 			    status_string.c_str ());
 	    }
 
@@ -3269,7 +3264,7 @@  queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg)
 
 	  /* Pass the last stop reply back to GDB, but don't notify
 	     yet.  */
-	  queue_stop_reply (entry->id, &thread->last_status);
+	  queue_stop_reply (thread->id, &thread->last_status);
 	}
     }
 
@@ -3281,10 +3276,8 @@  queue_stop_reply_callback (struct inferior_list_entry *entry, void *arg)
    it.  */
 
 static void
-gdb_wants_thread_stopped (struct inferior_list_entry *entry)
+gdb_wants_thread_stopped (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
-
   thread->last_resume_kind = resume_stop;
 
   if (thread->last_status.kind == TARGET_WAITKIND_IGNORE)
@@ -3308,10 +3301,8 @@  gdb_wants_all_threads_stopped (void)
    flag.  */
 
 static void
-clear_pending_status_callback (struct inferior_list_entry *entry)
+clear_pending_status_callback (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
-
   thread->status_pending_p = 0;
 }
 
@@ -3319,10 +3310,8 @@  clear_pending_status_callback (struct inferior_list_entry *entry)
    interesting event, mark it as having a pending event.  */
 
 static void
-set_pending_status_callback (struct inferior_list_entry *entry)
+set_pending_status_callback (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
-
   if (thread->last_status.kind != TARGET_WAITKIND_STOPPED
       || (thread->last_status.value.sig != GDB_SIGNAL_0
 	  /* A breakpoint, watchpoint or finished step from a previous
@@ -3339,10 +3328,8 @@  set_pending_status_callback (struct inferior_list_entry *entry)
    pending status to report to GDB.  */
 
 static int
-find_status_pending_thread_callback (struct inferior_list_entry *entry, void *data)
+find_status_pending_thread_callback (thread_info *thread, void *data)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
-
   return thread->status_pending_p;
 }
 
@@ -3371,7 +3358,7 @@  handle_status (char *own_buf)
     }
   else
     {
-      struct inferior_list_entry *thread = NULL;
+      thread_info *thread = NULL;
 
       pause_all (0);
       stabilize_threads ();
@@ -3401,7 +3388,7 @@  handle_status (char *own_buf)
       /* If we're still out of luck, simply pick the first thread in
 	 the thread list.  */
       if (thread == NULL)
-	thread = get_first_inferior (&all_threads);
+	thread = get_first_thread ();
 
       if (thread != NULL)
 	{
@@ -3417,7 +3404,7 @@  handle_status (char *own_buf)
 	  set_desired_thread ();
 
 	  gdb_assert (tp->last_status.kind != TARGET_WAITKIND_IGNORE);
-	  prepare_resume_reply (own_buf, tp->entry.id, &tp->last_status);
+	  prepare_resume_reply (own_buf, tp->id, &tp->last_status);
 	}
       else
 	strcpy (own_buf, "W00");
@@ -4095,7 +4082,7 @@  process_serial_event (void)
 		  break;
 		}
 
-	      thread_id = thread->entry.id;
+	      thread_id = thread->id;
 	    }
 	  else
 	    {
@@ -4119,7 +4106,7 @@  process_serial_event (void)
 							     general_thread);
 		  if (thread == NULL)
 		    thread = get_first_thread ();
-		  thread_id = thread->entry.id;
+		  thread_id = thread->id;
 		}
 
 	      general_thread = thread_id;
diff --git a/gdb/gdbserver/target.c b/gdb/gdbserver/target.c
index 94224a8a7c..8f757c0a5d 100644
--- a/gdb/gdbserver/target.c
+++ b/gdb/gdbserver/target.c
@@ -55,12 +55,11 @@  struct thread_search
    when accessing memory.  */
 
 static int
-thread_search_callback (struct inferior_list_entry *entry, void *args)
+thread_search_callback (thread_info *thread, void *args)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   struct thread_search *s = (struct thread_search *) args;
 
-  if (ptid_get_pid (entry->id) == ptid_get_pid (s->current_gen_ptid)
+  if (thread->id.pid () == ptid_get_pid (s->current_gen_ptid)
       && mythread_alive (ptid_of (thread)))
     {
       if (s->stopped == NULL
@@ -71,7 +70,7 @@  thread_search_callback (struct inferior_list_entry *entry, void *args)
       if (s->first == NULL)
 	s->first = thread;
 
-      if (s->current == NULL && ptid_equal (s->current_gen_ptid, entry->id))
+      if (s->current == NULL && s->current_gen_ptid == thread->id)
 	s->current = thread;
     }
 
diff --git a/gdb/gdbserver/thread-db.c b/gdb/gdbserver/thread-db.c
index 638a8337b6..67970f4eca 100644
--- a/gdb/gdbserver/thread-db.c
+++ b/gdb/gdbserver/thread-db.c
@@ -407,7 +407,7 @@  thread_db_get_tls_address (struct thread_info *thread, CORE_ADDR offset,
 
   lwp = get_thread_lwp (thread);
   if (!lwp->thread_known)
-    find_one_thread (thread->entry.id);
+    find_one_thread (thread->id);
   if (!lwp->thread_known)
     return TD_NOTHR;
 
@@ -465,7 +465,7 @@  thread_db_thread_handle (ptid_t ptid, gdb_byte **handle, int *handle_len)
 
   lwp = get_thread_lwp (thread);
 
-  if (!lwp->thread_known && !find_one_thread (thread->entry.id))
+  if (!lwp->thread_known && !find_one_thread (thread->id))
     return false;
 
   gdb_assert (lwp->thread_known);
diff --git a/gdb/gdbserver/tracepoint.c b/gdb/gdbserver/tracepoint.c
index 8ec8010ac8..73090a753d 100644
--- a/gdb/gdbserver/tracepoint.c
+++ b/gdb/gdbserver/tracepoint.c
@@ -4396,7 +4396,7 @@  tracepoint_finished_step (struct thread_info *tinfo, CORE_ADDR stop_pc)
   wstep_link = &tinfo->while_stepping;
 
   trace_debug ("Thread %s finished a single-step for tracepoint %d at 0x%s",
-	       target_pid_to_str (tinfo->entry.id),
+	       target_pid_to_str (tinfo->id),
 	       wstep->tp_number, paddress (wstep->tp_address));
 
   ctx.base.type = trap_tracepoint;
@@ -4409,7 +4409,7 @@  tracepoint_finished_step (struct thread_info *tinfo, CORE_ADDR stop_pc)
 	{
 	  trace_debug ("NO TRACEPOINT %d at 0x%s FOR THREAD %s!",
 		       wstep->tp_number, paddress (wstep->tp_address),
-		       target_pid_to_str (tinfo->entry.id));
+		       target_pid_to_str (tinfo->id));
 
 	  /* Unlink.  */
 	  *wstep_link = wstep->next;
@@ -4429,7 +4429,7 @@  tracepoint_finished_step (struct thread_info *tinfo, CORE_ADDR stop_pc)
 	{
 	  /* The requested numbers of steps have occurred.  */
 	  trace_debug ("Thread %s done stepping for tracepoint %d at 0x%s",
-		       target_pid_to_str (tinfo->entry.id),
+		       target_pid_to_str (tinfo->id),
 		       wstep->tp_number, paddress (wstep->tp_address));
 
 	  /* Unlink the wstep.  */
@@ -4576,7 +4576,7 @@  tracepoint_was_hit (struct thread_info *tinfo, CORE_ADDR stop_pc)
 	  && tpoint->type != static_tracepoint)
 	{
 	  trace_debug ("Thread %s at address of tracepoint %d at 0x%s",
-		       target_pid_to_str (tinfo->entry.id),
+		       target_pid_to_str (tinfo->id),
 		       tpoint->number, paddress (tpoint->address));
 
 	  /* Test the condition if present, and collect if true.  */
diff --git a/gdb/gdbserver/win32-i386-low.c b/gdb/gdbserver/win32-i386-low.c
index 03d6e1779d..fd99ca9cb6 100644
--- a/gdb/gdbserver/win32-i386-low.c
+++ b/gdb/gdbserver/win32-i386-low.c
@@ -37,10 +37,8 @@ 
 static struct x86_debug_reg_state debug_reg_state;
 
 static int
-update_debug_registers_callback (struct inferior_list_entry *entry,
-				 void *pid_p)
+update_debug_registers_callback (thread_info *thr, void *pid_p)
 {
-  struct thread_info *thr = (struct thread_info *) entry;
   win32_thread_info *th = (win32_thread_info *) thread_target_data (thr);
   int pid = *(int *) pid_p;
 
diff --git a/gdb/gdbserver/win32-low.c b/gdb/gdbserver/win32-low.c
index f9c890f164..66fc52c392 100644
--- a/gdb/gdbserver/win32-low.c
+++ b/gdb/gdbserver/win32-low.c
@@ -231,9 +231,8 @@  child_add_thread (DWORD pid, DWORD tid, HANDLE h, void *tlb)
 
 /* Delete a thread from the list of threads.  */
 static void
-delete_thread_info (struct inferior_list_entry *entry)
+delete_thread_info (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   win32_thread_info *th = (win32_thread_info *) thread_target_data (thread);
 
   remove_thread (thread);
@@ -245,15 +244,14 @@  delete_thread_info (struct inferior_list_entry *entry)
 static void
 child_delete_thread (DWORD pid, DWORD tid)
 {
-  struct inferior_list_entry *thread;
   ptid_t ptid;
 
   /* If the last thread is exiting, just return.  */
-  if (one_inferior_p (&all_threads))
+  if (all_threads.size () == 1)
     return;
 
   ptid = ptid_build (pid, tid, 0);
-  thread = find_inferior_id (&all_threads, ptid);
+  thread_info *thread = find_inferior_id (&all_threads, ptid);
   if (thread == NULL)
     return;
 
@@ -431,9 +429,8 @@  do_initial_child_stuff (HANDLE proch, DWORD pid, int attached)
 /* Resume all artificially suspended threads if we are continuing
    execution.  */
 static int
-continue_one_thread (struct inferior_list_entry *this_thread, void *id_ptr)
+continue_one_thread (thread_info *thread, void *id_ptr)
 {
-  struct thread_info *thread = (struct thread_info *) this_thread;
   int thread_id = * (int *) id_ptr;
   win32_thread_info *th = (win32_thread_info *) thread_target_data (thread);
 
@@ -1347,9 +1344,8 @@  handle_exception (struct target_waitstatus *ourstatus)
 
 
 static void
-suspend_one_thread (struct inferior_list_entry *entry)
+suspend_one_thread (thread_info *thread)
 {
-  struct thread_info *thread = (struct thread_info *) entry;
   win32_thread_info *th = (win32_thread_info *) thread_target_data (thread);
 
   if (!th->suspended)
@@ -1488,7 +1484,7 @@  get_child_debug_event (struct target_waitstatus *ourstatus)
       child_delete_thread (current_event.dwProcessId,
 			   current_event.dwThreadId);
 
-      current_thread = (struct thread_info *) all_threads.head;
+      current_thread = get_first_thread ();
       return 1;
 
     case CREATE_PROCESS_DEBUG_EVENT: