source: vendor/glibc-tests/glibc/nptl/tst-mutex8.c

Last change on this file was 2036, checked in by bird, 20 years ago

Initial revision

  • Property cvs2svn:cvs-rev set to 1.1
  • Property svn:eol-style set to native
  • Property svn:executable set to *
  • Property svn:keywords set to Author Date Id Revision
File size: 7.5 KB
Line 
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, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
19
20/* This test checks behavior not required by POSIX. */
21#include <errno.h>
22#include <pthread.h>
23#include <stdbool.h>
24#include <stdio.h>
25#include <stdlib.h>
26
27
28static pthread_mutex_t *m;
29static pthread_barrier_t b;
30static pthread_cond_t c;
31static bool done;
32
33
34static void
35cl (void *arg)
36{
37 if (pthread_mutex_unlock (m) != 0)
38 {
39 puts ("cl: mutex_unlocked failed");
40 exit (1);
41 }
42}
43
44
45static void *
46tf (void *arg)
47{
48 if (pthread_mutex_lock (m) != 0)
49 {
50 puts ("tf: mutex_lock failed");
51 return (void *) 1l;
52 }
53
54 int e = pthread_barrier_wait (&b);
55 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
56 {
57 puts ("barrier_wait failed");
58 return (void *) 1l;
59 }
60
61 if (arg == NULL)
62 do
63 if (pthread_cond_wait (&c, m) != 0)
64 {
65 puts ("tf: cond_wait failed");
66 return (void *) 1l;
67 }
68 while (! done);
69 else
70 do
71 {
72 pthread_cleanup_push (cl, NULL);
73
74 if (pthread_cond_wait (&c, m) != 0)
75 {
76 puts ("tf: cond_wait failed");
77 return (void *) 1l;
78 }
79
80 pthread_cleanup_pop (0);
81 }
82 while (! done);
83
84 if (pthread_mutex_unlock (m) != 0)
85 {
86 puts ("tf: mutex_unlock failed");
87 return (void *) 1l;
88 }
89
90 return NULL;
91}
92
93
94static int
95check_type (const char *mas, pthread_mutexattr_t *ma)
96{
97 if (pthread_mutex_init (m, ma) != 0)
98 {
99 printf ("1st mutex_init failed for %s\n", mas);
100 return 1;
101 }
102
103 if (pthread_mutex_destroy (m) != 0)
104 {
105 printf ("immediate mutex_destroy failed for %s\n", mas);
106 return 1;
107 }
108
109 if (pthread_mutex_init (m, ma) != 0)
110 {
111 printf ("2nd mutex_init failed for %s\n", mas);
112 return 1;
113 }
114
115 if (pthread_mutex_lock (m) != 0)
116 {
117 printf ("1st mutex_lock failed for %s\n", mas);
118 return 1;
119 }
120
121 int e = pthread_mutex_destroy (m);
122 if (e == 0)
123 {
124 printf ("mutex_destroy of self-locked mutex succeeded for %s\n", mas);
125 return 1;
126 }
127 if (e != EBUSY)
128 {
129 printf ("mutex_destroy of self-locked mutex did not return EBUSY %s\n",
130 mas);
131 return 1;
132 }
133
134 if (pthread_mutex_unlock (m) != 0)
135 {
136 printf ("1st mutex_unlock failed for %s\n", mas);
137 return 1;
138 }
139
140 if (pthread_mutex_trylock (m) != 0)
141 {
142 printf ("mutex_trylock failed for %s\n", mas);
143 return 1;
144 }
145
146 e = pthread_mutex_destroy (m);
147 if (e == 0)
148 {
149 printf ("mutex_destroy of self-trylocked mutex succeeded for %s\n", mas);
150 return 1;
151 }
152 if (e != EBUSY)
153 {
154 printf ("\
155mutex_destroy of self-trylocked mutex did not return EBUSY %s\n",
156 mas);
157 return 1;
158 }
159
160 if (pthread_mutex_unlock (m) != 0)
161 {
162 printf ("2nd mutex_unlock failed for %s\n", mas);
163 return 1;
164 }
165
166 pthread_t th;
167 if (pthread_create (&th, NULL, tf, NULL) != 0)
168 {
169 puts ("1st create failed");
170 return 1;
171 }
172 done = false;
173
174 e = pthread_barrier_wait (&b);
175 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
176 {
177 puts ("1st barrier_wait failed");
178 return 1;
179 }
180
181 if (pthread_mutex_lock (m) != 0)
182 {
183 printf ("2nd mutex_lock failed for %s\n", mas);
184 return 1;
185 }
186
187 if (pthread_mutex_unlock (m) != 0)
188 {
189 printf ("3rd mutex_unlock failed for %s\n", mas);
190 return 1;
191 }
192
193 e = pthread_mutex_destroy (m);
194 if (e == 0)
195 {
196 printf ("mutex_destroy of condvar-used mutex succeeded for %s\n", mas);
197 return 1;
198 }
199 if (e != EBUSY)
200 {
201 printf ("\
202mutex_destroy of condvar-used mutex did not return EBUSY for %s\n", mas);
203 return 1;
204 }
205
206 done = true;
207 if (pthread_cond_signal (&c) != 0)
208 {
209 puts ("cond_signal failed");
210 return 1;
211 }
212
213 void *r;
214 if (pthread_join (th, &r) != 0)
215 {
216 puts ("join failed");
217 return 1;
218 }
219 if (r != NULL)
220 {
221 puts ("thread didn't return NULL");
222 return 1;
223 }
224
225 if (pthread_mutex_destroy (m) != 0)
226 {
227 printf ("mutex_destroy after condvar-use failed for %s\n", mas);
228 return 1;
229 }
230
231 if (pthread_mutex_init (m, ma) != 0)
232 {
233 printf ("3rd mutex_init failed for %s\n", mas);
234 return 1;
235 }
236
237 if (pthread_create (&th, NULL, tf, (void *) 1) != 0)
238 {
239 puts ("2nd create failed");
240 return 1;
241 }
242 done = false;
243
244 e = pthread_barrier_wait (&b);
245 if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
246 {
247 puts ("2nd barrier_wait failed");
248 return 1;
249 }
250
251 if (pthread_mutex_lock (m) != 0)
252 {
253 printf ("3rd mutex_lock failed for %s\n", mas);
254 return 1;
255 }
256
257 if (pthread_mutex_unlock (m) != 0)
258 {
259 printf ("4th mutex_unlock failed for %s\n", mas);
260 return 1;
261 }
262
263 e = pthread_mutex_destroy (m);
264 if (e == 0)
265 {
266 printf ("2nd mutex_destroy of condvar-used mutex succeeded for %s\n",
267 mas);
268 return 1;
269 }
270 if (e != EBUSY)
271 {
272 printf ("\
2732nd mutex_destroy of condvar-used mutex did not return EBUSY for %s\n",
274 mas);
275 return 1;
276 }
277
278 if (pthread_cancel (th) != 0)
279 {
280 puts ("cond_cancel failed");
281 return 1;
282 }
283
284 if (pthread_join (th, &r) != 0)
285 {
286 puts ("join failed");
287 return 1;
288 }
289 if (r != PTHREAD_CANCELED)
290 {
291 puts ("thread not canceled");
292 return 1;
293 }
294
295 if (pthread_mutex_destroy (m) != 0)
296 {
297 printf ("mutex_destroy after condvar-canceled failed for %s\n", mas);
298 return 1;
299 }
300
301 return 0;
302}
303
304
305static int
306do_test (void)
307{
308 pthread_mutex_t mm;
309 m = &mm;
310
311 if (pthread_barrier_init (&b, NULL, 2) != 0)
312 {
313 puts ("barrier_init failed");
314 return 1;
315 }
316
317 if (pthread_cond_init (&c, NULL) != 0)
318 {
319 puts ("cond_init failed");
320 return 1;
321 }
322
323 puts ("check normal mutex");
324 int res = check_type ("normal", NULL);
325
326 pthread_mutexattr_t ma;
327 if (pthread_mutexattr_init (&ma) != 0)
328 {
329 puts ("1st mutexattr_init failed");
330 return 1;
331 }
332 if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_RECURSIVE) != 0)
333 {
334 puts ("1st mutexattr_settype failed");
335 return 1;
336 }
337 puts ("check recursive mutex");
338 res |= check_type ("recursive", &ma);
339 if (pthread_mutexattr_destroy (&ma) != 0)
340 {
341 puts ("1st mutexattr_destroy failed");
342 return 1;
343 }
344
345 if (pthread_mutexattr_init (&ma) != 0)
346 {
347 puts ("2nd mutexattr_init failed");
348 return 1;
349 }
350 if (pthread_mutexattr_settype (&ma, PTHREAD_MUTEX_ERRORCHECK) != 0)
351 {
352 puts ("2nd mutexattr_settype failed");
353 return 1;
354 }
355 puts ("check error-checking mutex");
356 res |= check_type ("error-checking", &ma);
357 if (pthread_mutexattr_destroy (&ma) != 0)
358 {
359 puts ("2nd mutexattr_destroy failed");
360 return 1;
361 }
362
363 return res;
364}
365
366#define TEST_FUNCTION do_test ()
367#include "../test-skeleton.c"
Note: See TracBrowser for help on using the repository browser.