xref: /haiku/src/system/libroot/posix/pthread/pthread_attr.c (revision 0f9ffb37c166a9d9257044c8937f6450f4257b75)
1 /*
2  * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3  * Copyright 2008, Axel Dörfler, axeld@pinc-software.de.
4  * Copyright 2006, Jérôme Duval. All rights reserved.
5  * Distributed under the terms of the MIT License.
6  */
7 
8 
9 #include <pthread.h>
10 #include "pthread_private.h"
11 
12 #include <limits.h>
13 #include <stdlib.h>
14 
15 #include <Debug.h>
16 
17 #include <syscalls.h>
18 #include <thread_defs.h>
19 
20 
21 int __pthread_attr_get_np(pthread_t thread, pthread_attr_t *_attr);
22 int __pthread_getattr_np(pthread_t thread, pthread_attr_t *_attr);
23 
24 
25 int
26 pthread_attr_init(pthread_attr_t *_attr)
27 {
28 	pthread_attr *attr;
29 
30 	if (_attr == NULL)
31 		return B_BAD_VALUE;
32 
33 	attr = (pthread_attr *)malloc(sizeof(pthread_attr));
34 	if (attr == NULL)
35 		return B_NO_MEMORY;
36 
37 	attr->detach_state = PTHREAD_CREATE_JOINABLE;
38 	attr->sched_priority = B_NORMAL_PRIORITY;
39 	attr->stack_size = USER_STACK_SIZE;
40 	attr->guard_size = USER_STACK_GUARD_SIZE;
41 	attr->stack_address = NULL;
42 
43 	*_attr = attr;
44 	return B_OK;
45 }
46 
47 
48 int
49 pthread_attr_destroy(pthread_attr_t *_attr)
50 {
51 	pthread_attr *attr;
52 
53 	if (_attr == NULL || (attr = *_attr) == NULL)
54 		return B_BAD_VALUE;
55 
56 	*_attr = NULL;
57 	free(attr);
58 
59 	return B_OK;
60 }
61 
62 
63 int
64 pthread_attr_getdetachstate(const pthread_attr_t *_attr, int *state)
65 {
66 	pthread_attr *attr;
67 
68 	if (_attr == NULL || (attr = *_attr) == NULL || state == NULL)
69 		return B_BAD_VALUE;
70 
71 	*state = attr->detach_state;
72 
73 	return B_OK;
74 }
75 
76 
77 int
78 pthread_attr_setdetachstate(pthread_attr_t *_attr, int state)
79 {
80 	pthread_attr *attr;
81 
82 	if (_attr == NULL || (attr = *_attr) == NULL)
83 		return B_BAD_VALUE;
84 
85 	if (state != PTHREAD_CREATE_JOINABLE && state != PTHREAD_CREATE_DETACHED)
86 		return B_BAD_VALUE;
87 
88 	attr->detach_state = state;
89 
90 	return B_OK;
91 }
92 
93 
94 int
95 pthread_attr_getstacksize(const pthread_attr_t *_attr, size_t *stacksize)
96 {
97 	pthread_attr *attr;
98 
99 	if (_attr == NULL || (attr = *_attr) == NULL || stacksize == NULL)
100 		return B_BAD_VALUE;
101 
102 	*stacksize = attr->stack_size;
103 
104 	return 0;
105 }
106 
107 
108 int
109 pthread_attr_setstacksize(pthread_attr_t *_attr, size_t stacksize)
110 {
111 	pthread_attr *attr;
112 
113 	if (_attr == NULL || (attr = *_attr) == NULL)
114 		return B_BAD_VALUE;
115 
116 	STATIC_ASSERT(PTHREAD_STACK_MIN >= MIN_USER_STACK_SIZE
117 		&& PTHREAD_STACK_MIN <= MAX_USER_STACK_SIZE);
118 	if (stacksize < PTHREAD_STACK_MIN || stacksize > MAX_USER_STACK_SIZE)
119 		return B_BAD_VALUE;
120 
121 	attr->stack_size = stacksize;
122 
123 	return 0;
124 }
125 
126 
127 int
128 pthread_attr_getscope(const pthread_attr_t *attr, int *contentionScope)
129 {
130 	if (attr == NULL || contentionScope == NULL)
131 		return EINVAL;
132 
133 	*contentionScope = PTHREAD_SCOPE_SYSTEM;
134 	return 0;
135 }
136 
137 
138 int
139 pthread_attr_setscope(pthread_attr_t *attr, int contentionScope)
140 {
141 	if (attr == NULL)
142 		return EINVAL;
143 
144 	if (contentionScope != PTHREAD_SCOPE_SYSTEM)
145 		return ENOTSUP;
146 
147 	return 0;
148 }
149 
150 
151 int
152 pthread_attr_setschedparam(pthread_attr_t *attr,
153 	const struct sched_param *param)
154 {
155 	if (attr == NULL || param == NULL)
156 		return EINVAL;
157 
158 	(*attr)->sched_priority = param->sched_priority;
159 
160 	return 0;
161 }
162 
163 
164 int
165 pthread_attr_getschedparam(const pthread_attr_t *attr,
166 	struct sched_param *param)
167 {
168 	if (attr == NULL || param == NULL)
169 		return EINVAL;
170 
171 	param->sched_priority = (*attr)->sched_priority;
172 
173 	return 0;
174 }
175 
176 
177 int
178 pthread_attr_getguardsize(const pthread_attr_t *_attr, size_t *guardsize)
179 {
180 	pthread_attr *attr;
181 
182 	if (_attr == NULL || (attr = *_attr) == NULL || guardsize == NULL)
183 		return B_BAD_VALUE;
184 
185 	*guardsize = attr->guard_size;
186 
187 	return 0;
188 }
189 
190 
191 int
192 pthread_attr_setguardsize(pthread_attr_t *_attr, size_t guardsize)
193 {
194 	pthread_attr *attr;
195 
196 	if (_attr == NULL || (attr = *_attr) == NULL)
197 		return B_BAD_VALUE;
198 
199 	attr->guard_size = guardsize;
200 
201 	return 0;
202 }
203 
204 
205 int
206 pthread_attr_getstack(const pthread_attr_t *_attr, void **stackaddr,
207 	size_t *stacksize)
208 {
209 	pthread_attr *attr;
210 
211 	if (_attr == NULL || (attr = *_attr) == NULL || stackaddr == NULL
212 		|| stacksize == NULL) {
213 		return B_BAD_VALUE;
214 	}
215 
216 	*stacksize = attr->stack_size;
217 	*stackaddr = attr->stack_address;
218 
219 	return 0;
220 }
221 
222 
223 int
224 pthread_attr_setstack(pthread_attr_t *_attr, void *stackaddr,
225 	size_t stacksize)
226 {
227 	pthread_attr *attr;
228 
229 	if (_attr == NULL || (attr = *_attr) == NULL)
230 		return B_BAD_VALUE;
231 
232 	STATIC_ASSERT(PTHREAD_STACK_MIN >= MIN_USER_STACK_SIZE
233 		&& PTHREAD_STACK_MIN <= MAX_USER_STACK_SIZE);
234 	if (stacksize < PTHREAD_STACK_MIN || stacksize > MAX_USER_STACK_SIZE)
235 		return B_BAD_VALUE;
236 
237 	attr->stack_size = stacksize;
238 	attr->stack_address = stackaddr;
239 
240 	return 0;
241 }
242 
243 
244 int
245 __pthread_attr_get_np(pthread_t thread, pthread_attr_t *_attr)
246 {
247 	pthread_attr *attr;
248 	status_t status;
249 	thread_info info;
250 
251 	if (_attr == NULL || (attr = *_attr) == NULL)
252 		return B_BAD_VALUE;
253 
254 	status = _kern_get_thread_info(thread->id, &info);
255 	if (status == B_BAD_THREAD_ID)
256 		return ESRCH;
257 
258 	if ((thread->flags & THREAD_DETACHED) != 0)
259 		attr->detach_state = PTHREAD_CREATE_DETACHED;
260 	else
261 		attr->detach_state = PTHREAD_CREATE_JOINABLE;
262 	attr->sched_priority = info.priority;
263 	attr->stack_address = info.stack_base;
264 	attr->stack_size = (size_t)info.stack_end - (size_t)info.stack_base;
265 	// not in thread_info
266 	attr->guard_size = 0;
267 
268 	return 0;
269 }
270 
271 
272 int
273 __pthread_getattr_np(pthread_t thread, pthread_attr_t *_attr)
274 {
275 	int err = pthread_attr_init(_attr);
276 	if (err == 0)
277 		err = __pthread_attr_get_np(thread, _attr);
278 	return err;
279 }
280 
281 
282 B_DEFINE_WEAK_ALIAS(__pthread_getattr_np, pthread_getattr_np);
283 B_DEFINE_WEAK_ALIAS(__pthread_attr_get_np, pthread_attr_get_np);
284 
285