1 /* Linuxthreads - a simple clone()-based implementation of Posix */
2 /* threads for Linux. */
3 /* Copyright (C) 1996 Xavier Leroy (Xavier.Leroy@inria.fr) */
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. */
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 */
20 #include <stdio_ext.h>
24 #include <sys/param.h>
25 #include <sys/resource.h>
27 #include "internals.h"
30 #define __sched_get_priority_max(x) (L4_SCHED_MAX_PRIO)
31 #define __sched_get_priority_min(x) (1)
33 int __pthread_attr_init(pthread_attr_t *attr)
35 size_t ps = L4_PAGESIZE;
37 attr->__detachstate = PTHREAD_CREATE_JOINABLE;
38 attr->__schedpolicy = SCHED_OTHER;
39 attr->__schedparam.sched_priority = 0;
40 attr->__inheritsched = PTHREAD_EXPLICIT_SCHED;
41 attr->__scope = PTHREAD_SCOPE_SYSTEM;
42 #ifdef NEED_SEPARATE_REGISTER_STACK
43 attr->__guardsize = ps + ps;
45 attr->__guardsize = ps;
47 attr->__stackaddr = NULL;
48 attr->__stackaddr_set = 0;
49 attr->__stacksize = STACK_SIZE - ps;
52 strong_alias (__pthread_attr_init, pthread_attr_init)
54 int __pthread_attr_destroy(pthread_attr_t *attr)
58 strong_alias (__pthread_attr_destroy, pthread_attr_destroy)
60 int __pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
62 if (detachstate < PTHREAD_CREATE_JOINABLE ||
63 detachstate > PTHREAD_CREATE_DETACHED)
65 attr->__detachstate = detachstate;
68 strong_alias (__pthread_attr_setdetachstate, pthread_attr_setdetachstate)
70 int __pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
72 *detachstate = attr->__detachstate;
75 strong_alias (__pthread_attr_getdetachstate, pthread_attr_getdetachstate)
77 int __pthread_attr_setschedparam(pthread_attr_t *attr,
78 const struct sched_param *param)
80 int max_prio = __sched_get_priority_max(attr->__schedpolicy);
81 int min_prio = __sched_get_priority_min(attr->__schedpolicy);
83 if (param->sched_priority < min_prio || param->sched_priority > max_prio)
85 memcpy (&attr->__schedparam, param, sizeof (struct sched_param));
88 strong_alias (__pthread_attr_setschedparam, pthread_attr_setschedparam)
90 int __pthread_attr_getschedparam(const pthread_attr_t *attr,
91 struct sched_param *param)
93 memcpy (param, &attr->__schedparam, sizeof (struct sched_param));
96 strong_alias (__pthread_attr_getschedparam, pthread_attr_getschedparam)
98 int __pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
100 if (policy != SCHED_OTHER && policy != SCHED_FIFO && policy != SCHED_RR
101 && policy != SCHED_L4)
103 attr->__schedpolicy = policy;
106 strong_alias (__pthread_attr_setschedpolicy, pthread_attr_setschedpolicy)
108 int __pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
110 *policy = attr->__schedpolicy;
113 strong_alias (__pthread_attr_getschedpolicy, pthread_attr_getschedpolicy)
115 int __pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
117 if (inherit != PTHREAD_INHERIT_SCHED && inherit != PTHREAD_EXPLICIT_SCHED)
119 attr->__inheritsched = inherit;
122 strong_alias (__pthread_attr_setinheritsched, pthread_attr_setinheritsched)
124 int __pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
126 *inherit = attr->__inheritsched;
129 strong_alias (__pthread_attr_getinheritsched, pthread_attr_getinheritsched)
131 int __pthread_attr_setscope(pthread_attr_t *attr, int scope)
134 case PTHREAD_SCOPE_SYSTEM:
135 attr->__scope = scope;
137 case PTHREAD_SCOPE_PROCESS:
143 strong_alias (__pthread_attr_setscope, pthread_attr_setscope)
145 int __pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
147 *scope = attr->__scope;
150 strong_alias (__pthread_attr_getscope, pthread_attr_getscope)
152 int __pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
154 /* The guard size must not be larger than the stack itself */
155 if (guardsize >= attr->__stacksize) return EINVAL;
157 attr->__guardsize = guardsize;
161 weak_alias (__pthread_attr_setguardsize, pthread_attr_setguardsize)
163 int __pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
165 *guardsize = attr->__guardsize;
168 weak_alias (__pthread_attr_getguardsize, pthread_attr_getguardsize)
170 #if 0 /* uClibc: deprecated stuff disabled */
171 int __pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
173 attr->__stackaddr = stackaddr;
174 attr->__stackaddr_set = 1;
177 weak_alias (__pthread_attr_setstackaddr, pthread_attr_setstackaddr)
179 link_warning (pthread_attr_setstackaddr,
180 "the use of `pthread_attr_setstackaddr' is deprecated, use `pthread_attr_setstack'")
182 int __pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
184 /* XXX This function has a stupid definition. The standard specifies
185 no error value but what is if no stack address was set? We simply
186 return the value we have in the member. */
187 *stackaddr = attr->__stackaddr;
190 weak_alias (__pthread_attr_getstackaddr, pthread_attr_getstackaddr)
192 link_warning (pthread_attr_getstackaddr,
193 "the use of `pthread_attr_getstackaddr' is deprecated, use `pthread_attr_getstack'")
197 int __pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
199 /* We have to check against the maximum allowed stack size. This is no
200 problem if the manager is already started and we determined it. If
201 this hasn't happened, we have to find the limit outself. */
202 if (__pthread_max_stacksize == 0)
203 __pthread_init_max_stacksize ();
205 if (stacksize > __pthread_max_stacksize)
208 /* We don't accept value smaller than PTHREAD_STACK_MIN. */
209 if (stacksize < PTHREAD_STACK_MIN)
212 attr->__stacksize = stacksize;
216 #if PTHREAD_STACK_MIN == 16384 || defined __UCLIBC__
217 weak_alias (__pthread_attr_setstacksize, pthread_attr_setstacksize)
219 versioned_symbol (libpthread, __pthread_attr_setstacksize,
220 pthread_attr_setstacksize, GLIBC_2_3_3);
222 # if SHLIB_COMPAT(libpthread, GLIBC_2_1, GLIBC_2_3_3)
224 int __old_pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
226 /* We have to check against the maximum allowed stack size. This is no
227 problem if the manager is already started and we determined it. If
228 this hasn't happened, we have to find the limit outself. */
229 if (__pthread_max_stacksize == 0)
230 __pthread_init_max_stacksize ();
232 if (stacksize > __pthread_max_stacksize)
235 /* We don't accept value smaller than old PTHREAD_STACK_MIN. */
236 if (stacksize < 16384)
239 attr->__stacksize = stacksize;
242 compat_symbol (libpthread, __old_pthread_attr_setstacksize,
243 pthread_attr_setstacksize, GLIBC_2_1);
248 int __pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
250 *stacksize = attr->__stacksize;
253 weak_alias (__pthread_attr_getstacksize, pthread_attr_getstacksize)
255 int __pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr,
260 if ((((uintptr_t) stackaddr)
261 & (__alignof__ (struct _pthread_descr_struct) - 1)) != 0)
264 err = __pthread_attr_setstacksize (attr, stacksize);
267 #ifndef _STACK_GROWS_UP
268 attr->__stackaddr = (char *) stackaddr + stacksize;
270 attr->__stackaddr = stackaddr;
272 attr->__stackaddr_set = 1;
278 #if PTHREAD_STACK_MIN == 16384 || defined __UCLIBC__
279 weak_alias (__pthread_attr_setstack, pthread_attr_setstack)
281 versioned_symbol (libpthread, __pthread_attr_setstack, pthread_attr_setstack,
283 # if SHLIB_COMPAT(libpthread, GLIBC_2_2, GLIBC_2_3_3)
284 int __old_pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr,
289 if ((((uintptr_t) stackaddr)
290 & (__alignof__ (struct _pthread_descr_struct) - 1)) != 0)
293 err = __old_pthread_attr_setstacksize (attr, stacksize);
296 # ifndef _STACK_GROWS_UP
297 attr->__stackaddr = (char *) stackaddr + stacksize;
299 attr->__stackaddr = stackaddr;
301 attr->__stackaddr_set = 1;
307 compat_symbol (libpthread, __old_pthread_attr_setstack, pthread_attr_setstack,
313 int __pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr,
316 /* XXX This function has a stupid definition. The standard specifies
317 no error value but what is if no stack address was set? We simply
318 return the value we have in the member. */
319 #ifndef _STACK_GROWS_UP
320 *stackaddr = (char *) attr->__stackaddr - attr->__stacksize;
322 *stackaddr = attr->__stackaddr;
324 *stacksize = attr->__stacksize;
327 weak_alias (__pthread_attr_getstack, pthread_attr_getstack)
329 int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
331 pthread_handle handle = thread_handle (thread);
340 descr = handle_to_descr(handle);
342 attr->__detachstate = (descr->p_detached
343 ? PTHREAD_CREATE_DETACHED
344 : PTHREAD_CREATE_JOINABLE);
346 attr->__schedpolicy = descr->p_sched_policy;
347 if (attr->__schedpolicy == -1)
349 attr->__schedparam.sched_priority = descr->p_priority;
351 if (attr->__schedparam.sched_priority < 0)
354 attr->__inheritsched = descr->p_inheritsched;
355 attr->__scope = PTHREAD_SCOPE_SYSTEM;
357 #ifdef _STACK_GROWS_DOWN
359 attr->__stacksize = descr->p_stackaddr - (char *)descr->p_guardaddr
360 - descr->p_guardsize;
362 attr->__stacksize = (char *)(descr + 1) - (char *)descr->p_guardaddr
363 - descr->p_guardsize;
367 attr->__stacksize = (char *)descr->p_guardaddr - descr->p_stackaddr;
369 attr->__stacksize = (char *)descr->p_guardaddr - (char *)descr;
372 attr->__guardsize = descr->p_guardsize;
373 attr->__stackaddr_set = descr->p_userstack;
374 #ifdef NEED_SEPARATE_REGISTER_STACK
375 if (descr->p_userstack == 0)
376 attr->__stacksize *= 2;
377 /* XXX This is awkward. The guard pages are in the middle of the
378 two stacks. We must count the guard size in the stack size since
379 otherwise the range of the stack area cannot be computed. */
380 attr->__stacksize += attr->__guardsize;
383 attr->__stackaddr = descr->p_stackaddr;
385 # ifndef _STACK_GROWS_UP
386 attr->__stackaddr = (char *)(descr + 1);
388 attr->__stackaddr = (char *)descr;
393 #ifdef NOT_FOR_L4 // XXX: fix for initial thread
395 if (attr->__stackaddr == NULL)
397 if (descr == &__pthread_initial_thread)
400 /* Stack size limit. */
403 /* The safest way to get the top of the stack is to read
404 /proc/self/maps and locate the line into which
405 __libc_stack_end falls. */
406 FILE *fp = fopen ("/proc/self/maps", "rc");
409 /* We need the limit of the stack in any case. */
410 else if (getrlimit (RLIMIT_STACK, &rl) != 0)
414 /* We need no locking. */
415 __fsetlocking (fp, FSETLOCKING_BYCALLER);
417 /* Until we found an entry (which should always be the case)
418 mark the result as a failure. */
423 uintptr_t last_to = 0;
425 while (! feof_unlocked (fp))
427 if (getdelim (&line, &linelen, '\n', fp) <= 0)
432 if (sscanf (line, "%" SCNxPTR "-%" SCNxPTR, &from, &to) != 2)
434 if (from <= (uintptr_t) __libc_stack_end
435 && (uintptr_t) __libc_stack_end < to)
437 /* Found the entry. Now we have the info we need. */
438 attr->__stacksize = rl.rlim_cur;
439 #ifdef _STACK_GROWS_UP
440 /* Don't check to enforce a limit on the __stacksize */
441 attr->__stackaddr = (void *) from;
443 attr->__stackaddr = (void *) to;
445 /* The limit might be too high. */
446 if ((size_t) attr->__stacksize
447 > (size_t) attr->__stackaddr - last_to)
448 attr->__stacksize = (size_t) attr->__stackaddr - last_to;
451 /* We succeed and no need to look further. */