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