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. */
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");
+ }
}
ptid_t filter_ptid);
/* Create a one-past-end iterator. */
- all_matching_threads_iterator ()
- : m_inf (nullptr),
- m_thr (nullptr),
- m_filter_target (nullptr),
- m_filter_ptid (minus_one_ptid)
- {}
+ all_matching_threads_iterator () = default;
thread_info *operator* () const { return m_thr; }
/* Advance to next thread, skipping filtered threads. */
void advance ();
- /* True if M_INF matches the process identified by
- M_FILTER_PTID. */
+ /* True if M_INF has the process target M_FILTER_TARGET. */
bool m_inf_matches ();
private:
+ enum class mode
+ {
+ /* All threads, possibly filtered down to a single target. */
+ ALL_THREADS,
+
+ /* All threads of the given inferior. */
+ ALL_THREADS_OF_INFERIOR,
+
+ /* A specific thread. */
+ SINGLE_THREAD,
+ } m_mode;
+
/* The current inferior. */
- inferior *m_inf;
+ inferior *m_inf = nullptr;
/* The current thread. */
- thread_info *m_thr;
+ thread_info *m_thr = nullptr;
- /* The filter. */
+ /* The target we filter on (may be nullptr). */
process_stratum_target *m_filter_target;
- ptid_t m_filter_ptid;
};
/* Filter for filtered_iterator. Filters out exited threads. */