1 /* Thread iterators and ranges for GDB, the GNU debugger.
3 Copyright (C) 2018-2024 Free Software Foundation, Inc.
5 This file is part of GDB.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 #include "gdbthread.h"
23 /* See thread-iter.h. */
25 all_threads_iterator::all_threads_iterator (begin_t
)
27 /* Advance M_INF/M_THR to the first thread's position. */
29 for (inferior
&inf
: inferior_list
)
31 auto thr_iter
= inf
.thread_list
.begin ();
32 if (thr_iter
!= inf
.thread_list
.end ())
43 /* See thread-iter.h. */
46 all_threads_iterator::advance ()
48 intrusive_list
<inferior
>::iterator
inf_iter (m_inf
);
49 intrusive_list
<thread_info
>::iterator
thr_iter (m_thr
);
51 /* The loop below is written in the natural way as-if we'd always
52 start at the beginning of the inferior list. This fast forwards
53 the algorithm to the actual current position. */
56 for (; inf_iter
!= inferior_list
.end (); ++inf_iter
)
59 thr_iter
= m_inf
->thread_list
.begin ();
60 while (thr_iter
!= m_inf
->thread_list
.end ())
72 /* See thread-iter.h. */
75 all_matching_threads_iterator::m_inf_matches ()
77 return (m_filter_target
== nullptr
78 || m_filter_target
== m_inf
->process_target ());
81 /* See thread-iter.h. */
83 all_matching_threads_iterator::all_matching_threads_iterator
84 (process_stratum_target
*filter_target
, ptid_t filter_ptid
)
85 : m_filter_target (filter_target
)
87 if (filter_ptid
== minus_one_ptid
)
89 /* Iterate on all threads of all inferiors, possibly filtering on
91 m_mode
= mode::ALL_THREADS
;
93 /* Seek the first thread of the first matching inferior. */
94 for (inferior
&inf
: inferior_list
)
99 || inf
.thread_list
.empty ())
102 m_thr
= &inf
.thread_list
.front ();
108 gdb_assert (filter_target
!= nullptr);
110 if (filter_ptid
.is_pid ())
112 /* Iterate on all threads of the given inferior. */
113 m_mode
= mode::ALL_THREADS_OF_INFERIOR
;
115 m_inf
= find_inferior_pid (filter_target
, filter_ptid
.pid ());
116 if (m_inf
!= nullptr)
117 m_thr
= &m_inf
->thread_list
.front ();
121 /* Iterate on a single thread. */
122 m_mode
= mode::SINGLE_THREAD
;
124 m_thr
= filter_target
->find_thread (filter_ptid
);
129 /* See thread-iter.h. */
132 all_matching_threads_iterator::advance ()
136 case mode::ALL_THREADS
:
138 intrusive_list
<inferior
>::iterator
inf_iter (m_inf
);
139 intrusive_list
<thread_info
>::iterator thr_iter
140 = m_inf
->thread_list
.iterator_to (*m_thr
);
142 /* The loop below is written in the natural way as-if we'd always
143 start at the beginning of the inferior list. This fast forwards
144 the algorithm to the actual current position. */
147 for (; inf_iter
!= inferior_list
.end (); ++inf_iter
)
151 if (!m_inf_matches ())
154 thr_iter
= m_inf
->thread_list
.begin ();
155 while (thr_iter
!= m_inf
->thread_list
.end ())
168 case mode::ALL_THREADS_OF_INFERIOR
:
170 intrusive_list
<thread_info
>::iterator thr_iter
171 = m_inf
->thread_list
.iterator_to (*m_thr
);
173 if (thr_iter
!= m_inf
->thread_list
.end ())
180 case mode::SINGLE_THREAD
:
185 gdb_assert_not_reached ("invalid mode value");