1pthread_getattr_np(3) Library Functions Manual pthread_getattr_np(3)
2
3
4
6 pthread_getattr_np - get attributes of created thread
7
9 POSIX threads library (libpthread, -lpthread)
10
12 #define _GNU_SOURCE /* See feature_test_macros(7) */
13 #include <pthread.h>
14
15 int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr);
16
18 The pthread_getattr_np() function initializes the thread attributes ob‐
19 ject referred to by attr so that it contains actual attribute values
20 describing the running thread thread.
21
22 The returned attribute values may differ from the corresponding attri‐
23 bute values passed in the attr object that was used to create the
24 thread using pthread_create(3). In particular, the following at‐
25 tributes may differ:
26
27 • the detach state, since a joinable thread may have detached itself
28 after creation;
29
30 • the stack size, which the implementation may align to a suitable
31 boundary.
32
33 • and the guard size, which the implementation may round upward to a
34 multiple of the page size, or ignore (i.e., treat as 0), if the ap‐
35 plication is allocating its own stack.
36
37 Furthermore, if the stack address attribute was not set in the thread
38 attributes object used to create the thread, then the returned thread
39 attributes object will report the actual stack address that the imple‐
40 mentation selected for the thread.
41
42 When the thread attributes object returned by pthread_getattr_np() is
43 no longer required, it should be destroyed using pthread_attr_de‐
44 stroy(3).
45
47 On success, this function returns 0; on error, it returns a nonzero er‐
48 ror number.
49
51 ENOMEM Insufficient memory.
52
53 In addition, if thread refers to the main thread, then
54 pthread_getattr_np() can fail because of errors from various underlying
55 calls: fopen(3), if /proc/self/maps can't be opened; and getrlimit(2),
56 if the RLIMIT_STACK resource limit is not supported.
57
59 For an explanation of the terms used in this section, see at‐
60 tributes(7).
61
62 ┌────────────────────────────────────────────┬───────────────┬─────────┐
63 │Interface │ Attribute │ Value │
64 ├────────────────────────────────────────────┼───────────────┼─────────┤
65 │pthread_getattr_np() │ Thread safety │ MT-Safe │
66 └────────────────────────────────────────────┴───────────────┴─────────┘
67
69 GNU; hence the suffix "_np" (nonportable) in the name.
70
72 glibc 2.2.3.
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
77 retrieve and display its guard size, stack address, and stack size
78 attributes. 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
83 default 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 <err.h>
128 #include <errno.h>
129 #include <pthread.h>
130 #include <stdio.h>
131 #include <stdlib.h>
132 #include <unistd.h>
133
134 static void
135 display_stack_related_attributes(pthread_attr_t *attr, char *prefix)
136 {
137 int s;
138 size_t stack_size, guard_size;
139 void *stack_addr;
140
141 s = pthread_attr_getguardsize(attr, &guard_size);
142 if (s != 0)
143 errc(EXIT_FAILURE, s, "pthread_attr_getguardsize");
144 printf("%sGuard size = %zu bytes\n", prefix, guard_size);
145
146 s = pthread_attr_getstack(attr, &stack_addr, &stack_size);
147 if (s != 0)
148 errc(EXIT_FAILURE, s, "pthread_attr_getstack");
149 printf("%sStack address = %p", prefix, stack_addr);
150 if (stack_size > 0)
151 printf(" (EOS = %p)", (char *) stack_addr + stack_size);
152 printf("\n");
153 printf("%sStack size = %#zx (%zu) bytes\n",
154 prefix, stack_size, stack_size);
155 }
156
157 static void
158 display_thread_attributes(pthread_t thread, char *prefix)
159 {
160 int s;
161 pthread_attr_t attr;
162
163 s = pthread_getattr_np(thread, &attr);
164 if (s != 0)
165 errc(EXIT_FAILURE, s, "pthread_getattr_np");
166
167 display_stack_related_attributes(&attr, prefix);
168
169 s = pthread_attr_destroy(&attr);
170 if (s != 0)
171 errc(EXIT_FAILURE, s, "pthread_attr_destroy");
172 }
173
174 static void * /* Start function for thread we create */
175 thread_start(void *arg)
176 {
177 printf("Attributes of created thread:\n");
178 display_thread_attributes(pthread_self(), "\t");
179
180 exit(EXIT_SUCCESS); /* Terminate all threads */
181 }
182
183 static void
184 usage(char *pname, char *msg)
185 {
186 if (msg != NULL)
187 fputs(msg, stderr);
188 fprintf(stderr, "Usage: %s [-s stack-size [-a]]"
189 " [-g guard-size]\n", pname);
190 fprintf(stderr, "\t\t-a means program should allocate stack\n");
191 exit(EXIT_FAILURE);
192 }
193
194 static pthread_attr_t * /* Get thread attributes from command line */
195 get_thread_attributes_from_cl(int argc, char *argv[],
196 pthread_attr_t *attrp)
197 {
198 int s, opt, allocate_stack;
199 size_t stack_size, guard_size;
200 void *stack_addr;
201 pthread_attr_t *ret_attrp = NULL; /* Set to attrp if we initialize
202 a thread attributes object */
203 allocate_stack = 0;
204 stack_size = -1;
205 guard_size = -1;
206
207 while ((opt = getopt(argc, argv, "ag:s:")) != -1) {
208 switch (opt) {
209 case 'a': allocate_stack = 1; break;
210 case 'g': guard_size = strtoul(optarg, NULL, 0); break;
211 case 's': stack_size = strtoul(optarg, NULL, 0); break;
212 default: usage(argv[0], NULL);
213 }
214 }
215
216 if (allocate_stack && stack_size == -1)
217 usage(argv[0], "Specifying -a without -s makes no sense\n");
218
219 if (argc > optind)
220 usage(argv[0], "Extraneous command-line arguments\n");
221
222 if (stack_size >= 0 || guard_size > 0) {
223 ret_attrp = attrp;
224
225 s = pthread_attr_init(attrp);
226 if (s != 0)
227 errc(EXIT_FAILURE, s, "pthread_attr_init");
228 }
229
230 if (stack_size >= 0) {
231 if (!allocate_stack) {
232 s = pthread_attr_setstacksize(attrp, stack_size);
233 if (s != 0)
234 errc(EXIT_FAILURE, s, "pthread_attr_setstacksize");
235 } else {
236 s = posix_memalign(&stack_addr, sysconf(_SC_PAGESIZE),
237 stack_size);
238 if (s != 0)
239 errc(EXIT_FAILURE, s, "posix_memalign");
240 printf("Allocated thread stack at %p\n\n", stack_addr);
241
242 s = pthread_attr_setstack(attrp, stack_addr, stack_size);
243 if (s != 0)
244 errc(EXIT_FAILURE, s, "pthread_attr_setstacksize");
245 }
246 }
247
248 if (guard_size >= 0) {
249 s = pthread_attr_setguardsize(attrp, guard_size);
250 if (s != 0)
251 errc(EXIT_FAILURE, s, "pthread_attr_setstacksize");
252 }
253
254 return ret_attrp;
255 }
256
257 int
258 main(int argc, char *argv[])
259 {
260 int s;
261 pthread_t thr;
262 pthread_attr_t attr;
263 pthread_attr_t *attrp = NULL; /* Set to &attr if we initialize
264 a thread attributes object */
265
266 attrp = get_thread_attributes_from_cl(argc, argv, &attr);
267
268 if (attrp != NULL) {
269 printf("Thread attributes object after initializations:\n");
270 display_stack_related_attributes(attrp, "\t");
271 printf("\n");
272 }
273
274 s = pthread_create(&thr, attrp, &thread_start, NULL);
275 if (s != 0)
276 errc(EXIT_FAILURE, s, "pthread_create");
277
278 if (attrp != NULL) {
279 s = pthread_attr_destroy(attrp);
280 if (s != 0)
281 errc(EXIT_FAILURE, s, "pthread_attr_destroy");
282 }
283
284 pause(); /* Terminates when other thread calls exit() */
285 }
286
288 pthread_attr_getaffinity_np(3), pthread_attr_getdetachstate(3),
289 pthread_attr_getguardsize(3), pthread_attr_getinheritsched(3),
290 pthread_attr_getschedparam(3), pthread_attr_getschedpolicy(3),
291 pthread_attr_getscope(3), pthread_attr_getstack(3),
292 pthread_attr_getstackaddr(3), pthread_attr_getstacksize(3),
293 pthread_attr_init(3), pthread_create(3), pthreads(7)
294
295
296
297Linux man-pages 6.05 2023-07-20 pthread_getattr_np(3)