__aeabi_ldivmod: fix sign logic
[minix.git] / lib / libmthread / attribute.c
blob0a96bbb2a9e6ed1fbf10fe674f062252b236bfd7
1 #include <minix/mthread.h>
2 #include "global.h"
3 #include "proto.h"
5 static struct __mthread_attr *va_front, *va_rear;
6 static void mthread_attr_add(mthread_attr_t *a);
7 static void mthread_attr_remove(mthread_attr_t *a);
8 static int mthread_attr_valid(mthread_attr_t *a);
10 /*===========================================================================*
11 * mthread_init_valid_attributes *
12 *===========================================================================*/
13 void mthread_init_valid_attributes(void)
15 /* Initialize list of valid attributs */
16 va_front = va_rear = NULL;
20 /*===========================================================================*
21 * mthread_attr_add *
22 *===========================================================================*/
23 static void mthread_attr_add(a)
24 mthread_attr_t *a;
26 /* Add attribute to list of valid, initialized attributes */
28 if (va_front == NULL) { /* Empty list */
29 va_front = *a;
30 (*a)->ma_prev = NULL;
31 } else {
32 va_rear->ma_next = *a;
33 (*a)->ma_prev = va_rear;
36 (*a)->ma_next = NULL;
37 va_rear = *a;
41 /*===========================================================================*
42 * mthread_attr_destroy *
43 *===========================================================================*/
44 int mthread_attr_destroy(attr)
45 mthread_attr_t *attr;
47 /* Invalidate attribute and deallocate resources. */
49 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
51 if (attr == NULL)
52 return(EINVAL);
54 if (!mthread_attr_valid(attr))
55 return(EINVAL);
57 /* Valide attribute; invalidate it */
58 mthread_attr_remove(attr);
59 free(*attr);
60 *attr = NULL;
62 return(0);
66 /*===========================================================================*
67 * mthread_attr_init *
68 *===========================================================================*/
69 int mthread_attr_init(attr)
70 mthread_attr_t *attr; /* Attribute */
72 /* Initialize the attribute to a known state. */
73 struct __mthread_attr *a;
75 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
77 if (attr == NULL)
78 return(EAGAIN);
79 else if (mthread_attr_valid(attr))
80 return(EBUSY);
82 if ((a = malloc(sizeof(struct __mthread_attr))) == NULL)
83 return(-1);
85 a->ma_detachstate = MTHREAD_CREATE_JOINABLE;
86 a->ma_stackaddr = NULL;
87 a->ma_stacksize = (size_t) 0;
89 *attr = (mthread_attr_t) a;
90 mthread_attr_add(attr); /* Validate attribute: attribute now in use */
92 return(0);
95 /*===========================================================================*
96 * mthread_attr_getdetachstate *
97 *===========================================================================*/
98 int mthread_attr_getdetachstate(attr, detachstate)
99 mthread_attr_t *attr;
100 int *detachstate;
102 /* Get detachstate of a thread attribute */
103 struct __mthread_attr *a;
105 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
107 if (attr == NULL)
108 return(EINVAL);
110 a = (struct __mthread_attr *) *attr;
111 if (!mthread_attr_valid(attr))
112 return(EINVAL);
114 *detachstate = a->ma_detachstate;
116 return(0);
120 /*===========================================================================*
121 * mthread_attr_setdetachstate *
122 *===========================================================================*/
123 int mthread_attr_setdetachstate(attr, detachstate)
124 mthread_attr_t *attr;
125 int detachstate;
127 /* Set detachstate of a thread attribute */
128 struct __mthread_attr *a;
130 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
132 if (attr == NULL)
133 return(EINVAL);
135 a = (struct __mthread_attr *) *attr;
136 if (!mthread_attr_valid(attr))
137 return(EINVAL);
138 else if(detachstate != MTHREAD_CREATE_JOINABLE &&
139 detachstate != MTHREAD_CREATE_DETACHED)
140 return(EINVAL);
142 a->ma_detachstate = detachstate;
144 return(0);
148 /*===========================================================================*
149 * mthread_attr_getstack *
150 *===========================================================================*/
151 int mthread_attr_getstack(attr, stackaddr, stacksize)
152 mthread_attr_t *attr;
153 void **stackaddr;
154 size_t *stacksize;
156 /* Get stack attribute */
157 struct __mthread_attr *a;
159 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
161 if (attr == NULL)
162 return(EINVAL);
164 a = (struct __mthread_attr *) *attr;
165 if (!mthread_attr_valid(attr))
166 return(EINVAL);
168 *stackaddr = a->ma_stackaddr;
169 *stacksize = a->ma_stacksize;
171 return(0);
175 /*===========================================================================*
176 * mthread_attr_getstacksize *
177 *===========================================================================*/
178 int mthread_attr_getstacksize(attr, stacksize)
179 mthread_attr_t *attr;
180 size_t *stacksize;
182 /* Get stack size attribute */
183 struct __mthread_attr *a;
185 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
187 if (attr == NULL)
188 return(EINVAL);
190 a = (struct __mthread_attr *) *attr;
191 if (!mthread_attr_valid(attr))
192 return(EINVAL);
194 *stacksize = a->ma_stacksize;
196 return(0);
200 /*===========================================================================*
201 * mthread_attr_setstack *
202 *===========================================================================*/
203 int mthread_attr_setstack(attr, stackaddr, stacksize)
204 mthread_attr_t *attr;
205 void *stackaddr;
206 size_t stacksize;
208 /* Set stack attribute */
209 struct __mthread_attr *a;
211 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
213 if (attr == NULL)
214 return(EINVAL);
216 a = (struct __mthread_attr *) *attr;
217 if (!mthread_attr_valid(attr) || stacksize < MTHREAD_STACK_MIN)
218 return(EINVAL);
220 /* We don't care about address alignment (POSIX standard). The ucontext
221 * system calls will make sure that the provided stack will be aligned (at
222 * the cost of some memory if needed).
225 a->ma_stackaddr = stackaddr;
226 a->ma_stacksize = stacksize;
228 return(0);
232 /*===========================================================================*
233 * mthread_attr_setstacksize *
234 *===========================================================================*/
235 int mthread_attr_setstacksize(attr, stacksize)
236 mthread_attr_t *attr;
237 size_t stacksize;
239 /* Set stack size attribute */
240 struct __mthread_attr *a;
242 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
244 if (attr == NULL)
245 return(EINVAL);
247 a = (struct __mthread_attr *) *attr;
248 if (!mthread_attr_valid(attr) || stacksize < MTHREAD_STACK_MIN)
249 return(EINVAL);
251 a->ma_stacksize = stacksize;
253 return(0);
257 /*===========================================================================*
258 * mthread_attr_remove *
259 *===========================================================================*/
260 static void mthread_attr_remove(a)
261 mthread_attr_t *a;
263 /* Remove attribute from list of valid, initialized attributes */
265 if ((*a)->ma_prev == NULL)
266 va_front = (*a)->ma_next;
267 else
268 (*a)->ma_prev->ma_next = (*a)->ma_next;
270 if ((*a)->ma_next == NULL)
271 va_rear = (*a)->ma_prev;
272 else
273 (*a)->ma_next->ma_prev = (*a)->ma_prev;
277 /*===========================================================================*
278 * mthread_attr_valid *
279 *===========================================================================*/
280 static int mthread_attr_valid(a)
281 mthread_attr_t *a;
283 /* Check to see if attribute is on the list of valid attributes */
284 struct __mthread_attr *loopitem;
286 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
288 loopitem = va_front;
290 while (loopitem != NULL) {
291 if (loopitem == *a)
292 return(1);
294 loopitem = loopitem->ma_next;
297 return(0);
301 /*===========================================================================*
302 * mthread_attr_verify *
303 *===========================================================================*/
304 #ifdef MDEBUG
305 int mthread_attr_verify(void)
307 /* Return true when no attributes are in use */
308 struct __mthread_attr *loopitem;
310 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
312 loopitem = va_front;
314 while (loopitem != NULL) {
315 loopitem = loopitem->ma_next;
316 return(0);
319 return(1);
321 #endif