1 #include <minix/mthread.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 /*===========================================================================*
22 *===========================================================================*/
23 static void mthread_attr_add(a
)
26 /* Add attribute to list of valid, initialized attributes */
28 if (va_front
== NULL
) { /* Empty list */
32 va_rear
->ma_next
= *a
;
33 (*a
)->ma_prev
= va_rear
;
41 /*===========================================================================*
42 * mthread_attr_destroy *
43 *===========================================================================*/
44 int mthread_attr_destroy(attr
)
47 /* Invalidate attribute and deallocate resources. */
49 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
54 if (!mthread_attr_valid(attr
))
57 /* Valide attribute; invalidate it */
58 mthread_attr_remove(attr
);
66 /*===========================================================================*
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 */
79 else if (mthread_attr_valid(attr
))
82 if ((a
= malloc(sizeof(struct __mthread_attr
))) == NULL
)
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 */
95 /*===========================================================================*
96 * mthread_attr_getdetachstate *
97 *===========================================================================*/
98 int mthread_attr_getdetachstate(attr
, detachstate
)
102 /* Get detachstate of a thread attribute */
103 struct __mthread_attr
*a
;
105 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
110 a
= (struct __mthread_attr
*) *attr
;
111 if (!mthread_attr_valid(attr
))
114 *detachstate
= a
->ma_detachstate
;
120 /*===========================================================================*
121 * mthread_attr_setdetachstate *
122 *===========================================================================*/
123 int mthread_attr_setdetachstate(attr
, detachstate
)
124 mthread_attr_t
*attr
;
127 /* Set detachstate of a thread attribute */
128 struct __mthread_attr
*a
;
130 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
135 a
= (struct __mthread_attr
*) *attr
;
136 if (!mthread_attr_valid(attr
))
138 else if(detachstate
!= MTHREAD_CREATE_JOINABLE
&&
139 detachstate
!= MTHREAD_CREATE_DETACHED
)
142 a
->ma_detachstate
= detachstate
;
148 /*===========================================================================*
149 * mthread_attr_getstack *
150 *===========================================================================*/
151 int mthread_attr_getstack(attr
, stackaddr
, stacksize
)
152 mthread_attr_t
*attr
;
156 /* Get stack attribute */
157 struct __mthread_attr
*a
;
159 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
164 a
= (struct __mthread_attr
*) *attr
;
165 if (!mthread_attr_valid(attr
))
168 *stackaddr
= a
->ma_stackaddr
;
169 *stacksize
= a
->ma_stacksize
;
175 /*===========================================================================*
176 * mthread_attr_getstacksize *
177 *===========================================================================*/
178 int mthread_attr_getstacksize(attr
, stacksize
)
179 mthread_attr_t
*attr
;
182 /* Get stack size attribute */
183 struct __mthread_attr
*a
;
185 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
190 a
= (struct __mthread_attr
*) *attr
;
191 if (!mthread_attr_valid(attr
))
194 *stacksize
= a
->ma_stacksize
;
200 /*===========================================================================*
201 * mthread_attr_setstack *
202 *===========================================================================*/
203 int mthread_attr_setstack(attr
, stackaddr
, stacksize
)
204 mthread_attr_t
*attr
;
208 /* Set stack attribute */
209 struct __mthread_attr
*a
;
211 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
216 a
= (struct __mthread_attr
*) *attr
;
217 if (!mthread_attr_valid(attr
) || stacksize
< MTHREAD_STACK_MIN
)
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
;
232 /*===========================================================================*
233 * mthread_attr_setstacksize *
234 *===========================================================================*/
235 int mthread_attr_setstacksize(attr
, stacksize
)
236 mthread_attr_t
*attr
;
239 /* Set stack size attribute */
240 struct __mthread_attr
*a
;
242 MTHREAD_CHECK_INIT(); /* Make sure mthreads is initialized */
247 a
= (struct __mthread_attr
*) *attr
;
248 if (!mthread_attr_valid(attr
) || stacksize
< MTHREAD_STACK_MIN
)
251 a
->ma_stacksize
= stacksize
;
257 /*===========================================================================*
258 * mthread_attr_remove *
259 *===========================================================================*/
260 static void mthread_attr_remove(a
)
263 /* Remove attribute from list of valid, initialized attributes */
265 if ((*a
)->ma_prev
== NULL
)
266 va_front
= (*a
)->ma_next
;
268 (*a
)->ma_prev
->ma_next
= (*a
)->ma_next
;
270 if ((*a
)->ma_next
== NULL
)
271 va_rear
= (*a
)->ma_prev
;
273 (*a
)->ma_next
->ma_prev
= (*a
)->ma_prev
;
277 /*===========================================================================*
278 * mthread_attr_valid *
279 *===========================================================================*/
280 static int mthread_attr_valid(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 */
290 while (loopitem
!= NULL
) {
294 loopitem
= loopitem
->ma_next
;
301 /*===========================================================================*
302 * mthread_attr_verify *
303 *===========================================================================*/
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 */
314 while (loopitem
!= NULL
) {
315 loopitem
= loopitem
->ma_next
;