iconv: Suppress array out of bounds warning.
[platform/upstream/glibc.git] / nptl / tst-robust1.c
1 /* Copyright (C) 2005-2015 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2005.
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
24
25 static pthread_mutex_t m1;
26 static pthread_mutex_t m2;
27 static pthread_barrier_t b;
28
29
30 #ifndef LOCK
31 # define LOCK(m) pthread_mutex_lock (m)
32 #endif
33
34
35 static void *
36 tf (void *arg)
37 {
38   long int round = (long int) arg;
39
40   if (pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL) != 0)
41     {
42       printf ("%ld: setcancelstate failed\n", round);
43       exit (1);
44     }
45
46   int e = LOCK (&m1);
47   if (e != 0)
48     {
49       printf ("%ld: child: mutex_lock m1 failed with error %d\n", round, e);
50       exit (1);
51     }
52
53   e = LOCK (&m2);
54   if (e != 0)
55     {
56       printf ("%ld: child: mutex_lock m2 failed with error %d\n", round, e);
57       exit (1);
58     }
59
60   e = pthread_barrier_wait (&b);
61   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
62     {
63       printf ("%ld: child: 1st barrier_wait failed\n", round);
64       exit (1);
65     }
66
67   e = pthread_barrier_wait (&b);
68   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
69     {
70       printf ("%ld: child: 2nd barrier_wait failed\n", round);
71       exit (1);
72     }
73
74   pthread_testcancel ();
75
76   printf ("%ld: testcancel returned\n", round);
77   exit (1);
78 }
79
80
81 static int
82 do_test (void)
83 {
84 #ifdef PREPARE_TMO
85   PREPARE_TMO;
86 #endif
87
88   pthread_mutexattr_t a;
89   if (pthread_mutexattr_init (&a) != 0)
90     {
91       puts ("mutexattr_init failed");
92       return 1;
93     }
94   if (pthread_mutexattr_setrobust_np (&a, PTHREAD_MUTEX_ROBUST_NP) != 0)
95     {
96       puts ("mutexattr_setrobust failed");
97       return 1;
98     }
99
100 #ifdef ENABLE_PI
101   if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
102     {
103       puts ("pthread_mutexattr_setprotocol failed");
104       return 1;
105     }
106   else
107     {
108       int e = pthread_mutex_init (&m1, &a);
109       if (e == ENOTSUP)
110         {
111           puts ("PI robust mutexes not supported");
112           return 0;
113         }
114       else if (e != 0)
115         {
116           puts ("mutex_init m1 failed");
117           return 1;
118         }
119       pthread_mutex_destroy (&m1);
120     }
121 #endif
122
123 #ifndef NOT_CONSISTENT
124   if (pthread_mutex_init (&m1, &a) != 0)
125     {
126       puts ("mutex_init m1 failed");
127       return 1;
128     }
129
130   if (pthread_mutex_init (&m2, &a) != 0)
131     {
132       puts ("mutex_init m2 failed");
133       return 1;
134     }
135 #endif
136
137   if (pthread_barrier_init (&b, NULL, 2) != 0)
138     {
139       puts ("barrier_init failed");
140       return 1;
141     }
142
143   for (long int round = 1; round < 5; ++round)
144     {
145 #ifdef NOT_CONSISTENT
146       if (pthread_mutex_init (&m1 , &a) != 0)
147         {
148           puts ("mutex_init m1 failed");
149           return 1;
150         }
151       if (pthread_mutex_init (&m2 , &a) != 0)
152         {
153           puts ("mutex_init m2 failed");
154           return 1;
155         }
156 #endif
157
158       pthread_t th;
159       if (pthread_create (&th, NULL, tf, (void *) round) != 0)
160         {
161           printf ("%ld: create failed\n", round);
162           return 1;
163         }
164
165       int e = pthread_barrier_wait (&b);
166       if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
167         {
168           printf ("%ld: parent: 1st barrier_wait failed\n", round);
169           return 1;
170         }
171
172       if (pthread_cancel (th) != 0)
173         {
174           printf ("%ld: cancel failed\n", round);
175           return 1;
176         }
177
178       e = pthread_barrier_wait (&b);
179       if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
180         {
181           printf ("%ld: parent: 2nd barrier_wait failed\n", round);
182           return 1;
183         }
184
185 #ifndef AFTER_JOIN
186       if (round & 1)
187 #endif
188         {
189           void *res;
190           if (pthread_join (th, &res) != 0)
191             {
192               printf ("%ld: join failed\n", round);
193               return 1;
194             }
195           if (res != PTHREAD_CANCELED)
196             {
197               printf ("%ld: thread not canceled\n", round);
198               return 1;
199             }
200         }
201
202       e = LOCK (&m1);
203       if (e == 0)
204         {
205           printf ("%ld: parent: mutex_lock m1 succeeded\n", round);
206           return 1;
207         }
208       if (e != EOWNERDEAD)
209         {
210           printf ("%ld: parent: mutex_lock m1 returned wrong code\n", round);
211           return 1;
212         }
213
214       e = LOCK (&m2);
215       if (e == 0)
216         {
217           printf ("%ld: parent: mutex_lock m2 succeeded\n", round);
218           return 1;
219         }
220       if (e != EOWNERDEAD)
221         {
222           printf ("%ld: parent: mutex_lock m2 returned wrong code\n", round);
223           return 1;
224         }
225
226 #ifndef AFTER_JOIN
227       if ((round & 1) == 0)
228         {
229           void *res;
230           if (pthread_join (th, &res) != 0)
231             {
232               printf ("%ld: join failed\n", round);
233               return 1;
234             }
235           if (res != PTHREAD_CANCELED)
236             {
237               printf ("%ld: thread not canceled\n", round);
238               return 1;
239             }
240         }
241 #endif
242
243 #ifndef NOT_CONSISTENT
244       e = pthread_mutex_consistent_np (&m1);
245       if (e != 0)
246         {
247           printf ("%ld: mutex_consistent m1 failed with error %d\n", round, e);
248           return 1;
249         }
250
251       e = pthread_mutex_consistent_np (&m2);
252       if (e != 0)
253         {
254           printf ("%ld: mutex_consistent m2 failed with error %d\n", round, e);
255           return 1;
256         }
257 #endif
258
259       e = pthread_mutex_unlock (&m1);
260       if (e != 0)
261         {
262           printf ("%ld: mutex_unlock m1 failed with %d\n", round, e);
263           return 1;
264         }
265
266       e = pthread_mutex_unlock (&m2);
267       if (e != 0)
268         {
269           printf ("%ld: mutex_unlock m2 failed with %d\n", round, e);
270           return 1;
271         }
272
273 #ifdef NOT_CONSISTENT
274       e = LOCK (&m1);
275       if (e == 0)
276         {
277           printf ("%ld: locking inconsistent mutex m1 succeeded\n", round);
278           return 1;
279         }
280       if (e != ENOTRECOVERABLE)
281         {
282           printf ("%ld: locking inconsistent mutex m1 failed with error %d\n",
283                   round, e);
284           return 1;
285         }
286
287       if (pthread_mutex_destroy (&m1) != 0)
288         {
289           puts ("mutex_destroy m1 failed");
290           return 1;
291         }
292
293       e = LOCK (&m2);
294       if (e == 0)
295         {
296           printf ("%ld: locking inconsistent mutex m2 succeeded\n", round);
297           return 1;
298         }
299       if (e != ENOTRECOVERABLE)
300         {
301           printf ("%ld: locking inconsistent mutex m2 failed with error %d\n",
302                   round, e);
303           return 1;
304         }
305
306       if (pthread_mutex_destroy (&m2) != 0)
307         {
308           puts ("mutex_destroy m2 failed");
309           return 1;
310         }
311 #endif
312     }
313
314 #ifndef NOT_CONSISTENT
315   if (pthread_mutex_destroy (&m1) != 0)
316     {
317       puts ("mutex_destroy m1 failed");
318       return 1;
319     }
320
321   if (pthread_mutex_destroy (&m2) != 0)
322     {
323       puts ("mutex_destroy m2 failed");
324       return 1;
325     }
326 #endif
327
328   if (pthread_mutexattr_destroy (&a) != 0)
329     {
330       puts ("mutexattr_destroy failed");
331       return 1;
332     }
333
334   return 0;
335 }
336
337 #define TEST_FUNCTION do_test ()
338 #include "../test-skeleton.c"