aboutsummaryrefslogtreecommitdiff
path: root/gdb/thread-iter.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/thread-iter.c')
-rw-r--r--gdb/thread-iter.c138
1 files changed, 90 insertions, 48 deletions
diff --git a/gdb/thread-iter.c b/gdb/thread-iter.c
index 31b7a36..e56ccd8 100644
--- a/gdb/thread-iter.c
+++ b/gdb/thread-iter.c
@@ -75,39 +75,56 @@ all_threads_iterator::advance ()
bool
all_matching_threads_iterator::m_inf_matches ()
{
- return ((m_filter_target == nullptr
- || m_filter_target == m_inf->process_target ())
- && (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
(process_stratum_target *filter_target, ptid_t filter_ptid)
- : m_filter_target (filter_target),
- m_filter_ptid (filter_ptid)
+ : m_filter_target (filter_target)
{
- gdb_assert ((filter_target == nullptr && filter_ptid == minus_one_ptid)
- || filter_target->stratum () == process_stratum);
-
- for (inferior &inf : inferior_list)
+ if (filter_ptid == minus_one_ptid)
{
- m_inf = &inf;
- if (m_inf_matches ())
- for (auto thr_iter = m_inf->thread_list.begin ();
- thr_iter != m_inf->thread_list.end ();
- ++thr_iter)
- {
- if (thr_iter->ptid.matches (m_filter_ptid))
- {
- m_thr = &*thr_iter;
- return;
- }
- }
+ /* 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);
- m_thr = 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. */
@@ -115,32 +132,57 @@ all_matching_threads_iterator::all_matching_threads_iterator
void
all_matching_threads_iterator::advance ()
{
- intrusive_list<inferior>::iterator inf_iter (m_inf);
- intrusive_list<thread_info>::iterator thr_iter (m_thr);
+ switch (m_mode)
+ {
+ case mode::ALL_THREADS:
+ {
+ 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)
+ {
+ m_inf = &*inf_iter;
- /* 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;
+ if (!m_inf_matches ())
+ continue;
- for (; inf_iter != inferior_list.end (); ++inf_iter)
- {
- m_inf = &*inf_iter;
- if (m_inf_matches ())
- {
- thr_iter = m_inf->thread_list.begin ();
- while (thr_iter != m_inf->thread_list.end ())
- {
- if (thr_iter->ptid.matches (m_filter_ptid))
- {
- m_thr = &*thr_iter;
- return;
- }
- start:
- ++thr_iter;
- }
- }
- }
+ thr_iter = m_inf->thread_list.begin ();
+ while (thr_iter != m_inf->thread_list.end ())
+ {
+ m_thr = &*thr_iter;
+ return;
- m_thr = nullptr;
+ 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");
+ }
}