1 /* Copyright (C) 2002-2022 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3 
4    The GNU C Library is free software; you can redistribute it and/or
5    modify it under the terms of the GNU Lesser General Public
6    License as published by the Free Software Foundation; either
7    version 2.1 of the License, or (at your option) any later version.
8 
9    The GNU C Library is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Lesser General Public License for more details.
13 
14    You should have received a copy of the GNU Lesser General Public
15    License along with the GNU C Library; if not, see
16    <https://www.gnu.org/licenses/>.  */
17 
18 #include <limits.h>
19 #include <pthread.h>
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <sys/param.h>
23 #include <unistd.h>
24 
25 
26 static void *stack;
27 static size_t size;
28 
29 
30 static void *
tf(void * a)31 tf (void *a)
32 {
33   int result = 0;
34 
35   puts ("child start");
36 
37   pthread_attr_t attr;
38   if (pthread_getattr_np (pthread_self (), &attr) != 0)
39     {
40       puts ("getattr_np failed");
41       exit (1);
42     }
43 
44   size_t test_size;
45   void *test_stack;
46   if (pthread_attr_getstack (&attr, &test_stack, &test_size) != 0)
47     {
48       puts ("attr_getstack failed");
49       exit (1);
50     }
51 
52   if (test_size != size)
53     {
54       printf ("child: reported size differs: is %zu, expected %zu\n",
55 	      test_size, size);
56       result = 1;
57     }
58 
59   if (test_stack != stack)
60     {
61       printf ("child: reported stack address differs: is %p, expected %p\n",
62 	      test_stack, stack);
63       result = 1;
64     }
65 
66   puts ("child OK");
67 
68   return result ? (void *) 1l : NULL;
69 }
70 
71 
72 int
do_test(void)73 do_test (void)
74 {
75   int result = 0;
76 
77   size = 4 * getpagesize ();
78 #ifdef PTHREAD_STACK_MIN
79   size = MAX (size, PTHREAD_STACK_MIN);
80 #endif
81   if (posix_memalign (&stack, getpagesize (), size) != 0)
82     {
83       puts ("out of memory while allocating the stack memory");
84       exit (1);
85     }
86 
87   pthread_attr_t attr;
88   if (pthread_attr_init (&attr) != 0)
89     {
90       puts ("attr_init failed");
91       exit (1);
92     }
93 
94   puts ("attr_setstack");
95   if (pthread_attr_setstack (&attr, stack, size) != 0)
96     {
97       puts ("attr_setstack failed");
98       exit (1);
99     }
100 
101   size_t test_size;
102   void *test_stack;
103   puts ("attr_getstack");
104   if (pthread_attr_getstack (&attr, &test_stack, &test_size) != 0)
105     {
106       puts ("attr_getstack failed");
107       exit (1);
108     }
109 
110   if (test_size != size)
111     {
112       printf ("reported size differs: is %zu, expected %zu\n",
113 	      test_size, size);
114       result = 1;
115     }
116 
117   if (test_stack != stack)
118     {
119       printf ("reported stack address differs: is %p, expected %p\n",
120 	      test_stack, stack);
121       result = 1;
122     }
123 
124   puts ("create");
125 
126   pthread_t th;
127   if (pthread_create (&th, &attr, tf, NULL) != 0)
128     {
129       puts ("failed to create thread");
130       exit (1);
131     }
132 
133   void *status;
134   if (pthread_join (th, &status) != 0)
135     {
136       puts ("join failed");
137       exit (1);
138     }
139 
140   result |= status != NULL;
141 
142   return result;
143 }
144 
145 
146 #define TEST_FUNCTION do_test ()
147 #include "../test-skeleton.c"
148