Don't reduce test timeout to less than default
[platform/upstream/glibc.git] / nptl / tst-mutex4.c
1 /* Copyright (C) 2002-2018 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
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 <stdint.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 #include <sys/mman.h>
27 #include <sys/wait.h>
28
29
30 static int
31 do_test (void)
32 {
33   size_t ps = sysconf (_SC_PAGESIZE);
34   char tmpfname[] = "/tmp/tst-mutex4.XXXXXX";
35   char data[ps];
36   void *mem;
37   int fd;
38   pthread_mutex_t *m;
39   pthread_mutexattr_t a;
40   pid_t pid;
41   char *p;
42   int err;
43   int s;
44   pthread_barrier_t *b;
45   pthread_barrierattr_t ba;
46
47   fd = mkstemp (tmpfname);
48   if (fd == -1)
49     {
50       printf ("cannot open temporary file: %m\n");
51       return 1;
52     }
53
54   /* Make sure it is always removed.  */
55   unlink (tmpfname);
56
57   /* Create one page of data.  */
58   memset (data, '\0', ps);
59
60   /* Write the data to the file.  */
61   if (write (fd, data, ps) != (ssize_t) ps)
62     {
63       puts ("short write");
64       return 1;
65     }
66
67   mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
68   if (mem == MAP_FAILED)
69     {
70       printf ("mmap failed: %m\n");
71       return 1;
72     }
73
74   m = (pthread_mutex_t *) (((uintptr_t) mem + __alignof (pthread_mutex_t) - 1)
75                            & ~(__alignof (pthread_mutex_t) - 1));
76   b = (pthread_barrier_t *) (((uintptr_t) (m + 1)
77                               + __alignof (pthread_barrier_t) - 1)
78                              & ~(__alignof (pthread_barrier_t) - 1));
79   p = (char *) (b + 1);
80
81   if (pthread_mutexattr_init (&a) != 0)
82     {
83       puts ("mutexattr_init failed");
84       return 1;
85     }
86
87   if (pthread_mutexattr_getpshared (&a, &s) != 0)
88     {
89       puts ("1st mutexattr_getpshared failed");
90       return 1;
91     }
92
93   if (s != PTHREAD_PROCESS_PRIVATE)
94     {
95       puts ("default pshared value wrong");
96       return 1;
97     }
98
99   if (pthread_mutexattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0)
100     {
101       puts ("mutexattr_setpshared failed");
102       return 1;
103     }
104
105   if (pthread_mutexattr_getpshared (&a, &s) != 0)
106     {
107       puts ("2nd mutexattr_getpshared failed");
108       return 1;
109     }
110
111   if (s != PTHREAD_PROCESS_SHARED)
112     {
113       puts ("pshared value after setpshared call wrong");
114       return 1;
115     }
116
117 #ifdef ENABLE_PI
118   if (pthread_mutexattr_setprotocol (&a, PTHREAD_PRIO_INHERIT) != 0)
119     {
120       puts ("pthread_mutexattr_setprotocol failed");
121       return 1;
122     }
123 #endif
124
125   if ((err = pthread_mutex_init (m, &a)) != 0)
126     {
127 #ifdef ENABLE_PI
128       if (err == ENOTSUP)
129         {
130           puts ("PI mutexes unsupported");
131           return 0;
132         }
133 #endif
134       puts ("mutex_init failed");
135       return 1;
136     }
137
138   if (pthread_mutex_lock (m) != 0)
139     {
140       puts ("mutex_lock failed");
141       return 1;
142     }
143
144   if (pthread_mutexattr_destroy (&a) != 0)
145     {
146       puts ("mutexattr_destroy failed");
147       return 1;
148     }
149
150   if (pthread_barrierattr_init (&ba) != 0)
151     {
152       puts ("barrierattr_init failed");
153       return 1;
154     }
155
156   if (pthread_barrierattr_setpshared (&ba, PTHREAD_PROCESS_SHARED) != 0)
157     {
158       puts ("barrierattr_setpshared failed");
159       return 1;
160     }
161
162   if (pthread_barrier_init (b, &ba, 2) != 0)
163     {
164       puts ("barrier_init failed");
165       return 1;
166     }
167
168   if (pthread_barrierattr_destroy (&ba) != 0)
169     {
170       puts ("barrierattr_destroy failed");
171       return 1;
172     }
173
174   err = pthread_mutex_trylock (m);
175   if (err == 0)
176     {
177       puts ("mutex_trylock succeeded");
178       return 1;
179     }
180   else if (err != EBUSY)
181     {
182       puts ("mutex_trylock didn't return EBUSY");
183       return 1;
184     }
185
186   *p = 0;
187
188   if (pthread_mutex_unlock (m) != 0)
189     {
190       puts ("parent: 1st mutex_unlock failed");
191       return 1;
192     }
193
194   puts ("going to fork now");
195   pid = fork ();
196   if (pid == -1)
197     {
198       puts ("fork failed");
199       return 1;
200     }
201   else if (pid == 0)
202     {
203       if (pthread_mutex_lock (m) != 0)
204         {
205           puts ("child: mutex_lock failed");
206           return 1;
207         }
208
209       int e = pthread_barrier_wait (b);
210       if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
211         {
212           puts ("child: barrier_wait failed");
213           return 1;
214         }
215
216       if ((*p)++ != 0)
217         {
218           puts ("child: *p != 0");
219           return 1;
220         }
221
222       if (pthread_mutex_unlock (m) != 0)
223         {
224           puts ("child: mutex_unlock failed");
225           return 1;
226         }
227
228       puts ("child done");
229     }
230   else
231     {
232       int e = pthread_barrier_wait (b);
233       if (e != 0 && e != PTHREAD_BARRIER_SERIAL_THREAD)
234         {
235           puts ("parent: barrier_wait failed");
236           return 1;
237         }
238
239       if (pthread_mutex_lock (m) != 0)
240         {
241           puts ("parent: 2nd mutex_lock failed");
242           return 1;
243         }
244
245       if (*p != 1)
246         {
247           puts ("*p != 1");
248           return 1;
249         }
250
251       if (pthread_mutex_unlock (m) != 0)
252         {
253           puts ("parent: 2nd mutex_unlock failed");
254           return 1;
255         }
256
257       if (pthread_mutex_destroy (m) != 0)
258         {
259           puts ("mutex_destroy failed");
260           return 1;
261         }
262
263       if (pthread_barrier_destroy (b) != 0)
264         {
265           puts ("barrier_destroy failed");
266           return 1;
267         }
268
269       puts ("parent done");
270     }
271
272   return 0;
273 }
274
275 #define TEST_FUNCTION do_test ()
276 #include "../test-skeleton.c"