123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- /* Thread iterators and ranges for GDB, the GNU debugger.
- Copyright (C) 2018-2022 Free Software Foundation, Inc.
- This file is part of GDB.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
- #include "defs.h"
- #include "gdbthread.h"
- #include "inferior.h"
- /* See thread-iter.h. */
- all_threads_iterator::all_threads_iterator (begin_t)
- {
- /* Advance M_INF/M_THR to the first thread's position. */
- 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 (; inf_iter != inferior_list.end (); ++inf_iter)
- {
- 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:
- ++thr_iter;
- }
- }
- m_thr = nullptr;
- }
- /* See thread-iter.h. */
- bool
- all_matching_threads_iterator::m_inf_matches ()
- {
- 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)
- {
- 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 ()
- {
- 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;
- 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");
- }
- }
|