/* Thread iterators and ranges for GDB, the GNU debugger.
- Copyright (C) 2018 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. */
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. */
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. */
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");
+ }
}