blob: 29b4bbe37be23d7bf5d02a741d66672bed950105 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* pthread_getattr_np test.
2 Copyright (C) 2003, 2004 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Jakub Jelinek <jakub@redhat.com>, 2003.
5
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
10
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public
17 License along with the GNU C Library; if not, write to the Free
18 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
19 02111-1307 USA. */
20
21#include <errno.h>
22#include <error.h>
23#include <pthread.h>
24#include <stdio.h>
25#include <stdlib.h>
26#include <string.h>
27#include <unistd.h>
28
29static void *
30tf (void *arg)
31{
32 pthread_attr_t a, *ap, a2;
33 int err;
34 void *result = NULL;
35
36 if (arg == NULL)
37 {
38 ap = &a2;
39 err = pthread_attr_init (ap);
40 if (err)
41 {
42 error (0, err, "pthread_attr_init failed");
43 return tf;
44 }
45 }
46 else
47 ap = (pthread_attr_t *) arg;
48
49 err = pthread_getattr_np (pthread_self (), &a);
50 if (err)
51 {
52 error (0, err, "pthread_getattr_np failed");
53 result = tf;
54 }
55
56 int detachstate1, detachstate2;
57 err = pthread_attr_getdetachstate (&a, &detachstate1);
58 if (err)
59 {
60 error (0, err, "pthread_attr_getdetachstate failed");
61 result = tf;
62 }
63 else
64 {
65 err = pthread_attr_getdetachstate (ap, &detachstate2);
66 if (err)
67 {
68 error (0, err, "pthread_attr_getdetachstate failed");
69 result = tf;
70 }
71 else if (detachstate1 != detachstate2)
72 {
73 error (0, 0, "detachstate differs %d != %d",
74 detachstate1, detachstate2);
75 result = tf;
76 }
77 }
78
79 void *stackaddr;
80 size_t stacksize;
81 err = pthread_attr_getstack (&a, &stackaddr, &stacksize);
82 if (err)
83 {
84 error (0, err, "pthread_attr_getstack failed");
85 result = tf;
86 }
87 else if ((void *) &a < stackaddr
88 || (void *) &a >= stackaddr + stacksize)
89 {
90 error (0, 0, "pthread_attr_getstack returned range does not cover thread's stack");
91 result = tf;
92 }
93 else
94 printf ("thread stack %p-%p (0x%zx)\n", stackaddr, stackaddr + stacksize,
95 stacksize);
96
97 size_t guardsize1, guardsize2;
98 err = pthread_attr_getguardsize (&a, &guardsize1);
99 if (err)
100 {
101 error (0, err, "pthread_attr_getguardsize failed");
102 result = tf;
103 }
104 else
105 {
106 err = pthread_attr_getguardsize (ap, &guardsize2);
107 if (err)
108 {
109 error (0, err, "pthread_attr_getguardsize failed");
110 result = tf;
111 }
112 else if (guardsize1 != guardsize2)
113 {
114 error (0, 0, "guardsize differs %zd != %zd",
115 guardsize1, guardsize2);
116 result = tf;
117 }
118 else
119 printf ("thread guardsize %zd\n", guardsize1);
120 }
121
122 int scope1, scope2;
123 err = pthread_attr_getscope (&a, &scope1);
124 if (err)
125 {
126 error (0, err, "pthread_attr_getscope failed");
127 result = tf;
128 }
129 else
130 {
131 err = pthread_attr_getscope (ap, &scope2);
132 if (err)
133 {
134 error (0, err, "pthread_attr_getscope failed");
135 result = tf;
136 }
137 else if (scope1 != scope2)
138 {
139 error (0, 0, "scope differs %d != %d",
140 scope1, scope2);
141 result = tf;
142 }
143 }
144
145 int inheritsched1, inheritsched2;
146 err = pthread_attr_getinheritsched (&a, &inheritsched1);
147 if (err)
148 {
149 error (0, err, "pthread_attr_getinheritsched failed");
150 result = tf;
151 }
152 else
153 {
154 err = pthread_attr_getinheritsched (ap, &inheritsched2);
155 if (err)
156 {
157 error (0, err, "pthread_attr_getinheritsched failed");
158 result = tf;
159 }
160 else if (inheritsched1 != inheritsched2)
161 {
162 error (0, 0, "inheritsched differs %d != %d",
163 inheritsched1, inheritsched2);
164 result = tf;
165 }
166 }
167
168 cpu_set_t c1, c2;
169 err = pthread_getaffinity_np (pthread_self (), sizeof (c1), &c1);
170 if (err == 0)
171 {
172 err = pthread_attr_getaffinity_np (&a, sizeof (c2), &c2);
173 if (err)
174 {
175 error (0, err, "pthread_attr_getaffinity_np failed");
176 result = tf;
177 }
178 else if (memcmp (&c1, &c2, sizeof (c1)))
179 {
180 error (0, 0, "pthread_attr_getaffinity_np returned different CPU mask than pthread_getattr_np");
181 result = tf;
182 }
183 }
184
185 err = pthread_attr_destroy (&a);
186 if (err)
187 {
188 error (0, err, "pthread_attr_destroy failed");
189 result = tf;
190 }
191
192 if (ap == &a2)
193 {
194 err = pthread_attr_destroy (ap);
195 if (err)
196 {
197 error (0, err, "pthread_attr_destroy failed");
198 result = tf;
199 }
200 }
201
202 return result;
203}
204
205
206static int
207do_test (void)
208{
209 int result = 0;
210 pthread_attr_t a;
211 cpu_set_t c1, c2;
212
213 int err = pthread_attr_init (&a);
214 if (err)
215 {
216 error (0, err, "pthread_attr_init failed");
217 result = 1;
218 }
219
220 err = pthread_attr_getaffinity_np (&a, sizeof (c1), &c1);
221 if (err && err != ENOSYS)
222 {
223 error (0, err, "pthread_attr_getaffinity_np failed");
224 result = 1;
225 }
226
227 err = pthread_attr_destroy (&a);
228 if (err)
229 {
230 error (0, err, "pthread_attr_destroy failed");
231 result = 1;
232 }
233
234 err = pthread_getattr_np (pthread_self (), &a);
235 if (err)
236 {
237 error (0, err, "pthread_getattr_np failed");
238 result = 1;
239 }
240
241 int detachstate;
242 err = pthread_attr_getdetachstate (&a, &detachstate);
243 if (err)
244 {
245 error (0, err, "pthread_attr_getdetachstate failed");
246 result = 1;
247 }
248 else if (detachstate != PTHREAD_CREATE_JOINABLE)
249 {
250 error (0, 0, "initial thread not joinable");
251 result = 1;
252 }
253
254 void *stackaddr;
255 size_t stacksize;
256 err = pthread_attr_getstack (&a, &stackaddr, &stacksize);
257 if (err)
258 {
259 error (0, err, "pthread_attr_getstack failed");
260 result = 1;
261 }
262 else if ((void *) &a < stackaddr
263 || (void *) &a >= stackaddr + stacksize)
264 {
265 error (0, 0, "pthread_attr_getstack returned range does not cover main's stack");
266 result = 1;
267 }
268 else
269 printf ("initial thread stack %p-%p (0x%zx)\n", stackaddr,
270 stackaddr + stacksize, stacksize);
271
272 size_t guardsize;
273 err = pthread_attr_getguardsize (&a, &guardsize);
274 if (err)
275 {
276 error (0, err, "pthread_attr_getguardsize failed");
277 result = 1;
278 }
279 else if (guardsize != 0)
280 {
281 error (0, 0, "pthread_attr_getguardsize returned %zd != 0",
282 guardsize);
283 result = 1;
284 }
285
286 int scope;
287 err = pthread_attr_getscope (&a, &scope);
288 if (err)
289 {
290 error (0, err, "pthread_attr_getscope failed");
291 result = 1;
292 }
293 else if (scope != PTHREAD_SCOPE_SYSTEM)
294 {
295 error (0, 0, "pthread_attr_getscope returned %d != PTHREAD_SCOPE_SYSTEM",
296 scope);
297 result = 1;
298 }
299
300 int inheritsched;
301 err = pthread_attr_getinheritsched (&a, &inheritsched);
302 if (err)
303 {
304 error (0, err, "pthread_attr_getinheritsched failed");
305 result = 1;
306 }
307 else if (inheritsched != PTHREAD_INHERIT_SCHED)
308 {
309 error (0, 0, "pthread_attr_getinheritsched returned %d != PTHREAD_INHERIT_SCHED",
310 inheritsched);
311 result = 1;
312 }
313
314 err = pthread_getaffinity_np (pthread_self (), sizeof (c1), &c1);
315 if (err == 0)
316 {
317 err = pthread_attr_getaffinity_np (&a, sizeof (c2), &c2);
318 if (err)
319 {
320 error (0, err, "pthread_attr_getaffinity_np failed");
321 result = 1;
322 }
323 else if (memcmp (&c1, &c2, sizeof (c1)))
324 {
325 error (0, 0, "pthread_attr_getaffinity_np returned different CPU mask than pthread_getattr_np");
326 result = 1;
327 }
328 }
329
330 err = pthread_attr_destroy (&a);
331 if (err)
332 {
333 error (0, err, "pthread_attr_destroy failed");
334 result = 1;
335 }
336
337 pthread_t th;
338 err = pthread_create (&th, NULL, tf, NULL);
339 if (err)
340 {
341 error (0, err, "pthread_create #1 failed");
342 result = 1;
343 }
344 else
345 {
346 void *ret;
347 err = pthread_join (th, &ret);
348 if (err)
349 {
350 error (0, err, "pthread_join #1 failed");
351 result = 1;
352 }
353 else if (ret != NULL)
354 result = 1;
355 }
356
357 err = pthread_attr_init (&a);
358 if (err)
359 {
360 error (0, err, "pthread_attr_init failed");
361 result = 1;
362 }
363
364 err = pthread_create (&th, &a, tf, &a);
365 if (err)
366 {
367 error (0, err, "pthread_create #2 failed");
368 result = 1;
369 }
370 else
371 {
372 void *ret;
373 err = pthread_join (th, &ret);
374 if (err)
375 {
376 error (0, err, "pthread_join #2 failed");
377 result = 1;
378 }
379 else if (ret != NULL)
380 result = 1;
381 }
382
383 err = pthread_attr_setguardsize (&a, 16 * sysconf (_SC_PAGESIZE));
384 if (err)
385 {
386 error (0, err, "pthread_attr_setguardsize failed");
387 result = 1;
388 }
389
390 err = pthread_create (&th, &a, tf, &a);
391 if (err)
392 {
393 error (0, err, "pthread_create #3 failed");
394 result = 1;
395 }
396 else
397 {
398 void *ret;
399 err = pthread_join (th, &ret);
400 if (err)
401 {
402 error (0, err, "pthread_join #3 failed");
403 result = 1;
404 }
405 else if (ret != NULL)
406 result = 1;
407 }
408
409 err = pthread_attr_destroy (&a);
410 if (err)
411 {
412 error (0, err, "pthread_attr_destroy failed");
413 result = 1;
414 }
415
416 return result;
417}
418
419#define TEST_FUNCTION do_test ()
420#include "../test-skeleton.c"