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 <sys/param.h>
21 #include <sys/resource.h>
23 #include "internals.h"
24 #include <shlib-compat.h>
25 #include <stackinfo.h>
27 int __pthread_attr_init_2_1(pthread_attr_t
*attr
)
29 size_t ps
= __getpagesize ();
31 attr
->__detachstate
= PTHREAD_CREATE_JOINABLE
;
32 attr
->__schedpolicy
= SCHED_OTHER
;
33 attr
->__schedparam
.sched_priority
= 0;
34 attr
->__inheritsched
= PTHREAD_EXPLICIT_SCHED
;
35 attr
->__scope
= PTHREAD_SCOPE_SYSTEM
;
36 attr
->__guardsize
= ps
;
37 attr
->__stackaddr
= NULL
;
38 attr
->__stackaddr_set
= 0;
39 attr
->__stacksize
= STACK_SIZE
- ps
;
43 versioned_symbol (libpthread
, __pthread_attr_init_2_1
, pthread_attr_init
,
46 #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
47 int __pthread_attr_init_2_0(pthread_attr_t
*attr
)
49 attr
->__detachstate
= PTHREAD_CREATE_JOINABLE
;
50 attr
->__schedpolicy
= SCHED_OTHER
;
51 attr
->__schedparam
.sched_priority
= 0;
52 attr
->__inheritsched
= PTHREAD_EXPLICIT_SCHED
;
53 attr
->__scope
= PTHREAD_SCOPE_SYSTEM
;
56 compat_symbol (libpthread
, __pthread_attr_init_2_0
, pthread_attr_init
,
60 int pthread_attr_destroy(pthread_attr_t
*attr
)
65 int pthread_attr_setdetachstate(pthread_attr_t
*attr
, int detachstate
)
67 if (detachstate
< PTHREAD_CREATE_JOINABLE
||
68 detachstate
> PTHREAD_CREATE_DETACHED
)
70 attr
->__detachstate
= detachstate
;
74 int pthread_attr_getdetachstate(const pthread_attr_t
*attr
, int *detachstate
)
76 *detachstate
= attr
->__detachstate
;
80 int pthread_attr_setschedparam(pthread_attr_t
*attr
,
81 const struct sched_param
*param
)
83 int max_prio
= __sched_get_priority_max(attr
->__schedpolicy
);
84 int min_prio
= __sched_get_priority_min(attr
->__schedpolicy
);
86 if (param
->sched_priority
< min_prio
|| param
->sched_priority
> max_prio
)
88 memcpy (&attr
->__schedparam
, param
, sizeof (struct sched_param
));
92 int pthread_attr_getschedparam(const pthread_attr_t
*attr
,
93 struct sched_param
*param
)
95 memcpy (param
, &attr
->__schedparam
, sizeof (struct sched_param
));
99 int pthread_attr_setschedpolicy(pthread_attr_t
*attr
, int policy
)
101 if (policy
!= SCHED_OTHER
&& policy
!= SCHED_FIFO
&& policy
!= SCHED_RR
)
103 attr
->__schedpolicy
= policy
;
107 int pthread_attr_getschedpolicy(const pthread_attr_t
*attr
, int *policy
)
109 *policy
= attr
->__schedpolicy
;
113 int pthread_attr_setinheritsched(pthread_attr_t
*attr
, int inherit
)
115 if (inherit
!= PTHREAD_INHERIT_SCHED
&& inherit
!= PTHREAD_EXPLICIT_SCHED
)
117 attr
->__inheritsched
= inherit
;
121 int pthread_attr_getinheritsched(const pthread_attr_t
*attr
, int *inherit
)
123 *inherit
= attr
->__inheritsched
;
127 int pthread_attr_setscope(pthread_attr_t
*attr
, int scope
)
130 case PTHREAD_SCOPE_SYSTEM
:
131 attr
->__scope
= scope
;
133 case PTHREAD_SCOPE_PROCESS
:
140 int pthread_attr_getscope(const pthread_attr_t
*attr
, int *scope
)
142 *scope
= attr
->__scope
;
146 int __pthread_attr_setguardsize(pthread_attr_t
*attr
, size_t guardsize
)
148 /* The guard size must not be larger than the stack itself */
149 if (guardsize
>= attr
->__stacksize
) return EINVAL
;
151 attr
->__guardsize
= guardsize
;
155 weak_alias (__pthread_attr_setguardsize
, pthread_attr_setguardsize
)
157 int __pthread_attr_getguardsize(const pthread_attr_t
*attr
, size_t *guardsize
)
159 *guardsize
= attr
->__guardsize
;
162 weak_alias (__pthread_attr_getguardsize
, pthread_attr_getguardsize
)
164 int __pthread_attr_setstackaddr(pthread_attr_t
*attr
, void *stackaddr
)
166 attr
->__stackaddr
= stackaddr
;
167 attr
->__stackaddr_set
= 1;
170 weak_alias (__pthread_attr_setstackaddr
, pthread_attr_setstackaddr
)
172 link_warning (pthread_attr_setstackaddr
,
173 "the use of `pthread_attr_setstackaddr' is deprecated, use `pthread_attr_setstack'")
175 int __pthread_attr_getstackaddr(const pthread_attr_t
*attr
, void **stackaddr
)
177 /* XXX This function has a stupid definition. The standard specifies
178 no error value but what is if no stack address was set? We simply
179 return the value we have in the member. */
180 *stackaddr
= attr
->__stackaddr
;
183 weak_alias (__pthread_attr_getstackaddr
, pthread_attr_getstackaddr
)
185 link_warning (pthread_attr_getstackaddr
,
186 "the use of `pthread_attr_getstackaddr' is deprecated, use `pthread_attr_getstack'")
189 int __pthread_attr_setstacksize(pthread_attr_t
*attr
, size_t stacksize
)
191 #ifdef FLOATING_STACKS
192 /* We have to check against the maximum allowed stack size. This is no
193 problem if the manager is already started and we determined it. If
194 this hasn't happened, we have to find the limit outself. */
195 if (__pthread_max_stacksize
== 0)
196 __pthread_init_max_stacksize ();
198 if (stacksize
> __pthread_max_stacksize
)
201 /* We have a fixed size limit. */
202 if (stacksize
> STACK_SIZE
)
206 /* We don't accept value smaller than PTHREAD_STACK_MIN. */
207 if (stacksize
< PTHREAD_STACK_MIN
)
210 attr
->__stacksize
= stacksize
;
213 weak_alias (__pthread_attr_setstacksize
, pthread_attr_setstacksize
)
215 int __pthread_attr_getstacksize(const pthread_attr_t
*attr
, size_t *stacksize
)
217 *stacksize
= attr
->__stacksize
;
220 weak_alias (__pthread_attr_getstacksize
, pthread_attr_getstacksize
)
222 int __pthread_attr_setstack (pthread_attr_t
*attr
, void *stackaddr
,
227 if ((((uintptr_t) stackaddr
)
228 & (__alignof__ (struct _pthread_descr_struct
) - 1)) != 0)
231 err
= __pthread_attr_setstacksize (attr
, stacksize
);
234 #ifndef _STACK_GROWS_UP
235 attr
->__stackaddr
= (char *) stackaddr
+ stacksize
;
237 attr
->__stackaddr
= stackaddr
;
239 attr
->__stackaddr_set
= 1;
244 weak_alias (__pthread_attr_setstack
, pthread_attr_setstack
)
246 int __pthread_attr_getstack (const pthread_attr_t
*attr
, void **stackaddr
,
249 /* XXX This function has a stupid definition. The standard specifies
250 no error value but what is if no stack address was set? We simply
251 return the value we have in the member. */
252 #ifndef _STACK_GROWS_UP
253 *stackaddr
= (char *) attr
->__stackaddr
- attr
->__stacksize
;
255 *stackaddr
= attr
->__stackaddr
;
257 *stacksize
= attr
->__stacksize
;
260 weak_alias (__pthread_attr_getstack
, pthread_attr_getstack
)
262 int pthread_getattr_np (pthread_t thread
, pthread_attr_t
*attr
)
264 pthread_handle handle
= thread_handle (thread
);
270 descr
= handle
->h_descr
;
272 attr
->__detachstate
= (descr
->p_detached
273 ? PTHREAD_CREATE_DETACHED
274 : PTHREAD_CREATE_JOINABLE
);
276 attr
->__schedpolicy
= __sched_getscheduler (descr
->p_pid
);
277 if (attr
->__schedpolicy
== -1)
280 if (__sched_getparam (descr
->p_pid
,
281 (struct sched_param
*) &attr
->__schedparam
) != 0)
284 attr
->__inheritsched
= descr
->p_inheritsched
;
285 attr
->__scope
= PTHREAD_SCOPE_SYSTEM
;
286 attr
->__stacksize
= (char *)(descr
+ 1) - (char *)descr
->p_guardaddr
287 - descr
->p_guardsize
;
288 attr
->__guardsize
= descr
->p_guardsize
;
289 attr
->__stackaddr_set
= descr
->p_userstack
;
290 #ifdef NEED_SEPARATE_REGISTER_STACK
291 if (descr
->p_userstack
== 0)
292 attr
->__stacksize
*= 2;
293 /* XXX This is awkward. The guard pages are in the middle of the
294 two stacks. We must count the guard size in the stack size since
295 otherwise the range of the stack area cannot be computed. */
296 attr
->__stacksize
+= attr
->__guardsize
;
298 #ifndef _STACK_GROWS_UP
299 attr
->__stackaddr
= (char *)(descr
+ 1);
301 # error __stackaddr not handled