Fix parameter name.
[glibc/pb-stable.git] / linuxthreads / attr.c
blob58a7b69f94f8f7a9b5e35b1a0d6355edfe107552
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;
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;
228 return 0;
230 weak_alias (__pthread_attr_getstacksize, pthread_attr_getstacksize)
232 int __pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr,
233 size_t stacksize)
235 int err;
237 if ((((uintptr_t) stackaddr)
238 & (__alignof__ (struct _pthread_descr_struct) - 1)) != 0)
239 err = EINVAL;
240 else
241 err = __pthread_attr_setstacksize (attr, stacksize);
242 if (err == 0)
244 #ifndef _STACK_GROWS_UP
245 attr->__stackaddr = (char *) stackaddr + stacksize;
246 #else
247 attr->__stackaddr = stackaddr;
248 #endif
249 attr->__stackaddr_set = 1;
252 return err;
254 weak_alias (__pthread_attr_setstack, pthread_attr_setstack)
256 int __pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr,
257 size_t *stacksize)
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;
264 #else
265 *stackaddr = attr->__stackaddr;
266 #endif
267 *stacksize = attr->__stacksize;
268 return 0;
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);
275 pthread_descr descr;
277 if (handle == NULL)
278 return ENOENT;
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)
288 return errno;
290 if (__sched_getparam (descr->p_pid,
291 (struct sched_param *) &attr->__schedparam) != 0)
292 return errno;
294 attr->__inheritsched = descr->p_inheritsched;
295 attr->__scope = PTHREAD_SCOPE_SYSTEM;
296 #ifdef _STACK_GROWS_DOWN
297 # ifdef USE_TLS
298 attr->__stacksize = descr->p_stackaddr - (char *)descr->p_guardaddr
299 - descr->p_guardsize;
300 # else
301 attr->__stacksize = (char *)(descr + 1) - (char *)descr->p_guardaddr
302 - descr->p_guardsize;
303 # endif
304 #else
305 # ifdef USE_TLS
306 attr->__stacksize = (char *)descr->p_guardaddr - descr->p_stackaddr;
307 # else
308 attr->__stacksize = (char *)descr->p_guardaddr - (char *)descr;
309 # endif
310 #endif
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;
320 #endif
321 #ifdef USE_TLS
322 attr->__stackaddr = descr->p_stackaddr;
323 #else
324 # ifndef _STACK_GROWS_UP
325 attr->__stackaddr = (char *)(descr + 1);
326 # else
327 attr->__stackaddr = (char *)descr;
328 # endif
329 #endif
331 return 0;