]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - gdb/unittests/parallel-for-selftests.c
Update copyright year range in header of all files managed by GDB
[thirdparty/binutils-gdb.git] / gdb / unittests / parallel-for-selftests.c
1 /* Self tests for parallel_for_each
2
3 Copyright (C) 2021-2024 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
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
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
67 static void
68 test (int n_threads)
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)
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 #undef NUMBER
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;
135 return std::make_unique<int> (end - start);
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 }));
144 }
145
146 #endif /* FOR_EACH */