Add overloads of for_each_thread/find_thread that filter on pid
[deliverable/binutils-gdb.git] / gdb / gdbserver / gdbthread.h
index fe0a75e44d892b2c0000f50134bfd7d350d2be50..b82d5b0e72ac8ca9673c24046dd62aa2ebb4517e 100644 (file)
@@ -1,5 +1,5 @@
 /* Multi-thread control defs for remote server for GDB.
-   Copyright (C) 1993-2014 Free Software Foundation, Inc.
+   Copyright (C) 1993-2017 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 #ifndef GDB_THREAD_H
 #define GDB_THREAD_H
 
+#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;
-  void *regcache_data;
+  struct regcache *regcache_data;
 
   /* The last resume GDB requested on this thread.  */
   enum resume_kind last_resume_kind;
@@ -70,16 +73,146 @@ 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);
 
+/* Find any thread of the PID process.  Returns NULL if none is
+   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;
+}
+
+/* Like the above, but only consider threads with pid PID.  */
+
+template <typename Func>
+static thread_info *
+find_thread (int pid, Func func)
+{
+  return find_thread ([&] (thread_info *thread)
+    {
+      return thread->id.pid () == pid && func (thread);
+    });
+}
+
+/* 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;
+    }
+}
+
+/* Like the above, but only consider threads with pid PID.  */
+
+template <typename Func>
+static void
+for_each_thread (int pid, Func func)
+{
+  for_each_thread ([&] (thread_info *thread)
+    {
+      if (pid == thread->id.pid ())
+       func (thread);
+    });
+}
+
+/* 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_inferior->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->id;
+}
+
+/* Get the pid of THREAD.  */
+
+static inline int
+pid_of (const thread_info *thread)
+{
+  return thread->id.pid ();
+}
+
+/* Get the lwp of THREAD.  */
+
+static inline long
+lwpid_of (const thread_info *thread)
+{
+  return thread->id.lwp ();
+}
+
+/* Create a cleanup to restore current_thread.  */
+struct cleanup *make_cleanup_restore_current_thread (void);
 
 #endif /* GDB_THREAD_H */
This page took 0.029003 seconds and 4 git commands to generate.