custom message type for VM_INFO
[minix3.git] / lib / libmthread / attribute.c
blobfe63352cc89c5ea0994a380495fd22f0fce76e1f
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 if (attr == NULL)
50 return(EINVAL);
52 if (!mthread_attr_valid(attr))
53 return(EINVAL);
55 /* Valide attribute; invalidate it */
56 mthread_attr_remove(attr);
57 free(*attr);
58 *attr = NULL;
60 return(0);
64 /*===========================================================================*
65 * mthread_attr_init *
66 *===========================================================================*/
67 int mthread_attr_init(attr)
68 mthread_attr_t *attr; /* Attribute */
70 /* Initialize the attribute to a known state. */
71 struct __mthread_attr *a;
73 if (attr == NULL)
74 return(EAGAIN);
75 else if (mthread_attr_valid(attr))
76 return(EBUSY);
78 if ((a = malloc(sizeof(struct __mthread_attr))) == NULL)
79 return(-1);
81 a->ma_detachstate = MTHREAD_CREATE_JOINABLE;
82 a->ma_stackaddr = NULL;
83 a->ma_stacksize = (size_t) 0;
85 *attr = (mthread_attr_t) a;
86 mthread_attr_add(attr); /* Validate attribute: attribute now in use */
88 return(0);
91 /*===========================================================================*
92 * mthread_attr_getdetachstate *
93 *===========================================================================*/
94 int mthread_attr_getdetachstate(attr, detachstate)
95 mthread_attr_t *attr;
96 int *detachstate;
98 /* Get detachstate of a thread attribute */
99 struct __mthread_attr *a;
101 if (attr == NULL)
102 return(EINVAL);
104 a = (struct __mthread_attr *) *attr;
105 if (!mthread_attr_valid(attr))
106 return(EINVAL);
108 *detachstate = a->ma_detachstate;
110 return(0);
114 /*===========================================================================*
115 * mthread_attr_setdetachstate *
116 *===========================================================================*/
117 int mthread_attr_setdetachstate(attr, detachstate)
118 mthread_attr_t *attr;
119 int detachstate;
121 /* Set detachstate of a thread attribute */
122 struct __mthread_attr *a;
124 if (attr == NULL)
125 return(EINVAL);
127 a = (struct __mthread_attr *) *attr;
128 if (!mthread_attr_valid(attr))
129 return(EINVAL);
130 else if(detachstate != MTHREAD_CREATE_JOINABLE &&
131 detachstate != MTHREAD_CREATE_DETACHED)
132 return(EINVAL);
134 a->ma_detachstate = detachstate;
136 return(0);
140 /*===========================================================================*
141 * mthread_attr_getstack *
142 *===========================================================================*/
143 int mthread_attr_getstack(attr, stackaddr, stacksize)
144 mthread_attr_t *attr;
145 void **stackaddr;
146 size_t *stacksize;
148 /* Get stack attribute */
149 struct __mthread_attr *a;
151 if (attr == NULL)
152 return(EINVAL);
154 a = (struct __mthread_attr *) *attr;
155 if (!mthread_attr_valid(attr))
156 return(EINVAL);
158 *stackaddr = a->ma_stackaddr;
159 *stacksize = a->ma_stacksize;
161 return(0);
165 /*===========================================================================*
166 * mthread_attr_getstacksize *
167 *===========================================================================*/
168 int mthread_attr_getstacksize(attr, stacksize)
169 mthread_attr_t *attr;
170 size_t *stacksize;
172 /* Get stack size attribute */
173 struct __mthread_attr *a;
175 if (attr == NULL)
176 return(EINVAL);
178 a = (struct __mthread_attr *) *attr;
179 if (!mthread_attr_valid(attr))
180 return(EINVAL);
182 *stacksize = a->ma_stacksize;
184 return(0);
188 /*===========================================================================*
189 * mthread_attr_setstack *
190 *===========================================================================*/
191 int mthread_attr_setstack(attr, stackaddr, stacksize)
192 mthread_attr_t *attr;
193 void *stackaddr;
194 size_t stacksize;
196 /* Set stack attribute */
197 struct __mthread_attr *a;
199 if (attr == NULL)
200 return(EINVAL);
202 a = (struct __mthread_attr *) *attr;
203 if (!mthread_attr_valid(attr) || stacksize < MTHREAD_STACK_MIN)
204 return(EINVAL);
206 /* We don't care about address alignment (POSIX standard). The ucontext
207 * system calls will make sure that the provided stack will be aligned (at
208 * the cost of some memory if needed).
211 a->ma_stackaddr = stackaddr;
212 a->ma_stacksize = stacksize;
214 return(0);
218 /*===========================================================================*
219 * mthread_attr_setstacksize *
220 *===========================================================================*/
221 int mthread_attr_setstacksize(attr, stacksize)
222 mthread_attr_t *attr;
223 size_t stacksize;
225 /* Set stack size attribute */
226 struct __mthread_attr *a;
228 if (attr == NULL)
229 return(EINVAL);
231 a = (struct __mthread_attr *) *attr;
232 if (!mthread_attr_valid(attr) || stacksize < MTHREAD_STACK_MIN)
233 return(EINVAL);
235 a->ma_stacksize = stacksize;
237 return(0);
241 /*===========================================================================*
242 * mthread_attr_remove *
243 *===========================================================================*/
244 static void mthread_attr_remove(a)
245 mthread_attr_t *a;
247 /* Remove attribute from list of valid, initialized attributes */
249 if ((*a)->ma_prev == NULL)
250 va_front = (*a)->ma_next;
251 else
252 (*a)->ma_prev->ma_next = (*a)->ma_next;
254 if ((*a)->ma_next == NULL)
255 va_rear = (*a)->ma_prev;
256 else
257 (*a)->ma_next->ma_prev = (*a)->ma_prev;
261 /*===========================================================================*
262 * mthread_attr_valid *
263 *===========================================================================*/
264 static int mthread_attr_valid(a)
265 mthread_attr_t *a;
267 /* Check to see if attribute is on the list of valid attributes */
268 struct __mthread_attr *loopitem;
270 loopitem = va_front;
272 while (loopitem != NULL) {
273 if (loopitem == *a)
274 return(1);
276 loopitem = loopitem->ma_next;
279 return(0);
283 /*===========================================================================*
284 * mthread_attr_verify *
285 *===========================================================================*/
286 #ifdef MDEBUG
287 int mthread_attr_verify(void)
289 /* Return true when no attributes are in use */
290 struct __mthread_attr *loopitem;
292 loopitem = va_front;
294 while (loopitem != NULL) {
295 loopitem = loopitem->ma_next;
296 return(0);
299 return(1);
301 #endif
303 /* pthread compatibility layer. */
304 __weak_alias(pthread_attr_destroy, mthread_attr_destroy)
305 __weak_alias(pthread_attr_getdetachstate, mthread_attr_getdetachstate)
306 __weak_alias(pthread_attr_getstack, mthread_attr_getstack)
307 __weak_alias(pthread_attr_getstacksize, mthread_attr_getstacksize)
308 __weak_alias(pthread_attr_init, mthread_attr_init)
309 __weak_alias(pthread_attr_setdetachstate, mthread_attr_setdetachstate)
310 __weak_alias(pthread_attr_setstack, mthread_attr_setstack)
311 __weak_alias(pthread_attr_setstacksize, mthread_attr_setstacksize)