]> sourceware.org Git - glibc.git/blame - linuxthreads/attr.c
Update.
[glibc.git] / linuxthreads / attr.c
CommitLineData
5afdca00
UD
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. */
14
15/* Handling of thread attributes */
16
4959e310 17#include <errno.h>
ba9234d9 18#include <string.h>
5afdca00 19#include <unistd.h>
5d409851 20#include <sys/param.h>
234dd7a6 21#include <sys/resource.h>
5afdca00
UD
22#include "pthread.h"
23#include "internals.h"
ef7dddd0 24#include <shlib-compat.h>
5afdca00 25
5d409851
UD
26int __pthread_attr_init_2_1(pthread_attr_t *attr)
27{
28 size_t ps = __getpagesize ();
29
c70ca1fa
UD
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;
5d409851
UD
39 return 0;
40}
5d409851 41
ef7dddd0
UD
42versioned_symbol (libpthread, __pthread_attr_init_2_1, pthread_attr_init,
43 GLIBC_2_1);
44
45#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
5d409851 46int __pthread_attr_init_2_0(pthread_attr_t *attr)
5afdca00 47{
c70ca1fa
UD
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;
5afdca00
UD
53 return 0;
54}
41aefe41
UD
55compat_symbol (libpthread, __pthread_attr_init_2_0, pthread_attr_init,
56 GLIBC_2_0);
5d409851 57#endif
5afdca00 58
82f81a90 59int __pthread_attr_destroy(pthread_attr_t *attr)
5afdca00
UD
60{
61 return 0;
62}
82f81a90 63strong_alias (__pthread_attr_destroy, pthread_attr_destroy);
5afdca00 64
82f81a90 65int __pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
5afdca00
UD
66{
67 if (detachstate < PTHREAD_CREATE_JOINABLE ||
68 detachstate > PTHREAD_CREATE_DETACHED)
69 return EINVAL;
c70ca1fa 70 attr->__detachstate = detachstate;
5afdca00
UD
71 return 0;
72}
82f81a90 73strong_alias (__pthread_attr_setdetachstate, pthread_attr_setdetachstate);
5afdca00 74
82f81a90 75int __pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
5afdca00 76{
c70ca1fa 77 *detachstate = attr->__detachstate;
5afdca00
UD
78 return 0;
79}
82f81a90 80strong_alias (__pthread_attr_getdetachstate, pthread_attr_getdetachstate);
5afdca00 81
82f81a90
UD
82int __pthread_attr_setschedparam(pthread_attr_t *attr,
83 const struct sched_param *param)
5afdca00 84{
c70ca1fa
UD
85 int max_prio = __sched_get_priority_max(attr->__schedpolicy);
86 int min_prio = __sched_get_priority_min(attr->__schedpolicy);
5afdca00
UD
87
88 if (param->sched_priority < min_prio || param->sched_priority > max_prio)
89 return EINVAL;
c70ca1fa 90 memcpy (&attr->__schedparam, param, sizeof (struct sched_param));
5afdca00
UD
91 return 0;
92}
82f81a90 93strong_alias (__pthread_attr_setschedparam, pthread_attr_setschedparam);
5afdca00 94
82f81a90
UD
95int __pthread_attr_getschedparam(const pthread_attr_t *attr,
96 struct sched_param *param)
5afdca00 97{
c70ca1fa 98 memcpy (param, &attr->__schedparam, sizeof (struct sched_param));
5afdca00
UD
99 return 0;
100}
82f81a90 101strong_alias (__pthread_attr_getschedparam, pthread_attr_getschedparam);
5afdca00 102
82f81a90 103int __pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
5afdca00
UD
104{
105 if (policy != SCHED_OTHER && policy != SCHED_FIFO && policy != SCHED_RR)
106 return EINVAL;
c70ca1fa 107 attr->__schedpolicy = policy;
5afdca00
UD
108 return 0;
109}
82f81a90 110strong_alias (__pthread_attr_setschedpolicy, pthread_attr_setschedpolicy);
5afdca00 111
82f81a90 112int __pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
5afdca00 113{
c70ca1fa 114 *policy = attr->__schedpolicy;
5afdca00
UD
115 return 0;
116}
82f81a90 117strong_alias (__pthread_attr_getschedpolicy, pthread_attr_getschedpolicy);
5afdca00 118
82f81a90 119int __pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
5afdca00
UD
120{
121 if (inherit != PTHREAD_INHERIT_SCHED && inherit != PTHREAD_EXPLICIT_SCHED)
122 return EINVAL;
c70ca1fa 123 attr->__inheritsched = inherit;
5afdca00
UD
124 return 0;
125}
82f81a90 126strong_alias (__pthread_attr_setinheritsched, pthread_attr_setinheritsched);
5afdca00 127
82f81a90 128int __pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
5afdca00 129{
c70ca1fa 130 *inherit = attr->__inheritsched;
5afdca00
UD
131 return 0;
132}
82f81a90 133strong_alias (__pthread_attr_getinheritsched, pthread_attr_getinheritsched);
5afdca00 134
82f81a90 135int __pthread_attr_setscope(pthread_attr_t *attr, int scope)
5afdca00
UD
136{
137 switch (scope) {
138 case PTHREAD_SCOPE_SYSTEM:
c70ca1fa 139 attr->__scope = scope;
5afdca00
UD
140 return 0;
141 case PTHREAD_SCOPE_PROCESS:
142 return ENOTSUP;
143 default:
144 return EINVAL;
145 }
146}
82f81a90 147strong_alias (__pthread_attr_setscope, pthread_attr_setscope);
5afdca00 148
82f81a90 149int __pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
5afdca00 150{
c70ca1fa 151 *scope = attr->__scope;
5afdca00
UD
152 return 0;
153}
82f81a90 154strong_alias (__pthread_attr_getscope, pthread_attr_getscope);
5d409851
UD
155
156int __pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
157{
ddbf7fef 158 /* The guard size must not be larger than the stack itself */
c70ca1fa 159 if (guardsize >= attr->__stacksize) return EINVAL;
5d409851 160
c70ca1fa 161 attr->__guardsize = guardsize;
5d409851
UD
162
163 return 0;
164}
165weak_alias (__pthread_attr_setguardsize, pthread_attr_setguardsize)
166
167int __pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
168{
c70ca1fa 169 *guardsize = attr->__guardsize;
5d409851
UD
170 return 0;
171}
172weak_alias (__pthread_attr_getguardsize, pthread_attr_getguardsize)
173
174int __pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
175{
c70ca1fa
UD
176 attr->__stackaddr = stackaddr;
177 attr->__stackaddr_set = 1;
5d409851
UD
178 return 0;
179}
180weak_alias (__pthread_attr_setstackaddr, pthread_attr_setstackaddr)
181
e8a5cd43
UD
182link_warning (pthread_attr_setstackaddr,
183 "the use of `pthread_attr_setstackaddr' is deprecated, use `pthread_attr_setstack'")
184
5d409851
UD
185int __pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
186{
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. */
c70ca1fa 190 *stackaddr = attr->__stackaddr;
5d409851
UD
191 return 0;
192}
c6bd526f 193weak_alias (__pthread_attr_getstackaddr, pthread_attr_getstackaddr)
5d409851 194
e8a5cd43
UD
195link_warning (pthread_attr_getstackaddr,
196 "the use of `pthread_attr_getstackaddr' is deprecated, use `pthread_attr_getstack'")
197
198
5d409851
UD
199int __pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
200{
234dd7a6
UD
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)
a66f0958 206 __pthread_init_max_stacksize ();
234dd7a6
UD
207
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
215
3387a425
UD
216 /* We don't accept value smaller than PTHREAD_STACK_MIN. */
217 if (stacksize < PTHREAD_STACK_MIN)
5d409851
UD
218 return EINVAL;
219
c70ca1fa 220 attr->__stacksize = stacksize;
5d409851
UD
221 return 0;
222}
223weak_alias (__pthread_attr_setstacksize, pthread_attr_setstacksize)
224
225int __pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
226{
c70ca1fa 227 *stacksize = attr->__stacksize;
5d409851
UD
228 return 0;
229}
230weak_alias (__pthread_attr_getstacksize, pthread_attr_getstacksize)
b81c8961
UD
231
232int __pthread_attr_setstack (pthread_attr_t *attr, void *stackaddr,
233 size_t stacksize)
234{
235 int err;
236
237 if ((((uintptr_t) stackaddr)
1fb7dc3c 238 & (__alignof__ (struct _pthread_descr_struct) - 1)) != 0)
b81c8961
UD
239 err = EINVAL;
240 else
241 err = __pthread_attr_setstacksize (attr, stacksize);
242 if (err == 0)
243 {
e8a5cd43 244#ifndef _STACK_GROWS_UP
b81c8961
UD
245 attr->__stackaddr = (char *) stackaddr + stacksize;
246#else
247 attr->__stackaddr = stackaddr;
248#endif
249 attr->__stackaddr_set = 1;
250 }
251
252 return err;
253}
254weak_alias (__pthread_attr_setstack, pthread_attr_setstack)
255
256int __pthread_attr_getstack (const pthread_attr_t *attr, void **stackaddr,
257 size_t *stacksize)
258{
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. */
5a7d27d4
UD
262#ifndef _STACK_GROWS_UP
263 *stackaddr = (char *) attr->__stackaddr - attr->__stacksize;
264#else
b81c8961 265 *stackaddr = attr->__stackaddr;
5a7d27d4 266#endif
b81c8961
UD
267 *stacksize = attr->__stacksize;
268 return 0;
269}
270weak_alias (__pthread_attr_getstack, pthread_attr_getstack)
3bf927cb
UD
271
272int pthread_getattr_np (pthread_t thread, pthread_attr_t *attr)
273{
274 pthread_handle handle = thread_handle (thread);
275 pthread_descr descr;
3bf927cb
UD
276
277 if (handle == NULL)
278 return ENOENT;
279
280 descr = handle->h_descr;
281
282 attr->__detachstate = (descr->p_detached
283 ? PTHREAD_CREATE_DETACHED
284 : PTHREAD_CREATE_JOINABLE);
285
286 attr->__schedpolicy = __sched_getscheduler (descr->p_pid);
287 if (attr->__schedpolicy == -1)
288 return errno;
289
290 if (__sched_getparam (descr->p_pid,
291 (struct sched_param *) &attr->__schedparam) != 0)
292 return errno;
293
3bf927cb
UD
294 attr->__inheritsched = descr->p_inheritsched;
295 attr->__scope = PTHREAD_SCOPE_SYSTEM;
cc765c2a 296#ifdef _STACK_GROWS_DOWN
b6a0a996
UD
297# ifdef USE_TLS
298 attr->__stacksize = descr->p_stackaddr - (char *)descr->p_guardaddr
299 - descr->p_guardsize;
300# else
1fb7dc3c
UD
301 attr->__stacksize = (char *)(descr + 1) - (char *)descr->p_guardaddr
302 - descr->p_guardsize;
b6a0a996 303# endif
cc765c2a 304#else
b6a0a996
UD
305# ifdef USE_TLS
306 attr->__stacksize = (char *)descr->p_guardaddr - descr->p_stackaddr;
307# else
cc765c2a 308 attr->__stacksize = (char *)descr->p_guardaddr - (char *)descr;
b6a0a996 309# endif
cc765c2a 310#endif
3bf927cb
UD
311 attr->__guardsize = descr->p_guardsize;
312 attr->__stackaddr_set = descr->p_userstack;
313#ifdef NEED_SEPARATE_REGISTER_STACK
93a4b7ca
UD
314 if (descr->p_userstack == 0)
315 attr->__stacksize *= 2;
3bf927cb
UD
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. */
aeba9785 319 attr->__stacksize += attr->__guardsize;
3bf927cb 320#endif
b6a0a996
UD
321#ifdef USE_TLS
322 attr->__stackaddr = descr->p_stackaddr;
1fb7dc3c 323#else
b6a0a996
UD
324# ifndef _STACK_GROWS_UP
325 attr->__stackaddr = (char *)(descr + 1);
326# else
cc765c2a 327 attr->__stackaddr = (char *)descr;
b6a0a996 328# endif
1fb7dc3c 329#endif
3bf927cb
UD
330
331 return 0;
332}
This page took 0.233416 seconds and 5 git commands to generate.