GDB (xrefs)
Loading...
Searching...
No Matches
parallel-for-selftests.c
Go to the documentation of this file.
1/* Self tests for parallel_for_each
2
3 Copyright (C) 2021-2023 Free Software Foundation, Inc.
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/* This file is divided in two parts:
21 - FOR_EACH-undefined, and
22 - FOR_EACH-defined.
23 The former includes the latter, more than once, with different values for
24 FOR_EACH. The FOR_EACH-defined part reads like a regular function. */
25#ifndef FOR_EACH
26
27#include "defs.h"
28#include "gdbsupport/selftest.h"
29#include "gdbsupport/parallel-for.h"
30
31#if CXX_STD_THREAD
32
33#include "gdbsupport/thread-pool.h"
34
35namespace selftests {
36namespace parallel_for {
37
38struct save_restore_n_threads
39{
40 save_restore_n_threads ()
41 : n_threads (gdb::thread_pool::g_thread_pool->thread_count ())
42 {
43 }
44
45 ~save_restore_n_threads ()
46 {
47 gdb::thread_pool::g_thread_pool->set_thread_count (n_threads);
48 }
49
50 int n_threads;
51};
52
53/* Define test_par using TEST in the FOR_EACH-defined part. */
54#define TEST test_par
55#define FOR_EACH gdb::parallel_for_each
57#undef FOR_EACH
58#undef TEST
59
60/* Define test_seq using TEST in the FOR_EACH-defined part. */
61#define TEST test_seq
62#define FOR_EACH gdb::sequential_for_each
64#undef FOR_EACH
65#undef TEST
66
67static void
68test (int n_threads)
69{
70 test_par (n_threads);
71 test_seq (n_threads);
72}
73
74static void
75test_n_threads ()
76{
77 test (0);
78 test (1);
79 test (3);
80}
81
82}
83}
84
85#endif /* CXX_STD_THREAD */
86
88void
90{
91#ifdef CXX_STD_THREAD
92 selftests::register_test ("parallel_for",
93 selftests::parallel_for::test_n_threads);
94#endif /* CXX_STD_THREAD */
95}
96
97#else /* FOR_EACH */
98
99static void
100TEST (int n_threads)
101{
102 save_restore_n_threads saver;
103 gdb::thread_pool::g_thread_pool->set_thread_count (n_threads);
104
105#define NUMBER 10000
106
107 std::atomic<int> counter (0);
108 FOR_EACH (1, 0, NUMBER,
109 [&] (int start, int end)
110 {
111 counter += end - start;
112 });
113 SELF_CHECK (counter == NUMBER);
114
115 counter = 0;
116 FOR_EACH (1, 0, 0,
117 [&] (int start, int end)
118 {
119 counter += end - start;
120 });
121 SELF_CHECK (counter == 0);
122
123 auto task_size_max_ = [] (int iter)
124 {
125 return (size_t)SIZE_MAX;
126 };
127 auto task_size_max = gdb::make_function_view (task_size_max_);
128
129 counter = 0;
130 FOR_EACH (1, 0, NUMBER,
131 [&] (int start, int end)
132 {
133 counter += end - start;
134 }, task_size_max);
135 SELF_CHECK (counter == NUMBER);
136
137 auto task_size_one_ = [] (int iter)
138 {
139 return (size_t)1;
140 };
141 auto task_size_one = gdb::make_function_view (task_size_one_);
142
143 counter = 0;
144 FOR_EACH (1, 0, NUMBER,
145 [&] (int start, int end)
146 {
147 counter += end - start;
148 }, task_size_one);
149 SELF_CHECK (counter == NUMBER);
150
151#undef NUMBER
152
153 /* Check that if there are fewer tasks than threads, then we won't
154 end up with a null result. */
155 std::vector<std::unique_ptr<int>> intresults;
156 std::atomic<bool> any_empty_tasks (false);
157
158 FOR_EACH (1, 0, 1,
159 [&] (int start, int end)
160 {
161 if (start == end)
162 any_empty_tasks = true;
163 return gdb::make_unique<int> (end - start);
164 });
165 SELF_CHECK (!any_empty_tasks);
166 SELF_CHECK (std::all_of (intresults.begin (),
167 intresults.end (),
168 [] (const std::unique_ptr<int> &entry)
169 {
170 return entry != nullptr;
171 }));
172
173 /* The same but using the task size parameter. */
174 intresults.clear ();
175 any_empty_tasks = false;
176 FOR_EACH (1, 0, 1,
177 [&] (int start, int end)
178 {
179 if (start == end)
180 any_empty_tasks = true;
181 return gdb::make_unique<int> (end - start);
182 },
183 task_size_one);
184 SELF_CHECK (!any_empty_tasks);
185 SELF_CHECK (std::all_of (intresults.begin (),
186 intresults.end (),
187 [] (const std::unique_ptr<int> &entry)
188 {
189 return entry != nullptr;
190 }));
191}
192
193#endif /* FOR_EACH */
#define SIZE_MAX
Definition ada-lex.c:87
int thread_count(process_stratum_target *proc_target)
Definition thread.c:605
void _initialize_parallel_for_selftests()