* sysdeps/m68k/setjmp.c: Add hidden_def.
[glibc/pb-stable.git] / linuxthreads / attr.c
blob177df90b98b0167708ebb8232ef592c103675d19
1 /* Linuxthreads - a simple clone()-based implementation of Posix */
2 /* threads for Linux. */
3 /* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
4 /* */
5 /* This program is free software; you can redistribute it and/or */
6 /* modify it under the terms of the GNU Library General Public License */
7 /* as published by the Free Software Foundation; either version 2 */
8 /* of the License, or (at your option) any later version. */
9 /* */
10 /* This program is distributed in the hope that it will be useful, */
11 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
12 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
13 /* GNU Library General Public License for more details. */
15 /* Handling of thread attributes */
17 #include <errno.h>
18 #include <string.h>
19 #include <unistd.h>
20 #include <sys/param.h>
21 #include <sys/resource.h>
22 #include "pthread.h"
23 #include "internals.h"
24 #include <shlib-compat.h>
26 int __pthread_attr_init_2_1(pthread_attr_t *attr)
28 size_t ps = __getpagesize ();
30 attr->__detachstate = PTHREAD_CREATE_JOINABLE;
31 attr->__schedpolicy = SCHED_OTHER;
32 attr->__schedparam.sched_priority = 0;
33 attr->__inheritsched = PTHREAD_EXPLICIT_SCHED;
34 attr->__scope = PTHREAD_SCOPE_SYSTEM;
35 attr->__guardsize = ps;
36 attr->__stackaddr = NULL;
37 attr->__stackaddr_set = 0;
38 attr->__stacksize = STACK_SIZE - ps;
39 return 0;
42 versioned_symbol (libpthread, __pthread_attr_init_2_1, pthread_attr_init,
43 GLIBC_2_1);
45 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
46 int __pthread_attr_init_2_0(pthread_attr_t *attr)
48 attr->__detachstate = PTHREAD_CREATE_JOINABLE;
49 attr->__schedpolicy = SCHED_OTHER;
50 attr->__schedparam.sched_priority = 0;
51 attr->__inheritsched = PTHREAD_EXPLICIT_SCHED;
52 attr->__scope = PTHREAD_SCOPE_SYSTEM;
53 return 0;
55 compat_symbol (libpthread, __pthread_attr_init_2_0, pthread_attr_init,
56 GLIBC_2_0);
57 #endif
59 int __pthread_attr_destroy(pthread_attr_t *attr)
61 return 0;
63 strong_alias (__pthread_attr_destroy, pthread_attr_destroy);
65 int __pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
67 if (detachstate < PTHREAD_CREATE_JOINABLE ||
68 detachstate > PTHREAD_CREATE_DETACHED)
69 return EINVAL;
70 attr->__detachstate = detachstate;
71 return 0;
73 strong_alias (__pthread_attr_setdetachstate, pthread_attr_setdetachstate);
75 int __pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
77 *detachstate = attr->__detachstate;
78 return 0;
80 strong_alias (__pthread_attr_getdetachstate, pthread_attr_getdetachstate);
82 int __pthread_attr_setschedparam(pthread_attr_t *attr,
83 const struct sched_param *param)
85 int max_prio = __sched_get_priority_max(attr->__schedpolicy);
86 int min_prio = __sched_get_priority_min(attr->__schedpolicy);
88 if (param->sched_priority < min_prio || param->sched_priority > max_prio)
89 return EINVAL;
90 memcpy (&attr->__schedparam, param, sizeof (struct sched_param));
91 return 0;
93 strong_alias (__pthread_attr_setschedparam, pthread_attr_setschedparam);
95 int __pthread_attr_getschedparam(const pthread_attr_t *attr,
96 struct sched_param *param)
98 memcpy (param, &attr->__schedparam, sizeof (struct sched_param));
99 return 0;
101 strong_alias (__pthread_attr_getschedparam, pthread_attr_getschedparam);
103 int __pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
105 if (policy != SCHED_OTHER && policy != SCHED_FIFO && policy != SCHED_RR)
106 return EINVAL;
107 attr->__schedpolicy = policy;
108 return 0;
110 strong_alias (__pthread_attr_setschedpolicy, pthread_attr_setschedpolicy);
112 int __pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
114 *policy = attr->__schedpolicy;
115 return 0;
117 strong_alias (__pthread_attr_getschedpolicy, pthread_attr_getschedpolicy);
119 int __pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
121 if (inherit != PTHREAD_INHERIT_SCHED && inherit != PTHREAD_EXPLICIT_SCHED)
122 return EINVAL;
123 attr->__inheritsched = inherit;
124 return 0;
126 strong_alias (__pthread_attr_setinheritsched, pthread_attr_setinheritsched);
128 int __pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
130 *inherit = attr->__inheritsched;
131 return 0;
133 strong_alias (__pthread_attr_getinheritsched, pthread_attr_getinheritsched);
135 int __pthread_attr_setscope(pthread_attr_t *attr, int scope)
137 switch (scope) {
138 case PTHREAD_SCOPE_SYSTEM:
139 attr->__scope = scope;
140 return 0;
141 case PTHREAD_SCOPE_PROCESS:
142 return ENOTSUP;
143 default:
144 return EINVAL;
147 strong_alias (__pthread_attr_setscope, pthread_attr_setscope);
149 int __pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
151 *scope = attr->__scope;
152 return 0;
154 strong_alias (__pthread_attr_getscope, pthread_attr_getscope);
156 int __pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
158 /* The guard size must not be larger than the stack itself */
159 if (guardsize >= attr->__stacksize) return EINVAL;
161 attr->__guardsize = guardsize;
163 return 0;
165 weak_alias (__pthread_attr_setguardsize, pthread_attr_setguardsize)
167 int __pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
169 *guardsize = attr->__guardsize;
170 return 0;
172 weak_alias (__pthread_attr_getguardsize, pthread_attr_getguardsize)
174 int __pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
176 attr->__stackaddr = stackaddr;
177 attr->__stackaddr_set = 1;
178 return 0;
180 weak_alias (__pthread_attr_setstackaddr, pthread_attr_setstackaddr)
182 link_warning (pthread_attr_setstackaddr,
183 "the use of `pthread_attr_setstackaddr' is deprecated, use `pthread_attr_setstack'")
185 int __pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
187 /* XXX This function has a stupid definition. The standard specifies
188 no error value but what is if no stack address was set? We simply
189 return the value we have in the member. */
190 *stackaddr = attr->__stackaddr;
191 return 0;
193 weak_alias (__pthread_attr_getstackaddr, pthread_attr_getstackaddr)
195 link_warning (pthread_attr_getstackaddr,
196 "the use of `pthread_attr_getstackaddr' is deprecated, use `pthread_attr_getstack'")
199 int __pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
201 #ifdef FLOATING_STACKS
202 /* We have to check against the maximum allowed stack size. This is no
203 problem if the manager is already started and we determined it. If
204 this hasn't happened, we have to find the limit outself. */
205 if (__pthread_max_stacksize == 0)
206 __pthread_init_max_stacksize ();
208 if (stacksize > __pthread_max_stacksize)
209 return EINVAL;
210 #else
211 /* We have a fixed size limit. */
212 if (stacksize > STACK_SIZE)
213 return EINVAL;
214 #endif
216 /* We don't accept value smaller than PTHREAD_STACK_MIN. */
217 if (stacksize < PTHREAD_STACK_MIN)
218 return EINVAL;
220 attr->__stacksize = stacksize;
221 return 0;
224 #if PTHREAD_STACK_MIN == 16384
225 weak_alias (__pthread_attr_setstacksize, pthread_attr_setstacksize)
226 #else
227 versioned_symbol (libpthread, __pthread_attr_setstacksize,
228 pthread_attr_setstacksize, GLIBC_2_3_3);
230 # if SHLIB_COMPAT(libpthread, GLIBC_2_1, GLIBC_2_3_3)
232 int __old_pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
234 # ifdef FLOATING_STACKS
235 /* We have to check against the maximum allowed stack size. This is no
236 problem if the manager is already started and we determined it. If
237 this hasn't happened, we have to find the limit outself. */
238 if (__pthread_max_stacksize == 0)
239 __pthread_init_max_stacksize ();
241 if (stacksize > __pthread_max_stacksize)
242 return EINVAL;
243 # else
244 /* We have a fixed size limit. */
245 if (stacksize > STACK_SIZE)
246 return EINVAL;
247 # endif
249 /* We don't accept value smaller than old PTHREAD_STACK_MIN. */
250 if (stacksize < 16384)
251 return EINVAL;
253 attr->__stacksize = stacksize;
254 return 0;
256 compat_symbol (libpthread, __old_pthread_attr_setstacksize,
257 pthread_attr_setstacksize, GLIBC_2_1);
258 # endif
259 #endif
262 int __pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
264 *stacksize = attr->__stacksize;
265 return 0;
267 weak_alias (__pthread_attr_getstacksize, pthread_attr_getstacksize)
269 int __pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr,
270 size_t stacksize)
272 int err;
274 if ((((uintptr_t) stackaddr)
275 & (__alignof__ (struct _pthread_descr_struct) - 1)) != 0)
276 err = EINVAL;
277 else
278 err = __pthread_attr_setstacksize (attr, stacksize);
279 if (err == 0)
281 #ifndef _STACK_GROWS_UP
282 attr->__stackaddr = (char *) stackaddr + stacksize;
283 #else
284 attr->__stackaddr = stackaddr;
285 #endif
286 attr->__stackaddr_set = 1;
289 return err;
292 #if PTHREAD_STACK_MIN == 16384
293 weak_alias (__pthread_attr_setstack, pthread_attr_setstack)
294 #else
295 versioned_symbol (libpthread, __pthread_attr_setstack, pthread_attr_setstack,
296 GLIBC_2_3_3);
297 # if SHLIB_COMPAT(libpthread, GLIBC_2_2, GLIBC_2_3_3)
298 int __old_pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr,
299 size_t stacksize)
301 int err;
303 if ((((uintptr_t) stackaddr)
304 & (__alignof__ (struct _pthread_descr_struct) - 1)) != 0)
305 err = EINVAL;
306 else
307 err = __old_pthread_attr_setstacksize (attr, stacksize);
308 if (err == 0)
310 # ifndef _STACK_GROWS_UP
311 attr->__stackaddr = (char *) stackaddr + stacksize;
312 # else
313 attr->__stackaddr = stackaddr;
314 # endif
315 attr->__stackaddr_set = 1;
318 return err;
321 compat_symbol (libpthread, __old_pthread_attr_setstack, pthread_attr_setstack,
322 GLIBC_2_2);
324 # endif
325 #endif
327 int __pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr,
328 size_t *stacksize)
330 /* XXX This function has a stupid definition. The standard specifies
331 no error value but what is if no stack address was set? We simply
332 return the value we have in the member. */
333 #ifndef _STACK_GROWS_UP
334 *stackaddr = (char *) attr->__stackaddr - attr->__stacksize;
335 #else
336 *stackaddr = attr->__stackaddr;
337 #endif
338 *stacksize = attr->__stacksize;
339 return 0;
341 weak_alias (__pthread_attr_getstack, pthread_attr_getstack)
343 int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
345 pthread_handle handle = thread_handle (thread);
346 pthread_descr descr;
348 if (handle == NULL)
349 return ENOENT;
351 descr = handle->h_descr;
353 attr->__detachstate = (descr->p_detached
354 ? PTHREAD_CREATE_DETACHED
355 : PTHREAD_CREATE_JOINABLE);
357 attr->__schedpolicy = __sched_getscheduler (descr->p_pid);
358 if (attr->__schedpolicy == -1)
359 return errno;
361 if (__sched_getparam (descr->p_pid,
362 (struct sched_param *) &attr->__schedparam) != 0)
363 return errno;
365 attr->__inheritsched = descr->p_inheritsched;
366 attr->__scope = PTHREAD_SCOPE_SYSTEM;
367 #ifdef _STACK_GROWS_DOWN
368 # ifdef USE_TLS
369 attr->__stacksize = descr->p_stackaddr - (char *)descr->p_guardaddr
370 - descr->p_guardsize;
371 # else
372 attr->__stacksize = (char *)(descr + 1) - (char *)descr->p_guardaddr
373 - descr->p_guardsize;
374 # endif
375 #else
376 # ifdef USE_TLS
377 attr->__stacksize = (char *)descr->p_guardaddr - descr->p_stackaddr;
378 # else
379 attr->__stacksize = (char *)descr->p_guardaddr - (char *)descr;
380 # endif
381 #endif
382 attr->__guardsize = descr->p_guardsize;
383 attr->__stackaddr_set = descr->p_userstack;
384 #ifdef NEED_SEPARATE_REGISTER_STACK
385 if (descr->p_userstack == 0)
386 attr->__stacksize *= 2;
387 /* XXX This is awkward. The guard pages are in the middle of the
388 two stacks. We must count the guard size in the stack size since
389 otherwise the range of the stack area cannot be computed. */
390 attr->__stacksize += attr->__guardsize;
391 #endif
392 #ifdef USE_TLS
393 attr->__stackaddr = descr->p_stackaddr;
394 #else
395 # ifndef _STACK_GROWS_UP
396 attr->__stackaddr = (char *)(descr + 1);
397 # else
398 attr->__stackaddr = (char *)descr;
399 # endif
400 #endif
402 return 0;