xref: /minix3/minix/lib/libmthread/attribute.c (revision 433d6423c39e34ec4b79c950597bb2d236f886be)
1*433d6423SLionel Sambuc #include <minix/mthread.h>
2*433d6423SLionel Sambuc #include "global.h"
3*433d6423SLionel Sambuc #include "proto.h"
4*433d6423SLionel Sambuc 
5*433d6423SLionel Sambuc static struct __mthread_attr *va_front, *va_rear;
6*433d6423SLionel Sambuc static void mthread_attr_add(mthread_attr_t *a);
7*433d6423SLionel Sambuc static void mthread_attr_remove(mthread_attr_t *a);
8*433d6423SLionel Sambuc static int mthread_attr_valid(mthread_attr_t *a);
9*433d6423SLionel Sambuc 
10*433d6423SLionel Sambuc /*===========================================================================*
11*433d6423SLionel Sambuc  *			mthread_init_valid_attributes			     *
12*433d6423SLionel Sambuc  *===========================================================================*/
mthread_init_valid_attributes(void)13*433d6423SLionel Sambuc void mthread_init_valid_attributes(void)
14*433d6423SLionel Sambuc {
15*433d6423SLionel Sambuc /* Initialize list of valid attributs */
16*433d6423SLionel Sambuc   va_front = va_rear = NULL;
17*433d6423SLionel Sambuc }
18*433d6423SLionel Sambuc 
19*433d6423SLionel Sambuc 
20*433d6423SLionel Sambuc /*===========================================================================*
21*433d6423SLionel Sambuc  *				mthread_attr_add			     *
22*433d6423SLionel Sambuc  *===========================================================================*/
mthread_attr_add(a)23*433d6423SLionel Sambuc static void mthread_attr_add(a)
24*433d6423SLionel Sambuc mthread_attr_t *a;
25*433d6423SLionel Sambuc {
26*433d6423SLionel Sambuc /* Add attribute to list of valid, initialized attributes */
27*433d6423SLionel Sambuc 
28*433d6423SLionel Sambuc   if (va_front == NULL) {	/* Empty list */
29*433d6423SLionel Sambuc   	va_front = *a;
30*433d6423SLionel Sambuc   	(*a)->ma_prev = NULL;
31*433d6423SLionel Sambuc   } else {
32*433d6423SLionel Sambuc   	va_rear->ma_next = *a;
33*433d6423SLionel Sambuc   	(*a)->ma_prev = va_rear;
34*433d6423SLionel Sambuc   }
35*433d6423SLionel Sambuc 
36*433d6423SLionel Sambuc   (*a)->ma_next = NULL;
37*433d6423SLionel Sambuc   va_rear = *a;
38*433d6423SLionel Sambuc }
39*433d6423SLionel Sambuc 
40*433d6423SLionel Sambuc 
41*433d6423SLionel Sambuc /*===========================================================================*
42*433d6423SLionel Sambuc  *				mthread_attr_destroy			     *
43*433d6423SLionel Sambuc  *===========================================================================*/
mthread_attr_destroy(attr)44*433d6423SLionel Sambuc int mthread_attr_destroy(attr)
45*433d6423SLionel Sambuc mthread_attr_t *attr;
46*433d6423SLionel Sambuc {
47*433d6423SLionel Sambuc /* Invalidate attribute and deallocate resources. */
48*433d6423SLionel Sambuc 
49*433d6423SLionel Sambuc   if (attr == NULL)
50*433d6423SLionel Sambuc   	return(EINVAL);
51*433d6423SLionel Sambuc 
52*433d6423SLionel Sambuc   if (!mthread_attr_valid(attr))
53*433d6423SLionel Sambuc   	return(EINVAL);
54*433d6423SLionel Sambuc 
55*433d6423SLionel Sambuc   /* Valide attribute; invalidate it */
56*433d6423SLionel Sambuc   mthread_attr_remove(attr);
57*433d6423SLionel Sambuc   free(*attr);
58*433d6423SLionel Sambuc   *attr = NULL;
59*433d6423SLionel Sambuc 
60*433d6423SLionel Sambuc   return(0);
61*433d6423SLionel Sambuc }
62*433d6423SLionel Sambuc 
63*433d6423SLionel Sambuc 
64*433d6423SLionel Sambuc /*===========================================================================*
65*433d6423SLionel Sambuc  *				mthread_attr_init			     *
66*433d6423SLionel Sambuc  *===========================================================================*/
mthread_attr_init(attr)67*433d6423SLionel Sambuc int mthread_attr_init(attr)
68*433d6423SLionel Sambuc mthread_attr_t *attr;	/* Attribute */
69*433d6423SLionel Sambuc {
70*433d6423SLionel Sambuc /* Initialize the attribute to a known state. */
71*433d6423SLionel Sambuc   struct __mthread_attr *a;
72*433d6423SLionel Sambuc 
73*433d6423SLionel Sambuc   if (attr == NULL)
74*433d6423SLionel Sambuc   	return(EAGAIN);
75*433d6423SLionel Sambuc   else if (mthread_attr_valid(attr))
76*433d6423SLionel Sambuc   	return(EBUSY);
77*433d6423SLionel Sambuc 
78*433d6423SLionel Sambuc   if ((a = malloc(sizeof(struct __mthread_attr))) == NULL)
79*433d6423SLionel Sambuc   	return(-1);
80*433d6423SLionel Sambuc 
81*433d6423SLionel Sambuc   a->ma_detachstate = MTHREAD_CREATE_JOINABLE;
82*433d6423SLionel Sambuc   a->ma_stackaddr = NULL;
83*433d6423SLionel Sambuc   a->ma_stacksize = (size_t) 0;
84*433d6423SLionel Sambuc 
85*433d6423SLionel Sambuc   *attr = (mthread_attr_t) a;
86*433d6423SLionel Sambuc   mthread_attr_add(attr); /* Validate attribute: attribute now in use */
87*433d6423SLionel Sambuc 
88*433d6423SLionel Sambuc   return(0);
89*433d6423SLionel Sambuc }
90*433d6423SLionel Sambuc 
91*433d6423SLionel Sambuc /*===========================================================================*
92*433d6423SLionel Sambuc  *				mthread_attr_getdetachstate			     *
93*433d6423SLionel Sambuc  *===========================================================================*/
mthread_attr_getdetachstate(attr,detachstate)94*433d6423SLionel Sambuc int mthread_attr_getdetachstate(attr, detachstate)
95*433d6423SLionel Sambuc mthread_attr_t *attr;
96*433d6423SLionel Sambuc int *detachstate;
97*433d6423SLionel Sambuc {
98*433d6423SLionel Sambuc /* Get detachstate of a thread attribute */
99*433d6423SLionel Sambuc   struct __mthread_attr *a;
100*433d6423SLionel Sambuc 
101*433d6423SLionel Sambuc   if (attr == NULL)
102*433d6423SLionel Sambuc   	return(EINVAL);
103*433d6423SLionel Sambuc 
104*433d6423SLionel Sambuc   a = (struct __mthread_attr *) *attr;
105*433d6423SLionel Sambuc   if (!mthread_attr_valid(attr))
106*433d6423SLionel Sambuc   	return(EINVAL);
107*433d6423SLionel Sambuc 
108*433d6423SLionel Sambuc   *detachstate = a->ma_detachstate;
109*433d6423SLionel Sambuc 
110*433d6423SLionel Sambuc   return(0);
111*433d6423SLionel Sambuc }
112*433d6423SLionel Sambuc 
113*433d6423SLionel Sambuc 
114*433d6423SLionel Sambuc /*===========================================================================*
115*433d6423SLionel Sambuc  *				mthread_attr_setdetachstate			     *
116*433d6423SLionel Sambuc  *===========================================================================*/
mthread_attr_setdetachstate(attr,detachstate)117*433d6423SLionel Sambuc int mthread_attr_setdetachstate(attr, detachstate)
118*433d6423SLionel Sambuc mthread_attr_t *attr;
119*433d6423SLionel Sambuc int detachstate;
120*433d6423SLionel Sambuc {
121*433d6423SLionel Sambuc /* Set detachstate of a thread attribute */
122*433d6423SLionel Sambuc   struct __mthread_attr *a;
123*433d6423SLionel Sambuc 
124*433d6423SLionel Sambuc   if (attr == NULL)
125*433d6423SLionel Sambuc   	return(EINVAL);
126*433d6423SLionel Sambuc 
127*433d6423SLionel Sambuc   a = (struct __mthread_attr *) *attr;
128*433d6423SLionel Sambuc   if (!mthread_attr_valid(attr))
129*433d6423SLionel Sambuc   	return(EINVAL);
130*433d6423SLionel Sambuc   else if(detachstate != MTHREAD_CREATE_JOINABLE &&
131*433d6423SLionel Sambuc   	  detachstate != MTHREAD_CREATE_DETACHED)
132*433d6423SLionel Sambuc 	return(EINVAL);
133*433d6423SLionel Sambuc 
134*433d6423SLionel Sambuc   a->ma_detachstate = detachstate;
135*433d6423SLionel Sambuc 
136*433d6423SLionel Sambuc   return(0);
137*433d6423SLionel Sambuc }
138*433d6423SLionel Sambuc 
139*433d6423SLionel Sambuc 
140*433d6423SLionel Sambuc /*===========================================================================*
141*433d6423SLionel Sambuc  *				mthread_attr_getstack			     *
142*433d6423SLionel Sambuc  *===========================================================================*/
mthread_attr_getstack(attr,stackaddr,stacksize)143*433d6423SLionel Sambuc int mthread_attr_getstack(attr, stackaddr, stacksize)
144*433d6423SLionel Sambuc mthread_attr_t *attr;
145*433d6423SLionel Sambuc void **stackaddr;
146*433d6423SLionel Sambuc size_t *stacksize;
147*433d6423SLionel Sambuc {
148*433d6423SLionel Sambuc /* Get stack attribute */
149*433d6423SLionel Sambuc   struct __mthread_attr *a;
150*433d6423SLionel Sambuc 
151*433d6423SLionel Sambuc   if (attr == NULL)
152*433d6423SLionel Sambuc   	return(EINVAL);
153*433d6423SLionel Sambuc 
154*433d6423SLionel Sambuc   a = (struct __mthread_attr *) *attr;
155*433d6423SLionel Sambuc   if (!mthread_attr_valid(attr))
156*433d6423SLionel Sambuc   	return(EINVAL);
157*433d6423SLionel Sambuc 
158*433d6423SLionel Sambuc   *stackaddr = a->ma_stackaddr;
159*433d6423SLionel Sambuc   *stacksize = a->ma_stacksize;
160*433d6423SLionel Sambuc 
161*433d6423SLionel Sambuc   return(0);
162*433d6423SLionel Sambuc }
163*433d6423SLionel Sambuc 
164*433d6423SLionel Sambuc 
165*433d6423SLionel Sambuc /*===========================================================================*
166*433d6423SLionel Sambuc  *				mthread_attr_getstacksize		     *
167*433d6423SLionel Sambuc  *===========================================================================*/
mthread_attr_getstacksize(attr,stacksize)168*433d6423SLionel Sambuc int mthread_attr_getstacksize(attr, stacksize)
169*433d6423SLionel Sambuc mthread_attr_t *attr;
170*433d6423SLionel Sambuc size_t *stacksize;
171*433d6423SLionel Sambuc {
172*433d6423SLionel Sambuc /* Get stack size attribute */
173*433d6423SLionel Sambuc   struct __mthread_attr *a;
174*433d6423SLionel Sambuc 
175*433d6423SLionel Sambuc   if (attr == NULL)
176*433d6423SLionel Sambuc   	return(EINVAL);
177*433d6423SLionel Sambuc 
178*433d6423SLionel Sambuc   a = (struct __mthread_attr *) *attr;
179*433d6423SLionel Sambuc   if (!mthread_attr_valid(attr))
180*433d6423SLionel Sambuc   	return(EINVAL);
181*433d6423SLionel Sambuc 
182*433d6423SLionel Sambuc   *stacksize = a->ma_stacksize;
183*433d6423SLionel Sambuc 
184*433d6423SLionel Sambuc   return(0);
185*433d6423SLionel Sambuc }
186*433d6423SLionel Sambuc 
187*433d6423SLionel Sambuc 
188*433d6423SLionel Sambuc /*===========================================================================*
189*433d6423SLionel Sambuc  *				mthread_attr_setstack			     *
190*433d6423SLionel Sambuc  *===========================================================================*/
mthread_attr_setstack(attr,stackaddr,stacksize)191*433d6423SLionel Sambuc int mthread_attr_setstack(attr, stackaddr, stacksize)
192*433d6423SLionel Sambuc mthread_attr_t *attr;
193*433d6423SLionel Sambuc void *stackaddr;
194*433d6423SLionel Sambuc size_t stacksize;
195*433d6423SLionel Sambuc {
196*433d6423SLionel Sambuc /* Set stack attribute */
197*433d6423SLionel Sambuc   struct __mthread_attr *a;
198*433d6423SLionel Sambuc 
199*433d6423SLionel Sambuc   if (attr == NULL)
200*433d6423SLionel Sambuc   	return(EINVAL);
201*433d6423SLionel Sambuc 
202*433d6423SLionel Sambuc   a = (struct __mthread_attr *) *attr;
203*433d6423SLionel Sambuc   if (!mthread_attr_valid(attr) || stacksize < MTHREAD_STACK_MIN)
204*433d6423SLionel Sambuc   	return(EINVAL);
205*433d6423SLionel Sambuc 
206*433d6423SLionel Sambuc   /* We don't care about address alignment (POSIX standard). The ucontext
207*433d6423SLionel Sambuc    * system calls will make sure that the provided stack will be aligned (at
208*433d6423SLionel Sambuc    * the cost of some memory if needed).
209*433d6423SLionel Sambuc    */
210*433d6423SLionel Sambuc 
211*433d6423SLionel Sambuc   a->ma_stackaddr = stackaddr;
212*433d6423SLionel Sambuc   a->ma_stacksize = stacksize;
213*433d6423SLionel Sambuc 
214*433d6423SLionel Sambuc   return(0);
215*433d6423SLionel Sambuc }
216*433d6423SLionel Sambuc 
217*433d6423SLionel Sambuc 
218*433d6423SLionel Sambuc /*===========================================================================*
219*433d6423SLionel Sambuc  *				mthread_attr_setstacksize			     *
220*433d6423SLionel Sambuc  *===========================================================================*/
mthread_attr_setstacksize(attr,stacksize)221*433d6423SLionel Sambuc int mthread_attr_setstacksize(attr, stacksize)
222*433d6423SLionel Sambuc mthread_attr_t *attr;
223*433d6423SLionel Sambuc size_t stacksize;
224*433d6423SLionel Sambuc {
225*433d6423SLionel Sambuc /* Set stack size attribute */
226*433d6423SLionel Sambuc   struct __mthread_attr *a;
227*433d6423SLionel Sambuc 
228*433d6423SLionel Sambuc   if (attr == NULL)
229*433d6423SLionel Sambuc   	return(EINVAL);
230*433d6423SLionel Sambuc 
231*433d6423SLionel Sambuc   a = (struct __mthread_attr *) *attr;
232*433d6423SLionel Sambuc   if (!mthread_attr_valid(attr) || stacksize < MTHREAD_STACK_MIN)
233*433d6423SLionel Sambuc 	return(EINVAL);
234*433d6423SLionel Sambuc 
235*433d6423SLionel Sambuc   a->ma_stacksize = stacksize;
236*433d6423SLionel Sambuc 
237*433d6423SLionel Sambuc   return(0);
238*433d6423SLionel Sambuc }
239*433d6423SLionel Sambuc 
240*433d6423SLionel Sambuc 
241*433d6423SLionel Sambuc /*===========================================================================*
242*433d6423SLionel Sambuc  *				mthread_attr_remove			     *
243*433d6423SLionel Sambuc  *===========================================================================*/
mthread_attr_remove(a)244*433d6423SLionel Sambuc static void mthread_attr_remove(a)
245*433d6423SLionel Sambuc mthread_attr_t *a;
246*433d6423SLionel Sambuc {
247*433d6423SLionel Sambuc /* Remove attribute from list of valid, initialized attributes */
248*433d6423SLionel Sambuc 
249*433d6423SLionel Sambuc   if ((*a)->ma_prev == NULL)
250*433d6423SLionel Sambuc   	va_front = (*a)->ma_next;
251*433d6423SLionel Sambuc   else
252*433d6423SLionel Sambuc   	(*a)->ma_prev->ma_next = (*a)->ma_next;
253*433d6423SLionel Sambuc 
254*433d6423SLionel Sambuc   if ((*a)->ma_next == NULL)
255*433d6423SLionel Sambuc   	va_rear = (*a)->ma_prev;
256*433d6423SLionel Sambuc   else
257*433d6423SLionel Sambuc   	(*a)->ma_next->ma_prev = (*a)->ma_prev;
258*433d6423SLionel Sambuc }
259*433d6423SLionel Sambuc 
260*433d6423SLionel Sambuc 
261*433d6423SLionel Sambuc /*===========================================================================*
262*433d6423SLionel Sambuc  *				mthread_attr_valid			     *
263*433d6423SLionel Sambuc  *===========================================================================*/
mthread_attr_valid(a)264*433d6423SLionel Sambuc static int mthread_attr_valid(a)
265*433d6423SLionel Sambuc mthread_attr_t *a;
266*433d6423SLionel Sambuc {
267*433d6423SLionel Sambuc /* Check to see if attribute is on the list of valid attributes */
268*433d6423SLionel Sambuc   struct __mthread_attr *loopitem;
269*433d6423SLionel Sambuc 
270*433d6423SLionel Sambuc   loopitem = va_front;
271*433d6423SLionel Sambuc 
272*433d6423SLionel Sambuc   while (loopitem != NULL) {
273*433d6423SLionel Sambuc   	if (loopitem == *a)
274*433d6423SLionel Sambuc   		return(1);
275*433d6423SLionel Sambuc 
276*433d6423SLionel Sambuc   	loopitem = loopitem->ma_next;
277*433d6423SLionel Sambuc   }
278*433d6423SLionel Sambuc 
279*433d6423SLionel Sambuc   return(0);
280*433d6423SLionel Sambuc }
281*433d6423SLionel Sambuc 
282*433d6423SLionel Sambuc 
283*433d6423SLionel Sambuc /*===========================================================================*
284*433d6423SLionel Sambuc  *				mthread_attr_verify			     *
285*433d6423SLionel Sambuc  *===========================================================================*/
286*433d6423SLionel Sambuc #ifdef MDEBUG
mthread_attr_verify(void)287*433d6423SLionel Sambuc int mthread_attr_verify(void)
288*433d6423SLionel Sambuc {
289*433d6423SLionel Sambuc /* Return true when no attributes are in use */
290*433d6423SLionel Sambuc   struct __mthread_attr *loopitem;
291*433d6423SLionel Sambuc 
292*433d6423SLionel Sambuc   loopitem = va_front;
293*433d6423SLionel Sambuc 
294*433d6423SLionel Sambuc   while (loopitem != NULL) {
295*433d6423SLionel Sambuc   	loopitem = loopitem->ma_next;
296*433d6423SLionel Sambuc   	return(0);
297*433d6423SLionel Sambuc   }
298*433d6423SLionel Sambuc 
299*433d6423SLionel Sambuc   return(1);
300*433d6423SLionel Sambuc }
301*433d6423SLionel Sambuc #endif
302*433d6423SLionel Sambuc 
303*433d6423SLionel Sambuc /* pthread compatibility layer. */
304*433d6423SLionel Sambuc __weak_alias(pthread_attr_destroy, mthread_attr_destroy)
305*433d6423SLionel Sambuc __weak_alias(pthread_attr_getdetachstate, mthread_attr_getdetachstate)
306*433d6423SLionel Sambuc __weak_alias(pthread_attr_getstack, mthread_attr_getstack)
307*433d6423SLionel Sambuc __weak_alias(pthread_attr_getstacksize, mthread_attr_getstacksize)
308*433d6423SLionel Sambuc __weak_alias(pthread_attr_init, mthread_attr_init)
309*433d6423SLionel Sambuc __weak_alias(pthread_attr_setdetachstate, mthread_attr_setdetachstate)
310*433d6423SLionel Sambuc __weak_alias(pthread_attr_setstack, mthread_attr_setstack)
311*433d6423SLionel Sambuc __weak_alias(pthread_attr_setstacksize, mthread_attr_setstacksize)
312*433d6423SLionel Sambuc 
313