1PTHREAD_GETATTR_NP(3)      Linux Programmer's Manual     PTHREAD_GETATTR_NP(3)
2
3
4

NAME

6       pthread_getattr_np - get attributes of created thread
7

SYNOPSIS

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

DESCRIPTION

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

RETURN VALUE

46       On success, this function returns 0; on error, it returns a nonzero er‐
47       ror number.
48

ERRORS

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

VERSIONS

58       This function is available in glibc since version 2.2.3.
59

ATTRIBUTES

61       For  an  explanation  of  the  terms  used  in  this  section,  see at‐
62       tributes(7).
63
64       ┌────────────────────────────────────────────┬───────────────┬─────────┐
65Interface                                   Attribute     Value   
66       ├────────────────────────────────────────────┼───────────────┼─────────┤
67pthread_getattr_np()                        │ Thread safety │ MT-Safe │
68       └────────────────────────────────────────────┴───────────────┴─────────┘
69

CONFORMING TO

71       This function is a nonstandard GNU extension; hence  the  suffix  "_np"
72       (nonportable) in the name.
73

EXAMPLES

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

SEE ALSO

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

COLOPHON

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)
Impressum