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
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
18 object 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
22 attribute values passed in the attr object that was used to create the
23 thread using pthread_create(3). In particular, the following
24 attributes 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 upwards to a
33 multiple of the page size, or ignore (i.e., treat as 0), if the
34 application 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
43 pthread_attr_destroy(3).
44
46 On success, this function returns 0; on error, it returns a nonzero
47 error 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 This function is a nonstandard GNU extension. hence the suffix "_np"
62 (nonportable) in the name.
63
65 The program below demonstrates the use of pthread_getattr_np(). The
66 program creates a thread that then uses pthread_getattr_np() to
67 retrieve and display its guard size, stack address, and stack size
68 attributes. Command-line arguments can be used to set these attributes
69 to values other than the default when creating the thread. The shell
70 sessions below demonstrate the use of the program.
71
72 In the first run, on an x86-32 system, a thread is created using
73 default attributes:
74
75 $ ulimit -s # No stack limit ==> default stack size is 2MB
76 unlimited
77 $ ./a.out
78 Attributes of created thread:
79 Guard size = 4096 bytes
80 Stack address = 0x40196000 (EOS = 0x40397000)
81 Stack size = 0x201000 (2101248) bytes
82
83 In the following run, we see that if a guard size is specified, it is
84 rounded up to the next multiple of the system page size (4096 bytes on
85 x86-32):
86
87 $ ./a.out -g 4097
88 Thread attributes object after initializations:
89 Guard size = 4097 bytes
90 Stack address = (nil)
91 Stack size = 0x0 (0) bytes
92
93 Attributes of created thread:
94 Guard size = 8192 bytes
95 Stack address = 0x40196000 (EOS = 0x40397000)
96 Stack size = 0x201000 (2101248) bytes
97
98 In the last run, the program manually allocates a stack for the thread.
99 In this case, the guard size attribute is ignored.
100
101 $ ./a.out -g 4096 -s 0x8000 -a
102 Allocated thread stack at 0x804d000
103
104 Thread attributes object after initializations:
105 Guard size = 4096 bytes
106 Stack address = 0x804d000 (EOS = 0x8055000)
107 Stack size = 0x8000 (32768) bytes
108
109 Attributes of created thread:
110 Guard size = 0 bytes
111 Stack address = 0x804d000 (EOS = 0x8055000)
112 Stack size = 0x8000 (32768) bytes
113
114 Program source
115
116 #define _GNU_SOURCE /* To get pthread_getattr_np() declaration */
117 #include <pthread.h>
118 #include <stdio.h>
119 #include <stdlib.h>
120 #include <unistd.h>
121 #include <errno.h>
122
123 #define handle_error_en(en, msg) \
124 do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
125
126 static void
127 display_stack_related_attributes(pthread_attr_t *attr, char *prefix)
128 {
129 int s;
130 size_t stack_size, guard_size;
131 void *stack_addr;
132
133 s = pthread_attr_getguardsize(attr, &guard_size);
134 if (s != 0)
135 handle_error_en(s, "pthread_attr_getguardsize");
136 printf("%sGuard size = %d bytes\n", prefix, guard_size);
137
138 s = pthread_attr_getstack(attr, &stack_addr, &stack_size);
139 if (s != 0)
140 handle_error_en(s, "pthread_attr_getstack");
141 printf("%sStack address = %p", prefix, stack_addr);
142 if (stack_size > 0)
143 printf(" (EOS = %p)", (char *) stack_addr + stack_size);
144 printf("\n");
145 printf("%sStack size = 0x%x (%d) bytes\n",
146 prefix, stack_size, stack_size);
147 }
148
149 static void
150 display_thread_attributes(pthread_t thread, char *prefix)
151 {
152 int s;
153 pthread_attr_t attr;
154
155 s = pthread_getattr_np(thread, &attr);
156 if (s != 0)
157 handle_error_en(s, "pthread_getattr_np");
158
159 display_stack_related_attributes(&attr, prefix);
160
161 s = pthread_attr_destroy(&attr);
162 if (s != 0)
163 handle_error_en(s, "pthread_attr_destroy");
164 }
165
166 static void * /* Start function for thread we create */
167 thread_start(void *arg)
168 {
169 printf("Attributes of created thread:\n");
170 display_thread_attributes(pthread_self(), "\t");
171
172 exit(EXIT_SUCCESS); /* Terminate all threads */
173 }
174
175 static void
176 usage(char *pname, char *msg)
177 {
178 if (msg != NULL)
179 fputs(msg, stderr);
180 fprintf(stderr, "Usage: %s [-s stack-size [-a]]"
181 " [-g guard-size]\n", pname);
182 fprintf(stderr, "\t\t-a means program should allocate stack\n");
183 exit(EXIT_FAILURE);
184 }
185
186 static pthread_attr_t * /* Get thread attributes from command line */
187 get_thread_attributes_from_cl(int argc, char *argv[],
188 pthread_attr_t *attrp)
189 {
190 int s, opt, allocate_stack;
191 long stack_size, guard_size;
192 void *stack_addr;
193 pthread_attr_t *ret_attrp = NULL; /* Set to attrp if we initialize
194 a thread attributes object */
195 allocate_stack = 0;
196 stack_size = -1;
197 guard_size = -1;
198
199 while ((opt = getopt(argc, argv, "ag:s:")) != -1) {
200 switch (opt) {
201 case 'a': allocate_stack = 1; break;
202 case 'g': guard_size = strtoul(optarg, NULL, 0); break;
203 case 's': stack_size = strtoul(optarg, NULL, 0); break;
204 default: usage(argv[0], NULL);
205 }
206 }
207
208 if (allocate_stack && stack_size == -1)
209 usage(argv[0], "Specifying -a without -s makes no sense\n");
210
211 if (argc > optind)
212 usage(argv[0], "Extraneous command-line arguments\n");
213
214 if (stack_size >= 0 || guard_size > 0) {
215 ret_attrp = attrp;
216
217 s = pthread_attr_init(attrp);
218 if (s != 0)
219 handle_error_en(s, "pthread_attr_init");
220 }
221
222 if (stack_size >= 0) {
223 if (!allocate_stack) {
224 s = pthread_attr_setstacksize(attrp, stack_size);
225 if (s != 0)
226 handle_error_en(s, "pthread_attr_setstacksize");
227 } else {
228 s = posix_memalign(&stack_addr, sysconf(_SC_PAGESIZE),
229 stack_size);
230 if (s != 0)
231 handle_error_en(s, "posix_memalign");
232 printf("Allocated thread stack at %p\n\n", stack_addr);
233
234 s = pthread_attr_setstack(attrp, stack_addr, stack_size);
235 if (s != 0)
236 handle_error_en(s, "pthread_attr_setstacksize");
237 }
238 }
239
240 if (guard_size >= 0) {
241 s = pthread_attr_setguardsize(attrp, guard_size);
242 if (s != 0)
243 handle_error_en(s, "pthread_attr_setstacksize");
244 }
245
246 return ret_attrp;
247 }
248
249 int
250 main(int argc, char *argv[])
251 {
252 int s;
253 pthread_t thr;
254 pthread_attr_t attr;
255 pthread_attr_t *attrp = NULL; /* Set to &attr if we initialize
256 a thread attributes object */
257
258 attrp = get_thread_attributes_from_cl(argc, argv, &attr);
259
260 if (attrp != NULL) {
261 printf("Thread attributes object after initializations:\n");
262 display_stack_related_attributes(attrp, "\t");
263 printf("\n");
264 }
265
266 s = pthread_create(&thr, attrp, &thread_start, NULL);
267 if (s != 0)
268 handle_error_en(s, "pthread_create");
269
270 if (attrp != NULL) {
271 s = pthread_attr_destroy(attrp);
272 if (s != 0)
273 handle_error_en(s, "pthread_attr_destroy");
274 }
275
276 pause(); /* Terminates when other thread calls exit() */
277 }
278
280 pthread_attr_getaffinity_np(3), pthread_attr_getdetachstate(3),
281 pthread_attr_getguardsize(3), pthread_attr_getinheritsched(3),
282 pthread_attr_getschedparam(3), pthread_attr_getschedpolicy(3),
283 pthread_attr_getscope(3), pthread_attr_getstack(3), pthread_attr_get‐
284 stackaddr(3), pthread_attr_getstacksize(3), pthread_attr_init(3),
285 pthread_create(3), pthreads(7)
286
288 This page is part of release 3.25 of the Linux man-pages project. A
289 description of the project, and information about reporting bugs, can
290 be found at http://www.kernel.org/doc/man-pages/.
291
292
293
294Linux 2008-11-11 PTHREAD_GETATTR_NP(3)