OSDN Git Service

2dc09e0398d204e497432f5a54658986a303bd84
[linuxjm/LDP_man-pages.git] / original / man3 / pthread_getattr_np.3
1 .\" Copyright (c) 2008 Linux Foundation, written by Michael Kerrisk
2 .\"     <mtk.manpages@gmail.com>
3 .\"
4 .\" %%%LICENSE_START(VERBATIM)
5 .\" Permission is granted to make and distribute verbatim copies of this
6 .\" manual provided the copyright notice and this permission notice are
7 .\" preserved on all copies.
8 .\"
9 .\" Permission is granted to copy and distribute modified versions of this
10 .\" manual under the conditions for verbatim copying, provided that the
11 .\" entire resulting derived work is distributed under the terms of a
12 .\" permission notice identical to this one.
13 .\"
14 .\" Since the Linux kernel and libraries are constantly changing, this
15 .\" manual page may be incorrect or out-of-date.  The author(s) assume no
16 .\" responsibility for errors or omissions, or for damages resulting from
17 .\" the use of the information contained herein.  The author(s) may not
18 .\" have taken the same level of care in the production of this manual,
19 .\" which is licensed free of charge, as they might when working
20 .\" professionally.
21 .\"
22 .\" Formatted or processed versions of this manual, if unaccompanied by
23 .\" the source, must acknowledge the copyright and authors of this work.
24 .\" %%%LICENSE_END
25 .\"
26 .TH PTHREAD_GETATTR_NP 3 2010-09-10 "Linux" "Linux Programmer's Manual"
27 .SH NAME
28 pthread_getattr_np \- get attributes of created thread
29 .SH SYNOPSIS
30 .nf
31 .BR "#define _GNU_SOURCE" "             /* See feature_test_macros(7) */"
32 .B #include <pthread.h>
33
34 .BI "int pthread_getattr_np(pthread_t " thread ", pthread_attr_t *" attr );
35 .sp
36 Compile and link with \fI\-pthread\fP.
37 .fi
38 .SH DESCRIPTION
39 The
40 .BR pthread_getattr_np ()
41 function initializes the thread attributes object referred to by
42 .I attr
43 so that it contains actual attribute values describing the running thread
44 .IR thread .
45
46 The returned attribute values may differ from
47 the corresponding attribute values passed in the
48 .I attr
49 object that was used to create the thread using
50 .BR pthread_create (3).
51 In particular, the following attributes may differ:
52 .IP * 2
53 the detach state, since a joinable thread may have detached itself
54 after creation;
55 .IP *
56 the stack size,
57 which the implementation may align to a suitable boundary.
58 .IP *
59 and the guard size,
60 which the implementation may round upward to a multiple of the page size,
61 or ignore (i.e., treat as 0),
62 if the application is allocating its own stack.
63 .PP
64 Furthermore, if the stack address attribute was not set
65 in the thread attributes object used to create the thread,
66 then the returned thread attributes object will report the actual
67 stack address that the implementation selected for the thread.
68
69 When the thread attributes object returned by
70 .BR pthread_getattr_np ()
71 is no longer required, it should be destroyed using
72 .BR pthread_attr_destroy (3).
73 .SH RETURN VALUE
74 On success, this function returns 0;
75 on error, it returns a nonzero error number.
76 .SH ERRORS
77 .TP
78 .B ENOMEM
79 .\" Can happen (but unlikely) while trying to allocate memory for cpuset
80 Insufficient memory.
81 .PP
82 In addition, if
83 .I thread
84 refers to the main thread, then
85 .BR pthread_getattr_np ()
86 can fail because of errors from various underlying calls:
87 .BR fopen (3),
88 if
89 .IR /proc/self/maps
90 can't be opened;
91 and
92 .BR getrlimit (2),
93 if the
94 .BR RLIMIT_STACK
95 resource limit is not supported.
96 .SH VERSIONS
97 This function is available in glibc since version 2.2.3.
98 .SH CONFORMING TO
99 This function is a nonstandard GNU extension;
100 hence the suffix "_np" (nonportable) in the name.
101 .SH EXAMPLE
102 The program below demonstrates the use of
103 .BR pthread_getattr_np ().
104 The program creates a thread that then uses
105 .BR pthread_getattr_np ()
106 to retrieve and display its guard size, stack address,
107 and stack size attributes.
108 Command-line arguments can be used to set these attributes
109 to values other than the default when creating the thread.
110 The shell sessions below demonstrate the use of the program.
111
112 In the first run, on an x86-32 system,
113 a thread is created using default attributes:
114
115 .in +4n
116 .nf
117 .RB "$" " ulimit \-s" "      # No stack limit ==> default stack size is 2MB"
118 unlimited
119 .RB "$" " ./a.out"
120 Attributes of created thread:
121         Guard size          = 4096 bytes
122         Stack address       = 0x40196000 (EOS = 0x40397000)
123         Stack size          = 0x201000 (2101248) bytes
124 .fi
125 .in
126
127 In the following run, we see that if a guard size is specified,
128 it is rounded up to the next multiple of the system page size
129 (4096 bytes on x86-32):
130
131 .in +4n
132 .nf
133 .RB "$" " ./a.out \-g 4097"
134 Thread attributes object after initializations:
135         Guard size          = 4097 bytes
136         Stack address       = (nil)
137         Stack size          = 0x0 (0) bytes
138
139 Attributes of created thread:
140         Guard size          = 8192 bytes
141         Stack address       = 0x40196000 (EOS = 0x40397000)
142         Stack size          = 0x201000 (2101248) bytes
143 .fi
144 .in
145 .\".in +4n
146 .\".nf
147 .\"$ ./a.out \-s 0x8000
148 .\"Thread attributes object after initializations:
149 .\"        Guard size          = 4096 bytes
150 .\"        Stack address       = 0xffff8000 (EOS = (nil))
151 .\"        Stack size          = 0x8000 (32768) bytes
152 .\"
153 .\"Attributes of created thread:
154 .\"        Guard size          = 4096 bytes
155 .\"        Stack address       = 0x4001e000 (EOS = 0x40026000)
156 .\"        Stack size          = 0x8000 (32768) bytes
157 .\".fi
158 .\".in
159
160 In the last run, the program manually allocates a stack for the thread.
161 In this case, the guard size attribute is ignored.
162
163 .in +4n
164 .nf
165 .RB "$" " ./a.out \-g 4096 \-s 0x8000 \-a"
166 Allocated thread stack at 0x804d000
167
168 Thread attributes object after initializations:
169         Guard size          = 4096 bytes
170         Stack address       = 0x804d000 (EOS = 0x8055000)
171         Stack size          = 0x8000 (32768) bytes
172
173 Attributes of created thread:
174         Guard size          = 0 bytes
175         Stack address       = 0x804d000 (EOS = 0x8055000)
176         Stack size          = 0x8000 (32768) bytes
177 .fi
178 .in
179 .SS Program source
180 \&
181 .nf
182 #define _GNU_SOURCE     /* To get pthread_getattr_np() declaration */
183 #include <pthread.h>
184 #include <stdio.h>
185 #include <stdlib.h>
186 #include <unistd.h>
187 #include <errno.h>
188
189 #define handle_error_en(en, msg) \\
190         do { errno = en; perror(msg); exit(EXIT_FAILURE); } while (0)
191
192 static void
193 display_stack_related_attributes(pthread_attr_t *attr, char *prefix)
194 {
195     int s;
196     size_t stack_size, guard_size;
197     void *stack_addr;
198
199     s = pthread_attr_getguardsize(attr, &guard_size);
200     if (s != 0)
201         handle_error_en(s, "pthread_attr_getguardsize");
202     printf("%sGuard size          = %d bytes\\n", prefix, guard_size);
203
204     s = pthread_attr_getstack(attr, &stack_addr, &stack_size);
205     if (s != 0)
206         handle_error_en(s, "pthread_attr_getstack");
207     printf("%sStack address       = %p", prefix, stack_addr);
208     if (stack_size > 0)
209         printf(" (EOS = %p)", (char *) stack_addr + stack_size);
210     printf("\\n");
211     printf("%sStack size          = 0x%x (%d) bytes\\n",
212             prefix, stack_size, stack_size);
213 }
214
215 static void
216 display_thread_attributes(pthread_t thread, char *prefix)
217 {
218     int s;
219     pthread_attr_t attr;
220
221     s = pthread_getattr_np(thread, &attr);
222     if (s != 0)
223         handle_error_en(s, "pthread_getattr_np");
224
225     display_stack_related_attributes(&attr, prefix);
226
227     s = pthread_attr_destroy(&attr);
228     if (s != 0)
229         handle_error_en(s, "pthread_attr_destroy");
230 }
231
232 static void *           /* Start function for thread we create */
233 thread_start(void *arg)
234 {
235     printf("Attributes of created thread:\\n");
236     display_thread_attributes(pthread_self(), "\\t");
237
238     exit(EXIT_SUCCESS);         /* Terminate all threads */
239 }
240
241 static void
242 usage(char *pname, char *msg)
243 {
244     if (msg != NULL)
245         fputs(msg, stderr);
246     fprintf(stderr, "Usage: %s [\-s stack\-size [\-a]]"
247             " [\-g guard\-size]\\n", pname);
248     fprintf(stderr, "\\t\\t\-a means program should allocate stack\\n");
249     exit(EXIT_FAILURE);
250 }
251
252 static pthread_attr_t *   /* Get thread attributes from command line */
253 get_thread_attributes_from_cl(int argc, char *argv[],
254                               pthread_attr_t *attrp)
255 {
256     int s, opt, allocate_stack;
257     long stack_size, guard_size;
258             void *stack_addr;
259     pthread_attr_t *ret_attrp = NULL;   /* Set to attrp if we initialize
260                                            a thread attributes object */
261     allocate_stack = 0;
262     stack_size = \-1;
263     guard_size = \-1;
264
265     while ((opt = getopt(argc, argv, "ag:s:")) != \-1) {
266         switch (opt) {
267         case \(aqa\(aq:   allocate_stack = 1;                     break;
268         case \(aqg\(aq:   guard_size = strtoul(optarg, NULL, 0);  break;
269         case \(aqs\(aq:   stack_size = strtoul(optarg, NULL, 0);  break;
270         default:    usage(argv[0], NULL);
271         }
272     }
273
274     if (allocate_stack && stack_size == \-1)
275         usage(argv[0], "Specifying \-a without \-s makes no sense\\n");
276
277     if (argc > optind)
278         usage(argv[0], "Extraneous command\-line arguments\\n");
279
280     if (stack_size >= 0 || guard_size > 0) {
281         ret_attrp = attrp;
282
283         s = pthread_attr_init(attrp);
284         if (s != 0)
285             handle_error_en(s, "pthread_attr_init");
286     }
287
288     if (stack_size >= 0) {
289         if (!allocate_stack) {
290             s = pthread_attr_setstacksize(attrp, stack_size);
291             if (s != 0)
292                 handle_error_en(s, "pthread_attr_setstacksize");
293         } else {
294             s = posix_memalign(&stack_addr, sysconf(_SC_PAGESIZE),
295                                stack_size);
296             if (s != 0)
297                 handle_error_en(s, "posix_memalign");
298             printf("Allocated thread stack at %p\\n\\n", stack_addr);
299
300             s = pthread_attr_setstack(attrp, stack_addr, stack_size);
301             if (s != 0)
302                 handle_error_en(s, "pthread_attr_setstacksize");
303         }
304     }
305
306     if (guard_size >= 0) {
307         s = pthread_attr_setguardsize(attrp, guard_size);
308         if (s != 0)
309             handle_error_en(s, "pthread_attr_setstacksize");
310     }
311
312     return ret_attrp;
313 }
314
315 int
316 main(int argc, char *argv[])
317 {
318     int s;
319     pthread_t thr;
320     pthread_attr_t attr;
321     pthread_attr_t *attrp = NULL;    /* Set to &attr if we initialize
322                                         a thread attributes object */
323
324     attrp = get_thread_attributes_from_cl(argc, argv, &attr);
325
326     if (attrp != NULL) {
327         printf("Thread attributes object after initializations:\\n");
328         display_stack_related_attributes(attrp, "\\t");
329         printf("\\n");
330     }
331
332     s = pthread_create(&thr, attrp, &thread_start, NULL);
333     if (s != 0)
334         handle_error_en(s, "pthread_create");
335
336     if (attrp != NULL) {
337         s = pthread_attr_destroy(attrp);
338         if (s != 0)
339             handle_error_en(s, "pthread_attr_destroy");
340     }
341
342     pause();    /* Terminates when other thread calls exit() */
343 }
344 .fi
345 .SH SEE ALSO
346 .ad l
347 .nh
348 .BR pthread_attr_getaffinity_np (3),
349 .BR pthread_attr_getdetachstate (3),
350 .BR pthread_attr_getguardsize (3),
351 .BR pthread_attr_getinheritsched (3),
352 .BR pthread_attr_getschedparam (3),
353 .BR pthread_attr_getschedpolicy (3),
354 .BR pthread_attr_getscope (3),
355 .BR pthread_attr_getstack (3),
356 .BR pthread_attr_getstackaddr (3),
357 .BR pthread_attr_getstacksize (3),
358 .BR pthread_attr_init (3),
359 .BR pthread_create (3),
360 .BR pthreads (7)
361 .SH COLOPHON
362 This page is part of release 3.64 of the Linux
363 .I man-pages
364 project.
365 A description of the project,
366 and information about reporting bugs,
367 can be found at
368 \%http://www.kernel.org/doc/man\-pages/.