]>
Commit | Line | Data |
---|---|---|
282aa4f7 TT |
1 | /* Self tests for parallel_for_each |
2 | ||
1d506c26 | 3 | Copyright (C) 2021-2024 Free Software Foundation, Inc. |
282aa4f7 TT |
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 | ||
728d5439 TV |
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 | ||
282aa4f7 TT |
27 | #include "defs.h" |
28 | #include "gdbsupport/selftest.h" | |
29 | #include "gdbsupport/parallel-for.h" | |
282aa4f7 TT |
30 | |
31 | #if CXX_STD_THREAD | |
32 | ||
828a9ed9 TT |
33 | #include "gdbsupport/thread-pool.h" |
34 | ||
282aa4f7 TT |
35 | namespace selftests { |
36 | namespace parallel_for { | |
37 | ||
38 | struct 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 | ||
728d5439 TV |
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 | |
56 | #include "parallel-for-selftests.c" | |
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 | |
63 | #include "parallel-for-selftests.c" | |
64 | #undef FOR_EACH | |
65 | #undef TEST | |
66 | ||
282aa4f7 TT |
67 | static void |
68 | test (int n_threads) | |
728d5439 TV |
69 | { |
70 | test_par (n_threads); | |
71 | test_seq (n_threads); | |
72 | } | |
73 | ||
74 | static void | |
75 | test_n_threads () | |
76 | { | |
77 | test (0); | |
78 | test (1); | |
79 | test (3); | |
80 | } | |
81 | ||
82 | } | |
83 | } | |
84 | ||
85 | #endif /* CXX_STD_THREAD */ | |
86 | ||
87 | void _initialize_parallel_for_selftests (); | |
88 | void | |
89 | _initialize_parallel_for_selftests () | |
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 | ||
99 | static void | |
100 | TEST (int n_threads) | |
282aa4f7 TT |
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 | ||
00894ecf | 107 | std::atomic<int> counter (0); |
728d5439 TV |
108 | FOR_EACH (1, 0, NUMBER, |
109 | [&] (int start, int end) | |
110 | { | |
111 | counter += end - start; | |
112 | }); | |
282aa4f7 TT |
113 | SELF_CHECK (counter == NUMBER); |
114 | ||
9083a323 | 115 | counter = 0; |
728d5439 TV |
116 | FOR_EACH (1, 0, 0, |
117 | [&] (int start, int end) | |
118 | { | |
119 | counter += end - start; | |
120 | }); | |
9083a323 TV |
121 | SELF_CHECK (counter == 0); |
122 | ||
282aa4f7 | 123 | #undef NUMBER |
63078a04 TT |
124 | |
125 | /* Check that if there are fewer tasks than threads, then we won't | |
126 | end up with a null result. */ | |
127 | std::vector<std::unique_ptr<int>> intresults; | |
128 | std::atomic<bool> any_empty_tasks (false); | |
129 | ||
130 | FOR_EACH (1, 0, 1, | |
131 | [&] (int start, int end) | |
132 | { | |
133 | if (start == end) | |
134 | any_empty_tasks = true; | |
6b62451a | 135 | return std::make_unique<int> (end - start); |
63078a04 TT |
136 | }); |
137 | SELF_CHECK (!any_empty_tasks); | |
138 | SELF_CHECK (std::all_of (intresults.begin (), | |
139 | intresults.end (), | |
140 | [] (const std::unique_ptr<int> &entry) | |
141 | { | |
142 | return entry != nullptr; | |
143 | })); | |
282aa4f7 TT |
144 | } |
145 | ||
728d5439 | 146 | #endif /* FOR_EACH */ |