]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/test/nptl/tst-mutex8.c
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / test / nptl / tst-mutex8.c
1 /* Copyright (C) 2003 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2003.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, see
17    <http://www.gnu.org/licenses/>.  */
18
19 /* This test checks behavior not required by POSIX.  */
20 #include <errno.h>
21 #include <pthread.h>
22 #include <stdbool.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25
26
27 static pthread_mutex_t *m;
28 static pthread_barrier_t b;
29 static pthread_cond_t c;
30 static bool done;
31
32
33 static void
34 cl (void *arg)
35 {
36   if (pthread_mutex_unlock (m) != 0)
37     {
38       puts ("cl: mutex_unlocked failed");
39       exit (1);
40     }
41 }
42
43
44 static void *
45 tf (void *arg)
46 {
47   if (pthread_mutex_lock (m) != 0)
48     {
49       puts ("tf: mutex_lock failed");
50       return (void *) 1l;
51     }
52
53   int e = pthread_barrier_wait (&b);
54   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
55     {
56       puts ("barrier_wait failed");
57       return (void *) 1l;
58     }
59
60   if (arg == NULL)
61     do
62       if (pthread_cond_wait (&c, m) != 0)
63         {
64           puts ("tf: cond_wait failed");
65           return (void *) 1l;
66         }
67     while (! done);
68   else
69     do
70       {
71         pthread_cleanup_push (cl, NULL);
72
73         if (pthread_cond_wait (&c, m) != 0)
74           {
75             puts ("tf: cond_wait failed");
76             return (void *) 1l;
77           }
78
79         pthread_cleanup_pop (0);
80       }
81     while (! done);
82
83   if (pthread_mutex_unlock (m) != 0)
84     {
85       puts ("tf: mutex_unlock failed");
86       return (void *) 1l;
87     }
88
89   return NULL;
90 }
91
92
93 static int
94 check_type (const char *mas, pthread_mutexattr_t *ma)
95 {
96   if (pthread_mutex_init (m, ma) != 0)
97     {
98       printf ("1st mutex_init failed for %s\n", mas);
99       return 1;
100     }
101
102   if (pthread_mutex_destroy (m) != 0)
103     {
104       printf ("immediate mutex_destroy failed for %s\n", mas);
105       return 1;
106     }
107
108   if (pthread_mutex_init (m, ma) != 0)
109     {
110       printf ("2nd mutex_init failed for %s\n", mas);
111       return 1;
112     }
113
114   if (pthread_mutex_lock (m) != 0)
115     {
116       printf ("1st mutex_lock failed for %s\n", mas);
117       return 1;
118     }
119
120   int e = pthread_mutex_destroy (m);
121   if (e == 0)
122     {
123       printf ("mutex_destroy of self-locked mutex succeeded for %s\n", mas);
124       return 1;
125     }
126   if (e != EBUSY)
127     {
128       printf ("mutex_destroy of self-locked mutex did not return EBUSY %s\n",
129               mas);
130       return 1;
131     }
132
133   if (pthread_mutex_unlock (m) != 0)
134     {
135       printf ("1st mutex_unlock failed for %s\n", mas);
136       return 1;
137     }
138
139   if (pthread_mutex_trylock (m) != 0)
140     {
141       printf ("mutex_trylock failed for %s\n", mas);
142       return 1;
143     }
144
145   e = pthread_mutex_destroy (m);
146   if (e == 0)
147     {
148       printf ("mutex_destroy of self-trylocked mutex succeeded for %s\n", mas);
149       return 1;
150     }
151   if (e != EBUSY)
152     {
153       printf ("\
154 mutex_destroy of self-trylocked mutex did not return EBUSY %s\n",
155               mas);
156       return 1;
157     }
158
159   if (pthread_mutex_unlock (m) != 0)
160     {
161       printf ("2nd mutex_unlock failed for %s\n", mas);
162       return 1;
163     }
164
165   pthread_t th;
166   if (pthread_create (&th, NULL, tf, NULL) != 0)
167     {
168       puts ("1st create failed");
169       return 1;
170     }
171   done = false;
172
173   e = pthread_barrier_wait (&b);
174   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
175     {
176       puts ("1st barrier_wait failed");
177       return 1;
178     }
179
180   if (pthread_mutex_lock (m) != 0)
181     {
182       printf ("2nd mutex_lock failed for %s\n", mas);
183       return 1;
184     }
185
186   if (pthread_mutex_unlock (m) != 0)
187     {
188       printf ("3rd mutex_unlock failed for %s\n", mas);
189       return 1;
190     }
191
192   e = pthread_mutex_destroy (m);
193   if (e == 0)
194     {
195       printf ("mutex_destroy of condvar-used mutex succeeded for %s\n", mas);
196       return 1;
197     }
198   if (e != EBUSY)
199     {
200       printf ("\
201 mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas);
202       return 1;
203     }
204
205   done = true;
206   if (pthread_cond_signal (&c) != 0)
207     {
208       puts ("cond_signal failed");
209       return 1;
210     }
211
212   void *r;
213   if (pthread_join (th, &r) != 0)
214     {
215       puts ("join failed");
216       return 1;
217     }
218   if (r != NULL)
219     {
220       puts ("thread didn't return NULL");
221       return 1;
222     }
223
224   if (pthread_mutex_destroy (m) != 0)
225     {
226       printf ("mutex_destroy after condvar-use failed for %s\n", mas);
227       return 1;
228     }
229
230   if (pthread_mutex_init (m, ma) != 0)
231     {
232       printf ("3rd mutex_init failed for %s\n", mas);
233       return 1;
234     }
235
236   if (pthread_create (&th, NULL, tf, (void *) 1) != 0)
237     {
238       puts ("2nd create failed");
239       return 1;
240     }
241   done = false;
242
243   e = pthread_barrier_wait (&b);
244   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
245     {
246       puts ("2nd barrier_wait failed");
247       return 1;
248     }
249
250   if (pthread_mutex_lock (m) != 0)
251     {
252       printf ("3rd mutex_lock failed for %s\n", mas);
253       return 1;
254     }
255
256   if (pthread_mutex_unlock (m) != 0)
257     {
258       printf ("4th mutex_unlock failed for %s\n", mas);
259       return 1;
260     }
261
262   e = pthread_mutex_destroy (m);
263   if (e == 0)
264     {
265       printf ("2nd mutex_destroy of condvar-used mutex succeeded for %s\n",
266               mas);
267       return 1;
268     }
269   if (e != EBUSY)
270     {
271       printf ("\
272 2nd mutex_destroy of condvar-used mutex did not return EBUSY for %s\n",
273               mas);
274       return 1;
275     }
276
277   if (pthread_cancel (th) != 0)
278     {
279       puts ("cond_cancel failed");
280       return 1;
281     }
282
283   if (pthread_join (th, &r) != 0)
284     {
285       puts ("join failed");
286       return 1;
287     }
288   if (r != PTHREAD_CANCELED)
289     {
290       puts ("thread not canceled");
291       return 1;
292     }
293
294   if (pthread_mutex_destroy (m) != 0)
295     {
296       printf ("mutex_destroy after condvar-canceled failed for %s\n", mas);
297       return 1;
298     }
299
300   return 0;
301 }
302
303
304 static int
305 do_test (void)
306 {
307   pthread_mutex_t mm;
308   m = &mm;
309
310   if (pthread_barrier_init (&b, NULL, 2) != 0)
311     {
312       puts ("barrier_init failed");
313       return 1;
314     }
315
316   if (pthread_cond_init (&c, NULL) != 0)
317     {
318       puts ("cond_init failed");
319       return 1;
320     }
321
322   puts ("check normal mutex");
323   int res = check_type ("normal", NULL);
324
325   pthread_mutexattr_t ma;
326   if (pthread_mutexattr_init (&ma) != 0)
327     {
328       puts ("1st mutexattr_init failed");
329       return 1;
330     }
331   if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_RECURSIVE) != 0)
332     {
333       puts ("1st mutexattr_settype failed");
334       return 1;
335     }
336   puts ("check recursive mutex");
337   res |= check_type ("recursive", &ma);
338   if (pthread_mutexattr_destroy (&ma) != 0)
339     {
340       puts ("1st mutexattr_destroy failed");
341       return 1;
342     }
343
344   if (pthread_mutexattr_init (&ma) != 0)
345     {
346       puts ("2nd mutexattr_init failed");
347       return 1;
348     }
349   if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_ERRORCHECK) != 0)
350     {
351       puts ("2nd mutexattr_settype failed");
352       return 1;
353     }
354   puts ("check error-checking mutex");
355   res |= check_type ("error-checking", &ma);
356   if (pthread_mutexattr_destroy (&ma) != 0)
357     {
358       puts ("2nd mutexattr_destroy failed");
359       return 1;
360     }
361
362   return res;
363 }
364
365 #define TEST_FUNCTION do_test ()
366 #include "../test-skeleton.c"