1 /* Generic test case for CPU affinity functions.
2 Copyright (C) 2015-2017 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 /* This file is included by the tst-affinity*.c files to test the two
20 variants of the functions, under different conditions. The
21 following functions have to be definied:
23 static int getaffinity (size_t, cpu_set_t *);
24 static int setaffinity (size_t, const cpu_set_t *);
25 static bool early_test (struct conf *);
27 The first two functions shall affect the affinity mask for the
28 current thread and return 0 for success, -1 for error (with an
31 early_test is invoked before the tests in this file affect the
32 affinity masks. If it returns true, testing continues, otherwise
33 no more tests run and the overall test exits with status 1.
42 /* CPU set configuration determined. Can be used from early_test. */
45 int set_size
; /* in bits */
52 /* There is considerable controversy about how to determine the size
53 of the kernel CPU mask. The probing loop below is only intended
54 for testing purposes. */
55 for (int num_cpus
= 64; num_cpus
<= INT_MAX
/ 2; ++num_cpus
)
57 cpu_set_t
*set
= CPU_ALLOC (num_cpus
);
58 size_t size
= CPU_ALLOC_SIZE (num_cpus
);
62 printf ("error: CPU_ALLOC (%d) failed\n", num_cpus
);
65 if (getaffinity (size
, set
) == 0)
72 printf ("error: getaffinity for %d CPUs: %m\n", num_cpus
);
78 puts ("error: Cannot find maximum CPU number");
83 find_last_cpu (const cpu_set_t
*set
, size_t size
)
85 /* We need to determine the set size with CPU_COUNT_S and the
86 cpus_found counter because there is no direct way to obtain the
87 actual CPU set size, in bits, from the value of
89 size_t cpus_found
= 0;
90 size_t total_cpus
= CPU_COUNT_S (size
, set
);
93 for (int cpu
= 0; cpus_found
< total_cpus
; ++cpu
)
95 if (CPU_ISSET_S (cpu
, size
, set
))
105 setup_conf (struct conf
*conf
)
107 *conf
= (struct conf
) {-1, -1};
108 conf
->set_size
= find_set_size ();
109 if (conf
->set_size
> 0)
111 cpu_set_t
*set
= CPU_ALLOC (conf
->set_size
);
115 printf ("error: CPU_ALLOC (%d) failed\n", conf
->set_size
);
119 if (getaffinity (CPU_ALLOC_SIZE (conf
->set_size
), set
) < 0)
121 printf ("error: getaffinity failed: %m\n");
125 conf
->last_cpu
= find_last_cpu (set
, CPU_ALLOC_SIZE (conf
->set_size
));
126 if (conf
->last_cpu
< 0)
127 puts ("info: No test CPU found");
133 test_size (const struct conf
*conf
, size_t size
)
135 if (size
< conf
->set_size
)
137 printf ("info: Test not run for CPU set size %zu\n", size
);
141 cpu_set_t
*initial_set
= CPU_ALLOC (size
);
142 cpu_set_t
*set2
= CPU_ALLOC (size
);
143 cpu_set_t
*active_cpu_set
= CPU_ALLOC (size
);
145 if (initial_set
== NULL
|| set2
== NULL
|| active_cpu_set
== NULL
)
147 printf ("error: size %zu: CPU_ALLOC failed\n", size
);
150 size_t kernel_size
= CPU_ALLOC_SIZE (size
);
152 if (getaffinity (kernel_size
, initial_set
) < 0)
154 printf ("error: size %zu: getaffinity: %m\n", size
);
157 if (setaffinity (kernel_size
, initial_set
) < 0)
159 printf ("error: size %zu: setaffinity: %m\n", size
);
163 /* Use one-CPU set to test switching between CPUs. */
164 int last_active_cpu
= -1;
165 for (int cpu
= 0; cpu
<= conf
->last_cpu
; ++cpu
)
167 int active_cpu
= sched_getcpu ();
168 if (last_active_cpu
>= 0 && last_active_cpu
!= active_cpu
)
170 printf ("error: Unexpected CPU %d, expected %d\n",
171 active_cpu
, last_active_cpu
);
175 if (!CPU_ISSET_S (cpu
, kernel_size
, initial_set
))
177 last_active_cpu
= cpu
;
179 CPU_ZERO_S (kernel_size
, active_cpu_set
);
180 CPU_SET_S (cpu
, kernel_size
, active_cpu_set
);
181 if (setaffinity (kernel_size
, active_cpu_set
) < 0)
183 printf ("error: size %zu: setaffinity (%d): %m\n", size
, cpu
);
186 active_cpu
= sched_getcpu ();
187 if (active_cpu
!= cpu
)
189 printf ("error: Unexpected CPU %d, expected %d\n", active_cpu
, cpu
);
192 if (getaffinity (kernel_size
, set2
) < 0)
194 printf ("error: size %zu: getaffinity (2): %m\n", size
);
197 if (!CPU_EQUAL_S (kernel_size
, active_cpu_set
, set2
))
199 printf ("error: size %zu: CPU sets do not match\n", size
);
204 /* Test setting the all-ones set. */
205 for (int cpu
= 0; cpu
< size
; ++cpu
)
206 CPU_SET_S (cpu
, kernel_size
, set2
);
207 if (setaffinity (kernel_size
, set2
) < 0)
209 printf ("error: size %zu: setaffinity (3): %m\n", size
);
213 if (setaffinity (kernel_size
, initial_set
) < 0)
215 printf ("error: size %zu: setaffinity (4): %m\n", size
);
218 if (getaffinity (kernel_size
, set2
) < 0)
220 printf ("error: size %zu: getaffinity (3): %m\n", size
);
223 if (!CPU_EQUAL_S (kernel_size
, initial_set
, set2
))
225 printf ("error: size %zu: CPU sets do not match (2)\n", size
);
229 CPU_FREE (initial_set
);
231 CPU_FREE (active_cpu_set
);
241 if (getaffinity (sizeof (set
), &set
) < 0 && errno
== ENOSYS
)
243 puts ("warning: getaffinity not supported, test cannot run");
246 if (sched_getcpu () < 0 && errno
== ENOSYS
)
248 puts ("warning: sched_getcpu not supported, test cannot run");
255 printf ("info: Detected CPU set size (in bits): %d\n", conf
.set_size
);
256 printf ("info: Maximum test CPU: %d\n", conf
.last_cpu
);
257 if (conf
.set_size
< 0 || conf
.last_cpu
< 0)
260 if (!early_test (&conf
))
264 error
|= !test_size (&conf
, 1024);
265 error
|= !test_size (&conf
, conf
.set_size
);
266 error
|= !test_size (&conf
, 2);
267 error
|= !test_size (&conf
, 32);
268 error
|= !test_size (&conf
, 40);
269 error
|= !test_size (&conf
, 64);
270 error
|= !test_size (&conf
, 96);
271 error
|= !test_size (&conf
, 128);
272 error
|= !test_size (&conf
, 256);
273 error
|= !test_size (&conf
, 8192);
277 #define TEST_FUNCTION do_test ()
278 #include "../test-skeleton.c"