Finish user stack support. Change locking code to be safe in
[kopensolaris-gnu/glibc.git] / linuxthreads / attr.c
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
17 #include <unistd.h>
18 #include <sys/param.h>
19 #include "pthread.h"
20 #include "internals.h"
21
22 int __pthread_attr_init_2_1(pthread_attr_t *attr)
23 {
24   size_t ps = __getpagesize ();
25
26   attr->detachstate = PTHREAD_CREATE_JOINABLE;
27   attr->schedpolicy = SCHED_OTHER;
28   attr->schedparam.sched_priority = 0;
29   attr->inheritsched = PTHREAD_EXPLICIT_SCHED;
30   attr->scope = PTHREAD_SCOPE_SYSTEM;
31   attr->guardsize = ps;
32   attr->stackaddr = NULL;
33   attr->stackaddr_set = 0;
34   attr->stacksize = STACK_SIZE - ps;
35   return 0;
36 }
37 #if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
38 default_symbol_version (__pthread_attr_init_2_1, pthread_attr_init, GLIBC_2.1);
39
40 int __pthread_attr_init_2_0(pthread_attr_t *attr)
41 {
42   attr->detachstate = PTHREAD_CREATE_JOINABLE;
43   attr->schedpolicy = SCHED_OTHER;
44   attr->schedparam.sched_priority = 0;
45   attr->inheritsched = PTHREAD_EXPLICIT_SCHED;
46   attr->scope = PTHREAD_SCOPE_SYSTEM;
47   return 0;
48 }
49 symbol_version (__pthread_attr_init_2_0, pthread_attr_init, GLIBC_2.0);
50 #else
51 strong_alias (__pthread_attr_init_2_1, pthread_attr_init)
52 #endif
53
54 int pthread_attr_destroy(pthread_attr_t *attr)
55 {
56   return 0;
57 }
58
59 int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate)
60 {
61   if (detachstate < PTHREAD_CREATE_JOINABLE ||
62       detachstate > PTHREAD_CREATE_DETACHED)
63     return EINVAL;
64   attr->detachstate = detachstate;
65   return 0;
66 }
67
68 int pthread_attr_getdetachstate(const pthread_attr_t *attr, int *detachstate)
69 {
70   *detachstate = attr->detachstate;
71   return 0;
72 }
73
74 int pthread_attr_setschedparam(pthread_attr_t *attr,
75                                const struct sched_param *param)
76 {
77   int max_prio = __sched_get_priority_max(attr->schedpolicy);
78   int min_prio = __sched_get_priority_min(attr->schedpolicy);
79
80   if (param->sched_priority < min_prio || param->sched_priority > max_prio)
81     return EINVAL;
82   attr->schedparam = *param;
83   return 0;
84 }
85
86 int pthread_attr_getschedparam(const pthread_attr_t *attr,
87                                struct sched_param *param)
88 {
89   *param = attr->schedparam;
90   return 0;
91 }
92
93 int pthread_attr_setschedpolicy(pthread_attr_t *attr, int policy)
94 {
95   if (policy != SCHED_OTHER && policy != SCHED_FIFO && policy != SCHED_RR)
96     return EINVAL;
97   if (policy != SCHED_OTHER && geteuid() != 0)
98     return ENOTSUP;
99   attr->schedpolicy = policy;
100   return 0;
101 }
102
103 int pthread_attr_getschedpolicy(const pthread_attr_t *attr, int *policy)
104 {
105   *policy = attr->schedpolicy;
106   return 0;
107 }
108
109 int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit)
110 {
111   if (inherit != PTHREAD_INHERIT_SCHED && inherit != PTHREAD_EXPLICIT_SCHED)
112     return EINVAL;
113   attr->inheritsched = inherit;
114   return 0;
115 }
116
117 int pthread_attr_getinheritsched(const pthread_attr_t *attr, int *inherit)
118 {
119   *inherit = attr->inheritsched;
120   return 0;
121 }
122
123 int pthread_attr_setscope(pthread_attr_t *attr, int scope)
124 {
125   switch (scope) {
126   case PTHREAD_SCOPE_SYSTEM:
127     attr->scope = scope;
128     return 0;
129   case PTHREAD_SCOPE_PROCESS:
130     return ENOTSUP;
131   default:
132     return EINVAL;
133   }
134 }
135
136 int pthread_attr_getscope(const pthread_attr_t *attr, int *scope)
137 {
138   *scope = attr->scope;
139   return 0;
140 }
141
142 int __pthread_attr_setguardsize(pthread_attr_t *attr, size_t guardsize)
143 {
144   size_t ps = __getpagesize ();
145
146   /* First round up the guard size.  */
147   guardsize = roundup (guardsize, ps);
148
149   /* The current implementation of LinuxThreads allocates 2MB stack space
150      for each thread.  So the maximum guardsize is 2MB - pagesize.  */
151   if (guardsize >= STACK_SIZE - ps)
152     return EINVAL;
153
154   attr->guardsize = guardsize;
155
156   return 0;
157 }
158 weak_alias (__pthread_attr_setguardsize, pthread_attr_setguardsize)
159
160 int __pthread_attr_getguardsize(const pthread_attr_t *attr, size_t *guardsize)
161 {
162   *guardsize = attr->guardsize;
163   return 0;
164 }
165 weak_alias (__pthread_attr_getguardsize, pthread_attr_getguardsize)
166
167 int __pthread_attr_setstackaddr(pthread_attr_t *attr, void *stackaddr)
168 {
169   attr->stackaddr = stackaddr;
170   attr->stackaddr_set = 1;
171   return 0;
172 }
173 weak_alias (__pthread_attr_setstackaddr, pthread_attr_setstackaddr)
174
175 int __pthread_attr_getstackaddr(const pthread_attr_t *attr, void **stackaddr)
176 {
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;
181   return 0;
182 }
183 weak_alias (__pthread_attr_getstackaddr, pthread_attr_getstackaddr)
184
185 int __pthread_attr_setstacksize(pthread_attr_t *attr, size_t stacksize)
186 {
187   /* We don't accept value smaller than PTHREAD_STACK_MIN.  */
188   if (stacksize < PTHREAD_STACK_MIN)
189     return EINVAL;
190
191   attr->stacksize = stacksize;
192   return 0;
193 }
194 weak_alias (__pthread_attr_setstacksize, pthread_attr_setstacksize)
195
196 int __pthread_attr_getstacksize(const pthread_attr_t *attr, size_t *stacksize)
197 {
198   *stacksize = attr->stacksize;
199   return 0;
200 }
201 weak_alias (__pthread_attr_getstacksize, pthread_attr_getstacksize)