]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/thread-iter.c
Automatic Copyright Year update after running gdb/copyright.py
[thirdparty/binutils-gdb.git] / gdb / thread-iter.c
CommitLineData
08036331
PA
1/* Thread iterators and ranges for GDB, the GNU debugger.
2
4a94e368 3 Copyright (C) 2018-2022 Free Software Foundation, Inc.
08036331
PA
4
5 This file is part of GDB.
6
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.
11
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.
16
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/>. */
19
20#include "defs.h"
21#include "gdbthread.h"
22#include "inferior.h"
23
24/* See thread-iter.h. */
25
26all_threads_iterator::all_threads_iterator (begin_t)
27{
28 /* Advance M_INF/M_THR to the first thread's position. */
08bdefb5
PA
29
30 for (inferior &inf : inferior_list)
bf809310 31 {
08bdefb5
PA
32 auto thr_iter = inf.thread_list.begin ();
33 if (thr_iter != inf.thread_list.end ())
bf809310 34 {
08bdefb5 35 m_inf = &inf;
bf809310
PA
36 m_thr = &*thr_iter;
37 return;
38 }
39 }
08bdefb5 40 m_inf = nullptr;
bf809310 41 m_thr = nullptr;
08036331
PA
42}
43
44/* See thread-iter.h. */
45
46void
47all_threads_iterator::advance ()
48{
08bdefb5 49 intrusive_list<inferior>::iterator inf_iter (m_inf);
bf809310
PA
50 intrusive_list<thread_info>::iterator thr_iter (m_thr);
51
08036331
PA
52 /* The loop below is written in the natural way as-if we'd always
53 start at the beginning of the inferior list. This fast forwards
54 the algorithm to the actual current position. */
55 goto start;
56
08bdefb5 57 for (; inf_iter != inferior_list.end (); ++inf_iter)
08036331 58 {
08bdefb5 59 m_inf = &*inf_iter;
bf809310
PA
60 thr_iter = m_inf->thread_list.begin ();
61 while (thr_iter != m_inf->thread_list.end ())
08036331 62 {
bf809310 63 m_thr = &*thr_iter;
08036331
PA
64 return;
65 start:
bf809310 66 ++thr_iter;
08036331
PA
67 }
68 }
bf809310
PA
69
70 m_thr = nullptr;
08036331
PA
71}
72
73/* See thread-iter.h. */
74
75bool
76all_matching_threads_iterator::m_inf_matches ()
77{
0618ae41
SM
78 return (m_filter_target == nullptr
79 || m_filter_target == m_inf->process_target ());
08036331
PA
80}
81
82/* See thread-iter.h. */
83
84all_matching_threads_iterator::all_matching_threads_iterator
5b6d1e4f 85 (process_stratum_target *filter_target, ptid_t filter_ptid)
0618ae41 86 : m_filter_target (filter_target)
08036331 87{
0618ae41 88 if (filter_ptid == minus_one_ptid)
08bdefb5 89 {
0618ae41
SM
90 /* Iterate on all threads of all inferiors, possibly filtering on
91 FILTER_TARGET. */
92 m_mode = mode::ALL_THREADS;
93
94 /* Seek the first thread of the first matching inferior. */
95 for (inferior &inf : inferior_list)
96 {
97 m_inf = &inf;
98
99 if (!m_inf_matches ()
100 || inf.thread_list.empty ())
101 continue;
102
103 m_thr = &inf.thread_list.front ();
104 return;
105 }
08bdefb5 106 }
0618ae41
SM
107 else
108 {
109 gdb_assert (filter_target != nullptr);
bf809310 110
0618ae41
SM
111 if (filter_ptid.is_pid ())
112 {
113 /* Iterate on all threads of the given inferior. */
114 m_mode = mode::ALL_THREADS_OF_INFERIOR;
115
116 m_inf = find_inferior_pid (filter_target, filter_ptid.pid ());
117 if (m_inf != nullptr)
118 m_thr = &m_inf->thread_list.front ();
119 }
120 else
121 {
122 /* Iterate on a single thread. */
123 m_mode = mode::SINGLE_THREAD;
124
125 m_thr = find_thread_ptid (filter_target, filter_ptid);
126 }
127 }
08036331
PA
128}
129
130/* See thread-iter.h. */
131
132void
133all_matching_threads_iterator::advance ()
134{
0618ae41
SM
135 switch (m_mode)
136 {
137 case mode::ALL_THREADS:
138 {
139 intrusive_list<inferior>::iterator inf_iter (m_inf);
140 intrusive_list<thread_info>::iterator thr_iter
141 = m_inf->thread_list.iterator_to (*m_thr);
142
143 /* The loop below is written in the natural way as-if we'd always
144 start at the beginning of the inferior list. This fast forwards
145 the algorithm to the actual current position. */
146 goto start;
147
148 for (; inf_iter != inferior_list.end (); ++inf_iter)
149 {
150 m_inf = &*inf_iter;
bf809310 151
0618ae41
SM
152 if (!m_inf_matches ())
153 continue;
08036331 154
0618ae41
SM
155 thr_iter = m_inf->thread_list.begin ();
156 while (thr_iter != m_inf->thread_list.end ())
157 {
158 m_thr = &*thr_iter;
159 return;
bf809310 160
0618ae41
SM
161 start:
162 ++thr_iter;
163 }
164 }
165 }
166 m_thr = nullptr;
167 break;
168
169 case mode::ALL_THREADS_OF_INFERIOR:
170 {
171 intrusive_list<thread_info>::iterator thr_iter
172 = m_inf->thread_list.iterator_to (*m_thr);
173 ++thr_iter;
174 if (thr_iter != m_inf->thread_list.end ())
175 m_thr = &*thr_iter;
176 else
177 m_thr = nullptr;
178 break;
179 }
180
181 case mode::SINGLE_THREAD:
182 m_thr = nullptr;
183 break;
184
185 default:
186 gdb_assert_not_reached ("invalid mode value");
187 }
08036331 188}