1 .\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk
2 .\" <mtk.manpages@gmail.com>
4 .\" Permission is granted to make and distribute verbatim copies of this
5 .\" manual provided the copyright notice and this permission notice are
6 .\" preserved on all copies.
8 .\" Permission is granted to copy and distribute modified versions of this
9 .\" manual under the conditions for verbatim copying, provided that the
10 .\" entire resulting derived work is distributed under the terms of a
11 .\" permission notice identical to this one.
13 .\" Since the Linux kernel and libraries are constantly changing, this
14 .\" manual page may be incorrect or out-of-date. The author(s) assume no
15 .\" responsibility for errors or omissions, or for damages resulting from
16 .\" the use of the information contained herein. The author(s) may not
17 .\" have taken the same level of care in the production of this manual,
18 .\" which is licensed free of charge, as they might when working
21 .\" Formatted or processed versions of this manual, if unaccompanied by
22 .\" the source, must acknowledge the copyright and authors of this work.
24 .TH PTHREAD_GETATTR_NP 3 2010-09-10 "Linux" "Linux Programmer's Manual"
26 pthread_getattr_np \- get attributes of created thread
29 .BR "#define _GNU_SOURCE" " /* See feature_test_macros(7) */"
30 .B #include <pthread.h>
32 .BI "int pthread_getattr_np(pthread_t " thread ", pthread_attr_t *" attr );
34 Compile and link with \fI\-pthread\fP.
37 .BR pthread_getattr_np ()
38 function initializes the thread attributes object referred to by
40 so that it contains actual attribute values describing the running thread
43 The returned attribute values may differ from
44 the corresponding attribute values passed in the
46 object that was used to create the thread using
47 .BR pthread_create (3).
48 In particular, the following attributes may differ:
50 the detach state, since a joinable thread may have detached itself
54 which the implementation may align to a suitable boundary.
57 which the implementation may round upward to a multiple of the page size,
58 or ignore (i.e., treat as 0),
59 if the application is allocating its own stack.
61 Furthermore, if the stack address attribute was not set
62 in the thread attributes object used to create the thread,
63 then the returned thread attributes object will report the actual
64 stack address that the implementation selected for the thread.
66 When the thread attributes object returned by
67 .BR pthread_getattr_np ()
68 is no longer required, it should be destroyed using
69 .BR pthread_attr_destroy (3).
71 On success, this function returns 0;
72 on error, it returns a nonzero error number.
76 .\" Can happen (but unlikely) while trying to allocate memory for cpuset
81 refers to the main thread, then
82 .BR pthread_getattr_np ()
83 can fail because of errors from various underlying calls:
92 resource limit is not supported.
94 This function is available in glibc since version 2.2.3.
96 This function is a nonstandard GNU extension;
97 hence the suffix "_np" (nonportable) in the name.
99 The program below demonstrates the use of
100 .BR pthread_getattr_np ().
101 The program creates a thread that then uses
102 .BR pthread_getattr_np ()
103 to retrieve and display its guard size, stack address,
104 and stack size attributes.
105 Command-line arguments can be used to set these attributes
106 to values other than the default when creating the thread.
107 The shell sessions below demonstrate the use of the program.
109 In the first run, on an x86-32 system,
110 a thread is created using default attributes:
114 .RB "$" " ulimit \-s" " # No stack limit ==> default stack size is 2MB"
117 Attributes of created thread:
118 Guard size = 4096 bytes
119 Stack address = 0x40196000 (EOS = 0x40397000)
120 Stack size = 0x201000 (2101248) bytes
124 In the following run, we see that if a guard size is specified,
125 it is rounded up to the next multiple of the system page size
126 (4096 bytes on x86-32):
130 .RB "$" " ./a.out \-g 4097"
131 Thread attributes object after initializations:
132 Guard size = 4097 bytes
133 Stack address = (nil)
134 Stack size = 0x0 (0) bytes
136 Attributes of created thread:
137 Guard size = 8192 bytes
138 Stack address = 0x40196000 (EOS = 0x40397000)
139 Stack size = 0x201000 (2101248) bytes
144 .\"$ ./a.out \-s 0x8000
145 .\"Thread attributes object after initializations:
146 .\" Guard size = 4096 bytes
147 .\" Stack address = 0xffff8000 (EOS = (nil))
148 .\" Stack size = 0x8000 (32768) bytes
150 .\"Attributes of created thread:
151 .\" Guard size = 4096 bytes
152 .\" Stack address = 0x4001e000 (EOS = 0x40026000)
153 .\" Stack size = 0x8000 (32768) bytes
157 In the last run, the program manually allocates a stack for the thread.
158 In this case, the guard size attribute is ignored.
162 .RB "$" " ./a.out \-g 4096 \-s 0x8000 \-a"
163 Allocated thread stack at 0x804d000
165 Thread attributes object after initializations:
166 Guard size = 4096 bytes
167 Stack address = 0x804d000 (EOS = 0x8055000)
168 Stack size = 0x8000 (32768) bytes
170 Attributes of created thread:
172 Stack address = 0x804d000 (EOS = 0x8055000)
173 Stack size = 0x8000 (32768) bytes
179 #define _GNU_SOURCE /* To get pthread_getattr_np() declaration */
186 #define handle_error_en(en, msg) \\
187 do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
190 display_stack_related_attributes(pthread_attr_t *attr, char *prefix)
193 size_t stack_size, guard_size;
196 s = pthread_attr_getguardsize(attr, &guard_size);
198 handle_error_en(s, "pthread_attr_getguardsize");
199 printf("%sGuard size = %d bytes\\n", prefix, guard_size);
201 s = pthread_attr_getstack(attr, &stack_addr, &stack_size);
203 handle_error_en(s, "pthread_attr_getstack");
204 printf("%sStack address = %p", prefix, stack_addr);
206 printf(" (EOS = %p)", (char *) stack_addr + stack_size);
208 printf("%sStack size = 0x%x (%d) bytes\\n",
209 prefix, stack_size, stack_size);
213 display_thread_attributes(pthread_t thread, char *prefix)
218 s = pthread_getattr_np(thread, &attr);
220 handle_error_en(s, "pthread_getattr_np");
222 display_stack_related_attributes(&attr, prefix);
224 s = pthread_attr_destroy(&attr);
226 handle_error_en(s, "pthread_attr_destroy");
229 static void * /* Start function for thread we create */
230 thread_start(void *arg)
232 printf("Attributes of created thread:\\n");
233 display_thread_attributes(pthread_self(), "\\t");
235 exit(EXIT_SUCCESS); /* Terminate all threads */
239 usage(char *pname, char *msg)
243 fprintf(stderr, "Usage: %s [\-s stack-size [\-a]]"
244 " [\-g guard-size]\\n", pname);
245 fprintf(stderr, "\\t\\t\-a means program should allocate stack\\n");
249 static pthread_attr_t * /* Get thread attributes from command line */
250 get_thread_attributes_from_cl(int argc, char *argv[],
251 pthread_attr_t *attrp)
253 int s, opt, allocate_stack;
254 long stack_size, guard_size;
256 pthread_attr_t *ret_attrp = NULL; /* Set to attrp if we initialize
257 a thread attributes object */
262 while ((opt = getopt(argc, argv, "ag:s:")) != \-1) {
264 case \(aqa\(aq: allocate_stack = 1; break;
265 case \(aqg\(aq: guard_size = strtoul(optarg, NULL, 0); break;
266 case \(aqs\(aq: stack_size = strtoul(optarg, NULL, 0); break;
267 default: usage(argv[0], NULL);
271 if (allocate_stack && stack_size == \-1)
272 usage(argv[0], "Specifying \-a without \-s makes no sense\\n");
275 usage(argv[0], "Extraneous command\-line arguments\\n");
277 if (stack_size >= 0 || guard_size > 0) {
280 s = pthread_attr_init(attrp);
282 handle_error_en(s, "pthread_attr_init");
285 if (stack_size >= 0) {
286 if (!allocate_stack) {
287 s = pthread_attr_setstacksize(attrp, stack_size);
289 handle_error_en(s, "pthread_attr_setstacksize");
291 s = posix_memalign(&stack_addr, sysconf(_SC_PAGESIZE),
294 handle_error_en(s, "posix_memalign");
295 printf("Allocated thread stack at %p\\n\\n", stack_addr);
297 s = pthread_attr_setstack(attrp, stack_addr, stack_size);
299 handle_error_en(s, "pthread_attr_setstacksize");
303 if (guard_size >= 0) {
304 s = pthread_attr_setguardsize(attrp, guard_size);
306 handle_error_en(s, "pthread_attr_setstacksize");
313 main(int argc, char *argv[])
318 pthread_attr_t *attrp = NULL; /* Set to &attr if we initialize
319 a thread attributes object */
321 attrp = get_thread_attributes_from_cl(argc, argv, &attr);
324 printf("Thread attributes object after initializations:\\n");
325 display_stack_related_attributes(attrp, "\\t");
329 s = pthread_create(&thr, attrp, &thread_start, NULL);
331 handle_error_en(s, "pthread_create");
334 s = pthread_attr_destroy(attrp);
336 handle_error_en(s, "pthread_attr_destroy");
339 pause(); /* Terminates when other thread calls exit() */
343 .BR pthread_attr_getaffinity_np (3),
344 .BR pthread_attr_getdetachstate (3),
345 .BR pthread_attr_getguardsize (3),
346 .BR pthread_attr_getinheritsched (3),
347 .BR pthread_attr_getschedparam (3),
348 .BR pthread_attr_getschedpolicy (3),
349 .BR pthread_attr_getscope (3),
350 .BR pthread_attr_getstack (3),
351 .BR pthread_attr_getstackaddr (3),
352 .BR pthread_attr_getstacksize (3),
353 .BR pthread_attr_init (3),
354 .BR pthread_create (3),