]>
Commit | Line | Data |
---|---|---|
a1eaacb1 | 1 | '\" t |
4f37d29c MK |
2 | .\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk |
3 | .\" <mtk.manpages@gmail.com> | |
4 | .\" | |
5fbde956 | 5 | .\" SPDX-License-Identifier: Linux-man-pages-copyleft |
4f37d29c | 6 | .\" |
4c1c5274 | 7 | .TH pthread_getattr_np 3 (date) "Linux man-pages (unreleased)" |
4f37d29c MK |
8 | .SH NAME |
9 | pthread_getattr_np \- get attributes of created thread | |
41295a69 AC |
10 | .SH LIBRARY |
11 | POSIX threads library | |
8fc3b2cf | 12 | .RI ( libpthread ", " \-lpthread ) |
4f37d29c MK |
13 | .SH SYNOPSIS |
14 | .nf | |
86b91fdf | 15 | .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */" |
4f37d29c | 16 | .B #include <pthread.h> |
f90f031e | 17 | .PP |
4f37d29c | 18 | .BI "int pthread_getattr_np(pthread_t " thread ", pthread_attr_t *" attr ); |
6030f2d8 | 19 | .fi |
4f37d29c MK |
20 | .SH DESCRIPTION |
21 | The | |
22 | .BR pthread_getattr_np () | |
23 | function initializes the thread attributes object referred to by | |
24 | .I attr | |
25 | so that it contains actual attribute values describing the running thread | |
26 | .IR thread . | |
847e0d88 | 27 | .PP |
4f37d29c MK |
28 | The returned attribute values may differ from |
29 | the corresponding attribute values passed in the | |
30 | .I attr | |
31 | object that was used to create the thread using | |
32 | .BR pthread_create (3). | |
33 | In particular, the following attributes may differ: | |
cdede5cd | 34 | .IP \[bu] 3 |
4f37d29c MK |
35 | the detach state, since a joinable thread may have detached itself |
36 | after creation; | |
cdede5cd | 37 | .IP \[bu] |
4f37d29c MK |
38 | the stack size, |
39 | which the implementation may align to a suitable boundary. | |
cdede5cd | 40 | .IP \[bu] |
4f37d29c | 41 | and the guard size, |
5fab2e7c | 42 | which the implementation may round upward to a multiple of the page size, |
4f37d29c MK |
43 | or ignore (i.e., treat as 0), |
44 | if the application is allocating its own stack. | |
45 | .PP | |
46 | Furthermore, if the stack address attribute was not set | |
47 | in the thread attributes object used to create the thread, | |
48 | then the returned thread attributes object will report the actual | |
49 | stack address that the implementation selected for the thread. | |
847e0d88 | 50 | .PP |
4f37d29c MK |
51 | When the thread attributes object returned by |
52 | .BR pthread_getattr_np () | |
53 | is no longer required, it should be destroyed using | |
54 | .BR pthread_attr_destroy (3). | |
55 | .SH RETURN VALUE | |
56 | On success, this function returns 0; | |
c7094399 | 57 | on error, it returns a nonzero error number. |
4f37d29c MK |
58 | .SH ERRORS |
59 | .TP | |
60 | .B ENOMEM | |
61 | .\" Can happen (but unlikely) while trying to allocate memory for cpuset | |
62 | Insufficient memory. | |
63 | .PP | |
64 | In addition, if | |
65 | .I thread | |
66 | refers to the main thread, then | |
67 | .BR pthread_getattr_np () | |
222d90f4 | 68 | can fail because of errors from various underlying calls: |
4f37d29c MK |
69 | .BR fopen (3), |
70 | if | |
1ae6b2c7 | 71 | .I /proc/self/maps |
4f37d29c MK |
72 | can't be opened; |
73 | and | |
74 | .BR getrlimit (2), | |
75 | if the | |
1ae6b2c7 | 76 | .B RLIMIT_STACK |
4f37d29c | 77 | resource limit is not supported. |
5effafa2 ZL |
78 | .SH ATTRIBUTES |
79 | For an explanation of the terms used in this section, see | |
80 | .BR attributes (7). | |
81 | .TS | |
82 | allbox; | |
c466875e | 83 | lbx lb lb |
5effafa2 ZL |
84 | l l l. |
85 | Interface Attribute Value | |
86 | T{ | |
9e54434e BR |
87 | .na |
88 | .nh | |
5effafa2 ZL |
89 | .BR pthread_getattr_np () |
90 | T} Thread safety MT-Safe | |
91 | .TE | |
3113c7f3 | 92 | .SH STANDARDS |
4131356c | 93 | GNU; |
d603cc27 | 94 | hence the suffix "_np" (nonportable) in the name. |
4131356c AC |
95 | .SH HISTORY |
96 | glibc 2.2.3. | |
a14af333 | 97 | .SH EXAMPLES |
4f37d29c MK |
98 | The program below demonstrates the use of |
99 | .BR pthread_getattr_np (). | |
100 | The program creates a thread that then uses | |
101 | .BR pthread_getattr_np () | |
102 | to retrieve and display its guard size, stack address, | |
103 | and stack size attributes. | |
104 | Command-line arguments can be used to set these attributes | |
105 | to values other than the default when creating the thread. | |
106 | The shell sessions below demonstrate the use of the program. | |
847e0d88 | 107 | .PP |
4f37d29c MK |
108 | In the first run, on an x86-32 system, |
109 | a thread is created using default attributes: | |
847e0d88 | 110 | .PP |
4f37d29c | 111 | .in +4n |
b8302363 | 112 | .EX |
ee8655b5 | 113 | .RB "$" " ulimit \-s" " # No stack limit ==> default stack size is 2 MB" |
4f37d29c | 114 | unlimited |
b43a3b30 | 115 | .RB "$" " ./a.out" |
4f37d29c MK |
116 | Attributes of created thread: |
117 | Guard size = 4096 bytes | |
118 | Stack address = 0x40196000 (EOS = 0x40397000) | |
119 | Stack size = 0x201000 (2101248) bytes | |
b8302363 | 120 | .EE |
4f37d29c | 121 | .in |
847e0d88 | 122 | .PP |
4f37d29c MK |
123 | In the following run, we see that if a guard size is specified, |
124 | it is rounded up to the next multiple of the system page size | |
125 | (4096 bytes on x86-32): | |
847e0d88 | 126 | .PP |
4f37d29c | 127 | .in +4n |
b8302363 | 128 | .EX |
b43a3b30 | 129 | .RB "$" " ./a.out \-g 4097" |
4f37d29c MK |
130 | Thread attributes object after initializations: |
131 | Guard size = 4097 bytes | |
132 | Stack address = (nil) | |
133 | Stack size = 0x0 (0) bytes | |
fe5dba13 | 134 | \& |
4f37d29c MK |
135 | Attributes of created thread: |
136 | Guard size = 8192 bytes | |
137 | Stack address = 0x40196000 (EOS = 0x40397000) | |
138 | Stack size = 0x201000 (2101248) bytes | |
b8302363 | 139 | .EE |
4f37d29c MK |
140 | .in |
141 | .\".in +4n | |
142 | .\".nf | |
143 | .\"$ ./a.out \-s 0x8000 | |
144 | .\"Thread attributes object after initializations: | |
145 | .\" Guard size = 4096 bytes | |
146 | .\" Stack address = 0xffff8000 (EOS = (nil)) | |
147 | .\" Stack size = 0x8000 (32768) bytes | |
148 | .\" | |
149 | .\"Attributes of created thread: | |
150 | .\" Guard size = 4096 bytes | |
151 | .\" Stack address = 0x4001e000 (EOS = 0x40026000) | |
152 | .\" Stack size = 0x8000 (32768) bytes | |
153 | .\".fi | |
154 | .\".in | |
847e0d88 | 155 | .PP |
4f37d29c MK |
156 | In the last run, the program manually allocates a stack for the thread. |
157 | In this case, the guard size attribute is ignored. | |
847e0d88 | 158 | .PP |
4f37d29c | 159 | .in +4n |
b8302363 | 160 | .EX |
b43a3b30 | 161 | .RB "$" " ./a.out \-g 4096 \-s 0x8000 \-a" |
4f37d29c | 162 | Allocated thread stack at 0x804d000 |
fe5dba13 | 163 | \& |
4f37d29c MK |
164 | Thread attributes object after initializations: |
165 | Guard size = 4096 bytes | |
166 | Stack address = 0x804d000 (EOS = 0x8055000) | |
167 | Stack size = 0x8000 (32768) bytes | |
fe5dba13 | 168 | \& |
4f37d29c MK |
169 | Attributes of created thread: |
170 | Guard size = 0 bytes | |
171 | Stack address = 0x804d000 (EOS = 0x8055000) | |
172 | Stack size = 0x8000 (32768) bytes | |
b8302363 | 173 | .EE |
4f37d29c | 174 | .in |
9c330504 | 175 | .SS Program source |
d84d0300 | 176 | \& |
b0b6ab4e | 177 | .\" SRC BEGIN (pthread_getattr_np.c) |
e7d0bb47 | 178 | .EX |
4f37d29c | 179 | #define _GNU_SOURCE /* To get pthread_getattr_np() declaration */ |
5a5208c1 | 180 | #include <err.h> |
ad3868f0 | 181 | #include <errno.h> |
4f37d29c MK |
182 | #include <pthread.h> |
183 | #include <stdio.h> | |
184 | #include <stdlib.h> | |
185 | #include <unistd.h> | |
fe5dba13 | 186 | \& |
4f37d29c MK |
187 | static void |
188 | display_stack_related_attributes(pthread_attr_t *attr, char *prefix) | |
189 | { | |
190 | int s; | |
191 | size_t stack_size, guard_size; | |
192 | void *stack_addr; | |
fe5dba13 | 193 | \& |
4f37d29c MK |
194 | s = pthread_attr_getguardsize(attr, &guard_size); |
195 | if (s != 0) | |
5a5208c1 | 196 | errc(EXIT_FAILURE, s, "pthread_attr_getguardsize"); |
037c6fd4 | 197 | printf("%sGuard size = %zu bytes\en", prefix, guard_size); |
fe5dba13 | 198 | \& |
4f37d29c MK |
199 | s = pthread_attr_getstack(attr, &stack_addr, &stack_size); |
200 | if (s != 0) | |
5a5208c1 | 201 | errc(EXIT_FAILURE, s, "pthread_attr_getstack"); |
4f37d29c MK |
202 | printf("%sStack address = %p", prefix, stack_addr); |
203 | if (stack_size > 0) | |
204 | printf(" (EOS = %p)", (char *) stack_addr + stack_size); | |
d1a71985 | 205 | printf("\en"); |
dc97703b | 206 | printf("%sStack size = %#zx (%zu) bytes\en", |
d917c31d | 207 | prefix, stack_size, stack_size); |
4f37d29c | 208 | } |
fe5dba13 | 209 | \& |
4f37d29c MK |
210 | static void |
211 | display_thread_attributes(pthread_t thread, char *prefix) | |
212 | { | |
213 | int s; | |
214 | pthread_attr_t attr; | |
fe5dba13 | 215 | \& |
4f37d29c MK |
216 | s = pthread_getattr_np(thread, &attr); |
217 | if (s != 0) | |
5a5208c1 | 218 | errc(EXIT_FAILURE, s, "pthread_getattr_np"); |
fe5dba13 | 219 | \& |
4f37d29c | 220 | display_stack_related_attributes(&attr, prefix); |
fe5dba13 | 221 | \& |
4f37d29c MK |
222 | s = pthread_attr_destroy(&attr); |
223 | if (s != 0) | |
5a5208c1 | 224 | errc(EXIT_FAILURE, s, "pthread_attr_destroy"); |
4f37d29c | 225 | } |
fe5dba13 | 226 | \& |
4f37d29c MK |
227 | static void * /* Start function for thread we create */ |
228 | thread_start(void *arg) | |
229 | { | |
d1a71985 MK |
230 | printf("Attributes of created thread:\en"); |
231 | display_thread_attributes(pthread_self(), "\et"); | |
fe5dba13 | 232 | \& |
4f37d29c MK |
233 | exit(EXIT_SUCCESS); /* Terminate all threads */ |
234 | } | |
fe5dba13 | 235 | \& |
4f37d29c MK |
236 | static void |
237 | usage(char *pname, char *msg) | |
238 | { | |
239 | if (msg != NULL) | |
240 | fputs(msg, stderr); | |
72da9ef1 | 241 | fprintf(stderr, "Usage: %s [\-s stack\-size [\-a]]" |
d1a71985 MK |
242 | " [\-g guard\-size]\en", pname); |
243 | fprintf(stderr, "\et\et\-a means program should allocate stack\en"); | |
4f37d29c MK |
244 | exit(EXIT_FAILURE); |
245 | } | |
fe5dba13 | 246 | \& |
4f37d29c MK |
247 | static pthread_attr_t * /* Get thread attributes from command line */ |
248 | get_thread_attributes_from_cl(int argc, char *argv[], | |
249 | pthread_attr_t *attrp) | |
250 | { | |
251 | int s, opt, allocate_stack; | |
7d974613 | 252 | size_t stack_size, guard_size; |
404990ae | 253 | void *stack_addr; |
4f37d29c MK |
254 | pthread_attr_t *ret_attrp = NULL; /* Set to attrp if we initialize |
255 | a thread attributes object */ | |
256 | allocate_stack = 0; | |
257 | stack_size = \-1; | |
258 | guard_size = \-1; | |
fe5dba13 | 259 | \& |
4f37d29c MK |
260 | while ((opt = getopt(argc, argv, "ag:s:")) != \-1) { |
261 | switch (opt) { | |
b957f81f AC |
262 | case \[aq]a\[aq]: allocate_stack = 1; break; |
263 | case \[aq]g\[aq]: guard_size = strtoul(optarg, NULL, 0); break; | |
264 | case \[aq]s\[aq]: stack_size = strtoul(optarg, NULL, 0); break; | |
4f37d29c MK |
265 | default: usage(argv[0], NULL); |
266 | } | |
267 | } | |
fe5dba13 | 268 | \& |
4f37d29c | 269 | if (allocate_stack && stack_size == \-1) |
d1a71985 | 270 | usage(argv[0], "Specifying \-a without \-s makes no sense\en"); |
fe5dba13 | 271 | \& |
4f37d29c | 272 | if (argc > optind) |
d1a71985 | 273 | usage(argv[0], "Extraneous command\-line arguments\en"); |
fe5dba13 | 274 | \& |
eb76bbe5 | 275 | if (stack_size != -1 || guard_size > 0) { |
4f37d29c | 276 | ret_attrp = attrp; |
fe5dba13 | 277 | \& |
4f37d29c MK |
278 | s = pthread_attr_init(attrp); |
279 | if (s != 0) | |
5a5208c1 | 280 | errc(EXIT_FAILURE, s, "pthread_attr_init"); |
4f37d29c | 281 | } |
fe5dba13 | 282 | \& |
eb76bbe5 | 283 | if (stack_size != -1) { |
4f37d29c MK |
284 | if (!allocate_stack) { |
285 | s = pthread_attr_setstacksize(attrp, stack_size); | |
286 | if (s != 0) | |
5a5208c1 | 287 | errc(EXIT_FAILURE, s, "pthread_attr_setstacksize"); |
4f37d29c MK |
288 | } else { |
289 | s = posix_memalign(&stack_addr, sysconf(_SC_PAGESIZE), | |
290 | stack_size); | |
291 | if (s != 0) | |
5a5208c1 | 292 | errc(EXIT_FAILURE, s, "posix_memalign"); |
d1a71985 | 293 | printf("Allocated thread stack at %p\en\en", stack_addr); |
fe5dba13 | 294 | \& |
4f37d29c MK |
295 | s = pthread_attr_setstack(attrp, stack_addr, stack_size); |
296 | if (s != 0) | |
5a5208c1 | 297 | errc(EXIT_FAILURE, s, "pthread_attr_setstacksize"); |
4f37d29c MK |
298 | } |
299 | } | |
fe5dba13 | 300 | \& |
eb76bbe5 | 301 | if (guard_size != -1) { |
4f37d29c MK |
302 | s = pthread_attr_setguardsize(attrp, guard_size); |
303 | if (s != 0) | |
5a5208c1 | 304 | errc(EXIT_FAILURE, s, "pthread_attr_setstacksize"); |
4f37d29c | 305 | } |
fe5dba13 | 306 | \& |
4f37d29c MK |
307 | return ret_attrp; |
308 | } | |
fe5dba13 | 309 | \& |
4f37d29c MK |
310 | int |
311 | main(int argc, char *argv[]) | |
312 | { | |
313 | int s; | |
314 | pthread_t thr; | |
315 | pthread_attr_t attr; | |
316 | pthread_attr_t *attrp = NULL; /* Set to &attr if we initialize | |
317 | a thread attributes object */ | |
fe5dba13 | 318 | \& |
4f37d29c | 319 | attrp = get_thread_attributes_from_cl(argc, argv, &attr); |
fe5dba13 | 320 | \& |
4f37d29c | 321 | if (attrp != NULL) { |
d1a71985 MK |
322 | printf("Thread attributes object after initializations:\en"); |
323 | display_stack_related_attributes(attrp, "\et"); | |
324 | printf("\en"); | |
4f37d29c | 325 | } |
fe5dba13 | 326 | \& |
4f37d29c MK |
327 | s = pthread_create(&thr, attrp, &thread_start, NULL); |
328 | if (s != 0) | |
5a5208c1 | 329 | errc(EXIT_FAILURE, s, "pthread_create"); |
fe5dba13 | 330 | \& |
4f37d29c MK |
331 | if (attrp != NULL) { |
332 | s = pthread_attr_destroy(attrp); | |
333 | if (s != 0) | |
5a5208c1 | 334 | errc(EXIT_FAILURE, s, "pthread_attr_destroy"); |
4f37d29c | 335 | } |
fe5dba13 | 336 | \& |
4f37d29c MK |
337 | pause(); /* Terminates when other thread calls exit() */ |
338 | } | |
e7d0bb47 | 339 | .EE |
b0b6ab4e | 340 | .\" SRC END |
4f37d29c | 341 | .SH SEE ALSO |
ca8a0bd2 MK |
342 | .ad l |
343 | .nh | |
4f37d29c MK |
344 | .BR pthread_attr_getaffinity_np (3), |
345 | .BR pthread_attr_getdetachstate (3), | |
346 | .BR pthread_attr_getguardsize (3), | |
347 | .BR pthread_attr_getinheritsched (3), | |
348 | .BR pthread_attr_getschedparam (3), | |
349 | .BR pthread_attr_getschedpolicy (3), | |
350 | .BR pthread_attr_getscope (3), | |
351 | .BR pthread_attr_getstack (3), | |
352 | .BR pthread_attr_getstackaddr (3), | |
353 | .BR pthread_attr_getstacksize (3), | |
354 | .BR pthread_attr_init (3), | |
355 | .BR pthread_create (3), | |
356 | .BR pthreads (7) |