Refer to C23 in place of C2X in glibc
[glibc.git] / nptl / tst-attr3.c
blob498b4f5cf9e4dcb0d2de2147b21ca93f42e3d375
1 /* pthread_getattr_np test.
2 Copyright (C) 2003-2024 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 <https://www.gnu.org/licenses/>. */
19 #include <errno.h>
20 #include <error.h>
21 #include <pthread.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
27 #include <stackinfo.h>
28 #include <libc-diag.h>
30 static void *
31 tf (void *arg)
33 pthread_attr_t a, *ap, a2;
34 int err;
35 void *result = NULL;
37 if (arg == NULL)
39 ap = &a2;
40 err = pthread_attr_init (ap);
41 if (err)
43 error (0, err, "pthread_attr_init failed");
44 return tf;
47 else
48 ap = (pthread_attr_t *) arg;
50 err = pthread_getattr_np (pthread_self (), &a);
51 if (err)
53 error (0, err, "pthread_getattr_np failed");
54 result = tf;
57 int detachstate1, detachstate2;
58 err = pthread_attr_getdetachstate (&a, &detachstate1);
59 if (err)
61 error (0, err, "pthread_attr_getdetachstate failed");
62 result = tf;
64 else
66 err = pthread_attr_getdetachstate (ap, &detachstate2);
67 if (err)
69 error (0, err, "pthread_attr_getdetachstate failed");
70 result = tf;
72 else if (detachstate1 != detachstate2)
74 error (0, 0, "detachstate differs %d != %d",
75 detachstate1, detachstate2);
76 result = tf;
80 void *stackaddr;
81 size_t stacksize;
82 err = pthread_attr_getstack (&a, &stackaddr, &stacksize);
83 if (err)
85 error (0, err, "pthread_attr_getstack failed");
86 result = tf;
88 else if ((void *) &a < stackaddr
89 || (void *) &a >= stackaddr + stacksize)
91 error (0, 0, "pthread_attr_getstack returned range does not cover thread's stack");
92 result = tf;
94 else
95 printf ("thread stack %p-%p (0x%zx)\n", stackaddr, stackaddr + stacksize,
96 stacksize);
98 size_t guardsize1, guardsize2;
99 err = pthread_attr_getguardsize (&a, &guardsize1);
100 if (err)
102 error (0, err, "pthread_attr_getguardsize failed");
103 result = tf;
105 else
107 err = pthread_attr_getguardsize (ap, &guardsize2);
108 if (err)
110 error (0, err, "pthread_attr_getguardsize failed");
111 result = tf;
113 else if (guardsize1 != guardsize2)
115 error (0, 0, "guardsize differs %zd != %zd",
116 guardsize1, guardsize2);
117 result = tf;
119 else
120 printf ("thread guardsize %zd\n", guardsize1);
123 int scope1, scope2;
124 err = pthread_attr_getscope (&a, &scope1);
125 if (err)
127 error (0, err, "pthread_attr_getscope failed");
128 result = tf;
130 else
132 err = pthread_attr_getscope (ap, &scope2);
133 if (err)
135 error (0, err, "pthread_attr_getscope failed");
136 result = tf;
138 else if (scope1 != scope2)
140 error (0, 0, "scope differs %d != %d",
141 scope1, scope2);
142 result = tf;
146 int inheritsched1, inheritsched2;
147 err = pthread_attr_getinheritsched (&a, &inheritsched1);
148 if (err)
150 error (0, err, "pthread_attr_getinheritsched failed");
151 result = tf;
153 else
155 err = pthread_attr_getinheritsched (ap, &inheritsched2);
156 if (err)
158 error (0, err, "pthread_attr_getinheritsched failed");
159 result = tf;
161 else if (inheritsched1 != inheritsched2)
163 error (0, 0, "inheritsched differs %d != %d",
164 inheritsched1, inheritsched2);
165 result = tf;
169 cpu_set_t c1, c2;
170 err = pthread_getaffinity_np (pthread_self (), sizeof (c1), &c1);
171 if (err == 0)
173 err = pthread_attr_getaffinity_np (&a, sizeof (c2), &c2);
174 if (err)
176 error (0, err, "pthread_attr_getaffinity_np failed");
177 result = tf;
179 else if (memcmp (&c1, &c2, sizeof (c1)))
181 error (0, 0, "pthread_attr_getaffinity_np returned different CPU mask than pthread_getattr_np");
182 result = tf;
186 err = pthread_attr_destroy (&a);
187 if (err)
189 error (0, err, "pthread_attr_destroy failed");
190 result = tf;
193 if (ap == &a2)
195 err = pthread_attr_destroy (ap);
196 if (err)
198 error (0, err, "pthread_attr_destroy failed");
199 result = tf;
203 return result;
207 static int
208 do_test (void)
210 int result = 0;
211 pthread_attr_t a;
212 cpu_set_t c1, c2;
214 int err = pthread_attr_init (&a);
215 if (err)
217 error (0, err, "pthread_attr_init failed");
218 result = 1;
221 err = pthread_attr_getaffinity_np (&a, sizeof (c1), &c1);
222 if (err && err != ENOSYS)
224 error (0, err, "pthread_attr_getaffinity_np failed");
225 result = 1;
228 err = pthread_attr_destroy (&a);
229 if (err)
231 error (0, err, "pthread_attr_destroy failed");
232 result = 1;
235 err = pthread_getattr_np (pthread_self (), &a);
236 if (err)
238 error (0, err, "pthread_getattr_np failed");
239 result = 1;
242 int detachstate;
243 err = pthread_attr_getdetachstate (&a, &detachstate);
244 if (err)
246 error (0, err, "pthread_attr_getdetachstate failed");
247 result = 1;
249 else if (detachstate != PTHREAD_CREATE_JOINABLE)
251 error (0, 0, "initial thread not joinable");
252 result = 1;
255 void *stackaddr;
256 size_t stacksize;
257 err = pthread_attr_getstack (&a, &stackaddr, &stacksize);
258 if (err)
260 error (0, err, "pthread_attr_getstack failed");
261 result = 1;
263 else if ((void *) &a < stackaddr
264 || (void *) &a >= stackaddr + stacksize)
266 error (0, 0, "pthread_attr_getstack returned range does not cover main's stack");
267 result = 1;
269 else
270 printf ("initial thread stack %p-%p (0x%zx)\n", stackaddr,
271 stackaddr + stacksize, stacksize);
273 size_t guardsize;
274 err = pthread_attr_getguardsize (&a, &guardsize);
275 if (err)
277 error (0, err, "pthread_attr_getguardsize failed");
278 result = 1;
280 else if (guardsize != 0)
282 error (0, 0, "pthread_attr_getguardsize returned %zd != 0",
283 guardsize);
284 result = 1;
287 int scope;
288 err = pthread_attr_getscope (&a, &scope);
289 if (err)
291 error (0, err, "pthread_attr_getscope failed");
292 result = 1;
294 else if (scope != PTHREAD_SCOPE_SYSTEM)
296 error (0, 0, "pthread_attr_getscope returned %d != PTHREAD_SCOPE_SYSTEM",
297 scope);
298 result = 1;
301 int inheritsched;
302 err = pthread_attr_getinheritsched (&a, &inheritsched);
303 if (err)
305 error (0, err, "pthread_attr_getinheritsched failed");
306 result = 1;
308 else if (inheritsched != PTHREAD_INHERIT_SCHED)
310 error (0, 0, "pthread_attr_getinheritsched returned %d != PTHREAD_INHERIT_SCHED",
311 inheritsched);
312 result = 1;
315 err = pthread_getaffinity_np (pthread_self (), sizeof (c1), &c1);
316 if (err == 0)
318 err = pthread_attr_getaffinity_np (&a, sizeof (c2), &c2);
319 if (err)
321 error (0, err, "pthread_attr_getaffinity_np failed");
322 result = 1;
324 else if (memcmp (&c1, &c2, sizeof (c1)))
326 error (0, 0, "pthread_attr_getaffinity_np returned different CPU mask than pthread_getattr_np");
327 result = 1;
331 err = pthread_attr_destroy (&a);
332 if (err)
334 error (0, err, "pthread_attr_destroy failed");
335 result = 1;
338 pthread_t th;
339 err = pthread_create (&th, NULL, tf, NULL);
340 if (err)
342 error (0, err, "pthread_create #1 failed");
343 result = 1;
345 else
347 void *ret;
348 err = pthread_join (th, &ret);
349 if (err)
351 error (0, err, "pthread_join #1 failed");
352 result = 1;
354 else if (ret != NULL)
355 result = 1;
358 err = pthread_attr_init (&a);
359 if (err)
361 error (0, err, "pthread_attr_init failed");
362 result = 1;
365 DIAG_PUSH_NEEDS_COMMENT;
366 #if __GNUC_PREREQ (7, 0)
367 /* GCC 8 warns about aliasing of the restrict-qualified arguments
368 passed &a. Since pthread_create does not dereference its fourth
369 argument, this aliasing, which is deliberate in this test, cannot
370 in fact cause problems. */
371 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wrestrict");
372 #endif
373 err = pthread_create (&th, &a, tf, &a);
374 DIAG_POP_NEEDS_COMMENT;
375 if (err)
377 error (0, err, "pthread_create #2 failed");
378 result = 1;
380 else
382 void *ret;
383 err = pthread_join (th, &ret);
384 if (err)
386 error (0, err, "pthread_join #2 failed");
387 result = 1;
389 else if (ret != NULL)
390 result = 1;
393 err = pthread_attr_setguardsize (&a, 16 * sysconf (_SC_PAGESIZE));
394 if (err)
396 error (0, err, "pthread_attr_setguardsize failed");
397 result = 1;
400 DIAG_PUSH_NEEDS_COMMENT;
401 #if __GNUC_PREREQ (7, 0)
402 /* GCC 8 warns about aliasing of the restrict-qualified arguments
403 passed &a. Since pthread_create does not dereference its fourth
404 argument, this aliasing, which is deliberate in this test, cannot
405 in fact cause problems. */
406 DIAG_IGNORE_NEEDS_COMMENT (8, "-Wrestrict");
407 #endif
408 err = pthread_create (&th, &a, tf, &a);
409 DIAG_POP_NEEDS_COMMENT;
410 if (err)
412 error (0, err, "pthread_create #3 failed");
413 result = 1;
415 else
417 void *ret;
418 err = pthread_join (th, &ret);
419 if (err)
421 error (0, err, "pthread_join #3 failed");
422 result = 1;
424 else if (ret != NULL)
425 result = 1;
428 err = pthread_attr_destroy (&a);
429 if (err)
431 error (0, err, "pthread_attr_destroy failed");
432 result = 1;
435 return result;
438 #define TEST_FUNCTION do_test ()
439 #include "../test-skeleton.c"