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