OSDN Git Service

Replace FSF snail mail address with URLs
[uclinux-h8/uClibc.git] / test / nptl / tst-cond8.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 #include <errno.h>
20 #include <pthread.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <time.h>
24 #include <sys/time.h>
25
26
27 static pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
28 static pthread_mutex_t mut = PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP;
29
30 static pthread_barrier_t bar;
31
32
33 static void
34 ch (void *arg)
35 {
36   int e = pthread_mutex_lock (&mut);
37   if (e == 0)
38     {
39       puts ("mutex not locked at all by cond_wait");
40       exit (1);
41     }
42
43   if (e != EDEADLK)
44     {
45       puts ("no deadlock error signaled");
46       exit (1);
47     }
48
49   if (pthread_mutex_unlock (&mut) != 0)
50     {
51       puts ("ch: cannot unlock mutex");
52       exit (1);
53     }
54
55   puts ("ch done");
56 }
57
58
59 static void *
60 tf1 (void *p)
61 {
62   int err;
63
64   if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) != 0
65       || pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, NULL) != 0)
66     {
67       puts ("cannot set cancellation options");
68       exit (1);
69     }
70
71   err = pthread_mutex_lock (&mut);
72   if (err != 0)
73     {
74       puts ("child: cannot get mutex");
75       exit (1);
76     }
77
78   err = pthread_barrier_wait (&bar);
79   if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
80     {
81       printf ("barrier_wait returned %d\n", err);
82       exit (1);
83     }
84
85   puts ("child: got mutex; waiting");
86
87   pthread_cleanup_push (ch, NULL);
88
89   pthread_cond_wait (&cond, &mut);
90
91   pthread_cleanup_pop (0);
92
93   puts ("child: cond_wait should not have returned");
94
95   return NULL;
96 }
97
98
99 static void *
100 tf2 (void *p)
101 {
102   int err;
103
104   if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) != 0
105       || pthread_setcanceltype (PTHREAD_CANCEL_DEFERRED, NULL) != 0)
106     {
107       puts ("cannot set cancellation options");
108       exit (1);
109     }
110
111   err = pthread_mutex_lock (&mut);
112   if (err != 0)
113     {
114       puts ("child: cannot get mutex");
115       exit (1);
116     }
117
118   err = pthread_barrier_wait (&bar);
119   if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
120     {
121       printf ("barrier_wait returned %d\n", err);
122       exit (1);
123     }
124
125   puts ("child: got mutex; waiting");
126
127   pthread_cleanup_push (ch, NULL);
128
129   /* Current time.  */
130   struct timeval tv;
131   (void) gettimeofday (&tv, NULL);
132   /* +1000 seconds in correct format.  */
133   struct timespec ts;
134   TIMEVAL_TO_TIMESPEC (&tv, &ts);
135   ts.tv_sec += 1000;
136
137   pthread_cond_timedwait (&cond, &mut, &ts);
138
139   pthread_cleanup_pop (0);
140
141   puts ("child: cond_wait should not have returned");
142
143   return NULL;
144 }
145
146
147 static int
148 do_test (void)
149 {
150   pthread_t th;
151   int err;
152
153   printf ("&cond = %p\n&mut = %p\n", &cond, &mut);
154
155   puts ("parent: get mutex");
156
157   err = pthread_barrier_init (&bar, NULL, 2);
158   if (err != 0)
159     {
160       puts ("parent: cannot init barrier");
161       exit (1);
162     }
163
164   puts ("parent: create child");
165
166   err = pthread_create (&th, NULL, tf1, NULL);
167   if (err != 0)
168     {
169       puts ("parent: cannot create thread");
170       exit (1);
171     }
172
173   puts ("parent: wait for child to lock mutex");
174
175   err = pthread_barrier_wait (&bar);
176   if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
177     {
178       puts ("parent: cannot wait for barrier");
179       exit (1);
180     }
181
182   err = pthread_mutex_lock (&mut);
183   if (err != 0)
184     {
185       puts ("parent: mutex_lock failed");
186       exit (1);
187     }
188
189   err = pthread_mutex_unlock (&mut);
190   if (err != 0)
191     {
192       puts ("parent: mutex_unlock failed");
193       exit (1);
194     }
195
196   if (pthread_cancel (th) != 0)
197     {
198       puts ("cannot cancel thread");
199       exit (1);
200     }
201
202   void *r;
203   err = pthread_join (th, &r);
204   if (err != 0)
205     {
206       puts ("parent: failed to join");
207       exit (1);
208     }
209
210   if (r != PTHREAD_CANCELED)
211     {
212       puts ("child hasn't been canceled");
213       exit (1);
214     }
215
216
217
218   puts ("parent: create 2nd child");
219
220   err = pthread_create (&th, NULL, tf2, NULL);
221   if (err != 0)
222     {
223       puts ("parent: cannot create thread");
224       exit (1);
225     }
226
227   puts ("parent: wait for child to lock mutex");
228
229   err = pthread_barrier_wait (&bar);
230   if (err != 0 && err != PTHREAD_BARRIER_SERIAL_THREAD)
231     {
232       puts ("parent: cannot wait for barrier");
233       exit (1);
234     }
235
236   err = pthread_mutex_lock (&mut);
237   if (err != 0)
238     {
239       puts ("parent: mutex_lock failed");
240       exit (1);
241     }
242
243   err = pthread_mutex_unlock (&mut);
244   if (err != 0)
245     {
246       puts ("parent: mutex_unlock failed");
247       exit (1);
248     }
249
250   if (pthread_cancel (th) != 0)
251     {
252       puts ("cannot cancel thread");
253       exit (1);
254     }
255
256   err = pthread_join (th, &r);
257   if (err != 0)
258     {
259       puts ("parent: failed to join");
260       exit (1);
261     }
262
263   if (r != PTHREAD_CANCELED)
264     {
265       puts ("child hasn't been canceled");
266       exit (1);
267     }
268
269   puts ("done");
270
271   return 0;
272 }
273
274
275 #define TEST_FUNCTION do_test ()
276 #include "../test-skeleton.c"