Convert break-catch-syscall to vtable ops
[binutils-gdb.git] / gdb / thread-iter.c
index 9a41a46aa66bae9e94a1bb7ea2034e022084dc5e..0b1596fe947a12975bf4c60a33d2048d896472b1 100644 (file)
@@ -1,6 +1,6 @@
 /* Thread iterators and ranges for GDB, the GNU debugger.
 
-   Copyright (C) 2018-2019 Free Software Foundation, Inc.
+   Copyright (C) 2018-2022 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
 all_threads_iterator::all_threads_iterator (begin_t)
 {
   /* Advance M_INF/M_THR to the first thread's position.  */
-  for (m_inf = inferior_list; m_inf != NULL; m_inf = m_inf->next)
-    if ((m_thr = m_inf->thread_list) != NULL)
-      return;
+
+  for (inferior &inf : inferior_list)
+    {
+      auto thr_iter = inf.thread_list.begin ();
+      if (thr_iter != inf.thread_list.end ())
+       {
+         m_inf = &inf;
+         m_thr = &*thr_iter;
+         return;
+       }
+    }
+  m_inf = nullptr;
+  m_thr = nullptr;
 }
 
 /* See thread-iter.h.  */
@@ -36,21 +46,28 @@ all_threads_iterator::all_threads_iterator (begin_t)
 void
 all_threads_iterator::advance ()
 {
+  intrusive_list<inferior>::iterator inf_iter (m_inf);
+  intrusive_list<thread_info>::iterator thr_iter (m_thr);
+
   /* The loop below is written in the natural way as-if we'd always
      start at the beginning of the inferior list.  This fast forwards
      the algorithm to the actual current position.  */
   goto start;
 
-  for (; m_inf != NULL; m_inf = m_inf->next)
+  for (; inf_iter != inferior_list.end (); ++inf_iter)
     {
-      m_thr = m_inf->thread_list;
-      while (m_thr != NULL)
+      m_inf = &*inf_iter;
+      thr_iter = m_inf->thread_list.begin ();
+      while (thr_iter != m_inf->thread_list.end ())
        {
+         m_thr = &*thr_iter;
          return;
        start:
-         m_thr = m_thr->next;
+         ++thr_iter;
        }
     }
+
+  m_thr = nullptr;
 }
 
 /* See thread-iter.h.  */
@@ -58,22 +75,56 @@ all_threads_iterator::advance ()
 bool
 all_matching_threads_iterator::m_inf_matches ()
 {
-  return (m_filter_ptid == minus_one_ptid
-         || m_filter_ptid.pid () == m_inf->pid);
+  return (m_filter_target == nullptr
+         || m_filter_target == m_inf->process_target ());
 }
 
 /* See thread-iter.h.  */
 
 all_matching_threads_iterator::all_matching_threads_iterator
-  (ptid_t filter_ptid)
-  : m_filter_ptid (filter_ptid)
+  (process_stratum_target *filter_target, ptid_t filter_ptid)
+  : m_filter_target (filter_target)
 {
-  m_thr = nullptr;
-  for (m_inf = inferior_list; m_inf != NULL; m_inf = m_inf->next)
-    if (m_inf_matches ())
-      for (m_thr = m_inf->thread_list; m_thr != NULL; m_thr = m_thr->next)
-       if (m_thr->ptid.matches (m_filter_ptid))
+  if (filter_ptid == minus_one_ptid)
+    {
+      /* Iterate on all threads of all inferiors, possibly filtering on
+         FILTER_TARGET.  */
+      m_mode = mode::ALL_THREADS;
+
+      /* Seek the first thread of the first matching inferior.  */
+      for (inferior &inf : inferior_list)
+       {
+         m_inf = &inf;
+
+         if (!m_inf_matches ()
+             || inf.thread_list.empty ())
+           continue;
+
+         m_thr = &inf.thread_list.front ();
          return;
+       }
+    }
+  else
+    {
+      gdb_assert (filter_target != nullptr);
+
+      if (filter_ptid.is_pid ())
+       {
+         /* Iterate on all threads of the given inferior.  */
+         m_mode = mode::ALL_THREADS_OF_INFERIOR;
+
+         m_inf = find_inferior_pid (filter_target, filter_ptid.pid ());
+         if (m_inf != nullptr)
+           m_thr = &m_inf->thread_list.front ();
+       }
+      else
+       {
+         /* Iterate on a single thread.  */
+         m_mode = mode::SINGLE_THREAD;
+
+         m_thr = find_thread_ptid (filter_target, filter_ptid);
+       }
+    }
 }
 
 /* See thread-iter.h.  */
@@ -81,21 +132,57 @@ all_matching_threads_iterator::all_matching_threads_iterator
 void
 all_matching_threads_iterator::advance ()
 {
-  /* The loop below is written in the natural way as-if we'd always
-     start at the beginning of the inferior list.  This fast forwards
-     the algorithm to the actual current position.  */
-  goto start;
-
-  for (; m_inf != NULL; m_inf = m_inf->next)
-    if (m_inf_matches ())
+  switch (m_mode)
+    {
+    case mode::ALL_THREADS:
       {
-       m_thr = m_inf->thread_list;
-       while (m_thr != NULL)
+       intrusive_list<inferior>::iterator inf_iter (m_inf);
+       intrusive_list<thread_info>::iterator thr_iter
+         = m_inf->thread_list.iterator_to (*m_thr);
+
+       /* The loop below is written in the natural way as-if we'd always
+          start at the beginning of the inferior list.  This fast forwards
+          the algorithm to the actual current position.  */
+       goto start;
+
+       for (; inf_iter != inferior_list.end (); ++inf_iter)
          {
-           if (m_thr->ptid.matches (m_filter_ptid))
-             return;
-         start:
-           m_thr = m_thr->next;
+           m_inf = &*inf_iter;
+
+           if (!m_inf_matches ())
+             continue;
+
+           thr_iter = m_inf->thread_list.begin ();
+           while (thr_iter != m_inf->thread_list.end ())
+             {
+               m_thr = &*thr_iter;
+               return;
+
+             start:
+               ++thr_iter;
+             }
          }
       }
+      m_thr = nullptr;
+      break;
+
+    case mode::ALL_THREADS_OF_INFERIOR:
+      {
+       intrusive_list<thread_info>::iterator thr_iter
+         = m_inf->thread_list.iterator_to (*m_thr);
+       ++thr_iter;
+       if (thr_iter != m_inf->thread_list.end ())
+         m_thr = &*thr_iter;
+       else
+         m_thr = nullptr;
+       break;
+      }
+
+    case mode::SINGLE_THREAD:
+      m_thr = nullptr;
+      break;
+
+    default:
+      gdb_assert_not_reached ("invalid mode value");
+    }
 }