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