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>
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
;
42 versioned_symbol (libpthread
, __pthread_attr_init_2_1
, pthread_attr_init
,
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
;
55 compat_symbol (libpthread
, __pthread_attr_init_2_0
, pthread_attr_init
,
59 int __pthread_attr_destroy(pthread_attr_t
*attr
)
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
)
70 attr
->__detachstate
= detachstate
;
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
;
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
)
90 memcpy (&attr
->__schedparam
, param
, sizeof (struct sched_param
));
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
));
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
)
107 attr
->__schedpolicy
= policy
;
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
;
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
)
123 attr
->__inheritsched
= inherit
;
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
;
133 strong_alias (__pthread_attr_getinheritsched
, pthread_attr_getinheritsched
);
135 int __pthread_attr_setscope(pthread_attr_t
*attr
, int scope
)
138 case PTHREAD_SCOPE_SYSTEM
:
139 attr
->__scope
= scope
;
141 case PTHREAD_SCOPE_PROCESS
:
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
;
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
;
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
;
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;
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
;
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
)
211 /* We have a fixed size limit. */
212 if (stacksize
> STACK_SIZE
)
216 /* We don't accept value smaller than PTHREAD_STACK_MIN. */
217 if (stacksize
< PTHREAD_STACK_MIN
)
220 attr
->__stacksize
= stacksize
;
223 weak_alias (__pthread_attr_setstacksize
, pthread_attr_setstacksize
)
225 int __pthread_attr_getstacksize(const pthread_attr_t
*attr
, size_t *stacksize
)
227 *stacksize
= attr
->__stacksize
;
230 weak_alias (__pthread_attr_getstacksize
, pthread_attr_getstacksize
)
232 int __pthread_attr_setstack (pthread_attr_t
*attr
, void *stackaddr
,
237 if ((((uintptr_t) stackaddr
)
238 & (__alignof__ (struct _pthread_descr_struct
) - 1)) != 0)
241 err
= __pthread_attr_setstacksize (attr
, stacksize
);
244 #ifndef _STACK_GROWS_UP
245 attr
->__stackaddr
= (char *) stackaddr
+ stacksize
;
247 attr
->__stackaddr
= stackaddr
;
249 attr
->__stackaddr_set
= 1;
254 weak_alias (__pthread_attr_setstack
, pthread_attr_setstack
)
256 int __pthread_attr_getstack (const pthread_attr_t
*attr
, void **stackaddr
,
259 /* XXX This function has a stupid definition. The standard specifies
260 no error value but what is if no stack address was set? We simply
261 return the value we have in the member. */
262 #ifndef _STACK_GROWS_UP
263 *stackaddr
= (char *) attr
->__stackaddr
- attr
->__stacksize
;
265 *stackaddr
= attr
->__stackaddr
;
267 *stacksize
= attr
->__stacksize
;
270 weak_alias (__pthread_attr_getstack
, pthread_attr_getstack
)
272 int pthread_getattr_np (pthread_t thread
, pthread_attr_t
*attr
)
274 pthread_handle handle
= thread_handle (thread
);
280 descr
= handle
->h_descr
;
282 attr
->__detachstate
= (descr
->p_detached
283 ? PTHREAD_CREATE_DETACHED
284 : PTHREAD_CREATE_JOINABLE
);
286 attr
->__schedpolicy
= __sched_getscheduler (descr
->p_pid
);
287 if (attr
->__schedpolicy
== -1)
290 if (__sched_getparam (descr
->p_pid
,
291 (struct sched_param
*) &attr
->__schedparam
) != 0)
294 attr
->__inheritsched
= descr
->p_inheritsched
;
295 attr
->__scope
= PTHREAD_SCOPE_SYSTEM
;
296 #ifdef _STACK_GROWS_DOWN
298 attr
->__stacksize
= descr
->p_stackaddr
- (char *)descr
->p_guardaddr
299 - descr
->p_guardsize
;
301 attr
->__stacksize
= (char *)(descr
+ 1) - (char *)descr
->p_guardaddr
302 - descr
->p_guardsize
;
306 attr
->__stacksize
= (char *)descr
->p_guardaddr
- descr
->p_stackaddr
;
308 attr
->__stacksize
= (char *)descr
->p_guardaddr
- (char *)descr
;
311 attr
->__guardsize
= descr
->p_guardsize
;
312 attr
->__stackaddr_set
= descr
->p_userstack
;
313 #ifdef NEED_SEPARATE_REGISTER_STACK
314 if (descr
->p_userstack
== 0)
315 attr
->__stacksize
*= 2;
316 /* XXX This is awkward. The guard pages are in the middle of the
317 two stacks. We must count the guard size in the stack size since
318 otherwise the range of the stack area cannot be computed. */
319 attr
->__stacksize
+= attr
->__guardsize
;
322 attr
->__stackaddr
= descr
->p_stackaddr
;
324 # ifndef _STACK_GROWS_UP
325 attr
->__stackaddr
= (char *)(descr
+ 1);
327 attr
->__stackaddr
= (char *)descr
;