1PTHREAD_GETATTR_NP(3) Linux Programmer's Manual PTHREAD_GETATTR_NP(3)
2
3
4
6 pthread_getattr_np - get attributes of created thread
7
9 #define _GNU_SOURCE /* See feature_test_macros(7) */
10 #include <pthread.h>
11
12 int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr);
13
14 Compile and link with -pthread.
15
17 The pthread_getattr_np() function initializes the thread attributes ob‐
18 ject referred to by attr so that it contains actual attribute values
19 describing the running thread thread.
20
21 The returned attribute values may differ from the corresponding attri‐
22 bute values passed in the attr object that was used to create the
23 thread using pthread_create(3). In particular, the following at‐
24 tributes may differ:
25
26 * the detach state, since a joinable thread may have detached itself
27 after creation;
28
29 * the stack size, which the implementation may align to a suitable
30 boundary.
31
32 * and the guard size, which the implementation may round upward to a
33 multiple of the page size, or ignore (i.e., treat as 0), if the ap‐
34 plication is allocating its own stack.
35
36 Furthermore, if the stack address attribute was not set in the thread
37 attributes object used to create the thread, then the returned thread
38 attributes object will report the actual stack address that the imple‐
39 mentation selected for the thread.
40
41 When the thread attributes object returned by pthread_getattr_np() is
42 no longer required, it should be destroyed using pthread_attr_de‐
43 stroy(3).
44
46 On success, this function returns 0; on error, it returns a nonzero er‐
47 ror number.
48
50 ENOMEM Insufficient memory.
51
52 In addition, if thread refers to the main thread, then
53 pthread_getattr_np() can fail because of errors from various underlying
54 calls: fopen(3), if /proc/self/maps can't be opened; and getrlimit(2),
55 if the RLIMIT_STACK resource limit is not supported.
56
58 This function is available in glibc since version 2.2.3.
59
61 For an explanation of the terms used in this section, see at‐
62 tributes(7).
63
64 ┌─────────────────────┬───────────────┬─────────┐
65 │Interface │ Attribute │ Value │
66 ├─────────────────────┼───────────────┼─────────┤
67 │pthread_getattr_np() │ Thread safety │ MT-Safe │
68 └─────────────────────┴───────────────┴─────────┘
70 This function is a nonstandard GNU extension; hence the suffix "_np"
71 (nonportable) in the name.
72
74 The program below demonstrates the use of pthread_getattr_np(). The
75 program creates a thread that then uses pthread_getattr_np() to re‐
76 trieve and display its guard size, stack address, and stack size at‐
77 tributes. Command-line arguments can be used to set these attributes
78 to values other than the default when creating the thread. The shell
79 sessions below demonstrate the use of the program.
80
81 In the first run, on an x86-32 system, a thread is created using de‐
82 fault attributes:
83
84 $ ulimit -s # No stack limit ==> default stack size is 2 MB
85 unlimited
86 $ ./a.out
87 Attributes of created thread:
88 Guard size = 4096 bytes
89 Stack address = 0x40196000 (EOS = 0x40397000)
90 Stack size = 0x201000 (2101248) bytes
91
92 In the following run, we see that if a guard size is specified, it is
93 rounded up to the next multiple of the system page size (4096 bytes on
94 x86-32):
95
96 $ ./a.out -g 4097
97 Thread attributes object after initializations:
98 Guard size = 4097 bytes
99 Stack address = (nil)
100 Stack size = 0x0 (0) bytes
101
102 Attributes of created thread:
103 Guard size = 8192 bytes
104 Stack address = 0x40196000 (EOS = 0x40397000)
105 Stack size = 0x201000 (2101248) bytes
106
107 In the last run, the program manually allocates a stack for the thread.
108 In this case, the guard size attribute is ignored.
109
110 $ ./a.out -g 4096 -s 0x8000 -a
111 Allocated thread stack at 0x804d000
112
113 Thread attributes object after initializations:
114 Guard size = 4096 bytes
115 Stack address = 0x804d000 (EOS = 0x8055000)
116 Stack size = 0x8000 (32768) bytes
117
118 Attributes of created thread:
119 Guard size = 0 bytes
120 Stack address = 0x804d000 (EOS = 0x8055000)
121 Stack size = 0x8000 (32768) bytes
122
123 Program source
124
125 #define _GNU_SOURCE /* To get pthread_getattr_np() declaration */
126 #include <pthread.h>
127 #include <stdio.h>
128 #include <stdlib.h>
129 #include <unistd.h>
130 #include <errno.h>
131
132 #define handle_error_en(en, msg) \
133 do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
134
135 static void
136 display_stack_related_attributes(pthread_attr_t *attr, char *prefix)
137 {
138 int s;
139 size_t stack_size, guard_size;
140 void *stack_addr;
141
142 s = pthread_attr_getguardsize(attr, &guard_size);
143 if (s != 0)
144 handle_error_en(s, "pthread_attr_getguardsize");
145 printf("%sGuard size = %zu bytes\n", prefix, guard_size);
146
147 s = pthread_attr_getstack(attr, &stack_addr, &stack_size);
148 if (s != 0)
149 handle_error_en(s, "pthread_attr_getstack");
150 printf("%sStack address = %p", prefix, stack_addr);
151 if (stack_size > 0)
152 printf(" (EOS = %p)", (char *) stack_addr + stack_size);
153 printf("\n");
154 printf("%sStack size = %#zx (%zu) bytes\n",
155 prefix, stack_size, stack_size);
156 }
157
158 static void
159 display_thread_attributes(pthread_t thread, char *prefix)
160 {
161 int s;
162 pthread_attr_t attr;
163
164 s = pthread_getattr_np(thread, &attr);
165 if (s != 0)
166 handle_error_en(s, "pthread_getattr_np");
167
168 display_stack_related_attributes(&attr, prefix);
169
170 s = pthread_attr_destroy(&attr);
171 if (s != 0)
172 handle_error_en(s, "pthread_attr_destroy");
173 }
174
175 static void * /* Start function for thread we create */
176 thread_start(void *arg)
177 {
178 printf("Attributes of created thread:\n");
179 display_thread_attributes(pthread_self(), "\t");
180
181 exit(EXIT_SUCCESS); /* Terminate all threads */
182 }
183
184 static void
185 usage(char *pname, char *msg)
186 {
187 if (msg != NULL)
188 fputs(msg, stderr);
189 fprintf(stderr, "Usage: %s [-s stack-size [-a]]"
190 " [-g guard-size]\n", pname);
191 fprintf(stderr, "\t\t-a means program should allocate stack\n");
192 exit(EXIT_FAILURE);
193 }
194
195 static pthread_attr_t * /* Get thread attributes from command line */
196 get_thread_attributes_from_cl(int argc, char *argv[],
197 pthread_attr_t *attrp)
198 {
199 int s, opt, allocate_stack;
200 size_t stack_size, guard_size;
201 void *stack_addr;
202 pthread_attr_t *ret_attrp = NULL; /* Set to attrp if we initialize
203 a thread attributes object */
204 allocate_stack = 0;
205 stack_size = -1;
206 guard_size = -1;
207
208 while ((opt = getopt(argc, argv, "ag:s:")) != -1) {
209 switch (opt) {
210 case 'a': allocate_stack = 1; break;
211 case 'g': guard_size = strtoul(optarg, NULL, 0); break;
212 case 's': stack_size = strtoul(optarg, NULL, 0); break;
213 default: usage(argv[0], NULL);
214 }
215 }
216
217 if (allocate_stack && stack_size == -1)
218 usage(argv[0], "Specifying -a without -s makes no sense\n");
219
220 if (argc > optind)
221 usage(argv[0], "Extraneous command-line arguments\n");
222
223 if (stack_size >= 0 || guard_size > 0) {
224 ret_attrp = attrp;
225
226 s = pthread_attr_init(attrp);
227 if (s != 0)
228 handle_error_en(s, "pthread_attr_init");
229 }
230
231 if (stack_size >= 0) {
232 if (!allocate_stack) {
233 s = pthread_attr_setstacksize(attrp, stack_size);
234 if (s != 0)
235 handle_error_en(s, "pthread_attr_setstacksize");
236 } else {
237 s = posix_memalign(&stack_addr, sysconf(_SC_PAGESIZE),
238 stack_size);
239 if (s != 0)
240 handle_error_en(s, "posix_memalign");
241 printf("Allocated thread stack at %p\n\n", stack_addr);
242
243 s = pthread_attr_setstack(attrp, stack_addr, stack_size);
244 if (s != 0)
245 handle_error_en(s, "pthread_attr_setstacksize");
246 }
247 }
248
249 if (guard_size >= 0) {
250 s = pthread_attr_setguardsize(attrp, guard_size);
251 if (s != 0)
252 handle_error_en(s, "pthread_attr_setstacksize");
253 }
254
255 return ret_attrp;
256 }
257
258 int
259 main(int argc, char *argv[])
260 {
261 int s;
262 pthread_t thr;
263 pthread_attr_t attr;
264 pthread_attr_t *attrp = NULL; /* Set to &attr if we initialize
265 a thread attributes object */
266
267 attrp = get_thread_attributes_from_cl(argc, argv, &attr);
268
269 if (attrp != NULL) {
270 printf("Thread attributes object after initializations:\n");
271 display_stack_related_attributes(attrp, "\t");
272 printf("\n");
273 }
274
275 s = pthread_create(&thr, attrp, &thread_start, NULL);
276 if (s != 0)
277 handle_error_en(s, "pthread_create");
278
279 if (attrp != NULL) {
280 s = pthread_attr_destroy(attrp);
281 if (s != 0)
282 handle_error_en(s, "pthread_attr_destroy");
283 }
284
285 pause(); /* Terminates when other thread calls exit() */
286 }
287
289 pthread_attr_getaffinity_np(3), pthread_attr_getdetachstate(3),
290 pthread_attr_getguardsize(3), pthread_attr_getinheritsched(3),
291 pthread_attr_getschedparam(3), pthread_attr_getschedpolicy(3),
292 pthread_attr_getscope(3), pthread_attr_getstack(3),
293 pthread_attr_getstackaddr(3), pthread_attr_getstacksize(3),
294 pthread_attr_init(3), pthread_create(3), pthreads(7)
295
297 This page is part of release 5.10 of the Linux man-pages project. A
298 description of the project, information about reporting bugs, and the
299 latest version of this page, can be found at
300 https://www.kernel.org/doc/man-pages/.
301
302
303
304Linux 2020-11-01 PTHREAD_GETATTR_NP(3)