iconv: Suppress array out of bounds warning.
[platform/upstream/glibc.git] / nptl / tst-robust7.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 <stdbool.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24
25
26 static pthread_barrier_t b;
27 static pthread_cond_t c = PTHREAD_COND_INITIALIZER;
28 static pthread_mutex_t m;
29 static bool first = true;
30
31
32 static void *
33 tf (void *arg)
34 {
35   long int n = (long int) arg;
36
37   if (pthread_mutex_lock (&m) != 0)
38     {
39       printf ("thread %ld: mutex_lock failed\n", n + 1);
40       exit (1);
41     }
42
43   int e = pthread_barrier_wait (&b);
44   if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
45     {
46       printf ("thread %ld: barrier_wait failed\n", n + 1);
47       exit (1);
48     }
49
50   e = pthread_cond_wait (&c, &m);
51   if (first)
52     {
53       if (e != 0)
54         {
55           printf ("thread %ld: cond_wait failed\n", n + 1);
56           exit (1);
57         }
58       first = false;
59     }
60   else
61     {
62       if (e != EOWNERDEAD)
63         {
64           printf ("thread %ld: cond_wait did not return EOWNERDEAD\n", n + 1);
65           exit (1);
66         }
67     }
68
69   if (pthread_cancel (pthread_self ()) != 0)
70     {
71       printf ("thread %ld: cancel failed\n", n + 1);
72       exit (1);
73     }
74
75   pthread_testcancel ();
76
77   printf ("thread %ld: testcancel returned\n", n + 1);
78   exit (1);
79 }
80
81
82 static int
83 do_test (void)
84 {
85   pthread_mutexattr_t a;
86   if (pthread_mutexattr_init (&a) != 0)
87     {
88       puts ("mutexattr_init failed");
89       return 1;
90     }
91
92   if (pthread_mutexattr_setrobust_np (&a, PTHREAD_MUTEX_ROBUST_NP) != 0)
93     {
94       puts ("mutexattr_setrobust failed");
95       return 1;
96     }
97
98 #ifdef ENABLE_PI
99   if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
100     {
101       puts ("pthread_mutexattr_setprotocol failed");
102       return 1;
103     }
104 #endif
105
106   int e;
107   e = pthread_mutex_init (&m, &a);
108   if (e != 0)
109     {
110 #ifdef ENABLE_PI
111       if (e == ENOTSUP)
112         {
113           puts ("PI robust mutexes not supported");
114           return 0;
115         }
116 #endif
117       puts ("mutex_init failed");
118       return 1;
119     }
120
121   if (pthread_mutexattr_destroy (&a) != 0)
122     {
123       puts ("mutexattr_destroy failed");
124       return 1;
125     }
126
127   if (pthread_barrier_init (&b, NULL, 2) != 0)
128     {
129       puts ("barrier_init failed");
130       return 1;
131     }
132
133 #define N 5
134   pthread_t th[N];
135   for (long int n = 0; n < N; ++n)
136     {
137       if (pthread_create (&th[n], NULL, tf, (void *) n) != 0)
138         {
139           printf ("pthread_create loop %ld failed\n", n + 1);
140           return 1;
141         }
142
143       e = pthread_barrier_wait (&b);
144       if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
145         {
146           printf ("parent: barrier_wait failed in round %ld\n", n + 1);
147           return 1;
148         }
149     }
150
151   if (pthread_mutex_lock (&m) != 0)
152     {
153       puts ("parent: mutex_lock failed");
154       return 1;
155     }
156
157   if (pthread_mutex_unlock (&m) != 0)
158     {
159       puts ("parent: mutex_unlock failed");
160       return 1;
161     }
162
163   if (pthread_cond_broadcast (&c) != 0)
164     {
165       puts ("cond_broadcast failed");
166       return 1;
167     }
168
169   for (int n = 0; n < N; ++n)
170     {
171       void *res;
172       if (pthread_join (th[n], &res) != 0)
173         {
174           printf ("join round %d failed\n", n + 1);
175           return 1;
176         }
177       if (res != PTHREAD_CANCELED)
178         {
179           printf ("thread %d not canceled\n", n + 1);
180           return 1;
181         }
182     }
183
184   e = pthread_mutex_lock (&m);
185   if (e == 0)
186     {
187       puts ("parent: 2nd mutex_lock succeeded");
188       return 1;
189     }
190   if (e != EOWNERDEAD)
191     {
192       puts ("parent: mutex_lock did not return EOWNERDEAD");
193       return 1;
194     }
195
196   if (pthread_mutex_unlock (&m) != 0)
197     {
198       puts ("parent: 2nd mutex_unlock failed");
199       return 1;
200     }
201
202   if (pthread_mutex_destroy (&m) != 0)
203     {
204       puts ("mutex_destroy failed");
205       return 1;
206     }
207
208   return 0;
209 }
210
211 #define TEST_FUNCTION do_test ()
212 #include "../test-skeleton.c"