OSDN Git Service

Replace FSF snail mail address with URLs
[uclinux-h8/uClibc.git] / test / nptl / tst-mutex9.c
1 /* Copyright (C) 2003, 2004 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 <string.h>
23 #include <unistd.h>
24 #include <sys/mman.h>
25 #include <sys/wait.h>
26 #include <stdint.h>
27 #include <stdlib.h>
28 #include <sys/time.h>
29
30 int gettimeofday(struct timeval *tv, struct timezone *tz);
31
32
33 static int
34 do_test (void)
35 {
36   size_t ps = sysconf (_SC_PAGESIZE);
37   char tmpfname[] = "/tmp/tst-mutex9.XXXXXX";
38   char data[ps];
39   void *mem;
40   int fd;
41   pthread_mutex_t *m;
42   pthread_mutexattr_t a;
43   pid_t pid;
44   char *p;
45
46   fd = mkstemp (tmpfname);
47   if (fd == -1)
48     {
49       printf ("cannot open temporary file: %m\n");
50       return 1;
51     }
52
53   /* Make sure it is always removed.  */
54   unlink (tmpfname);
55
56   /* Create one page of data.  */
57   memset (data, '\0', ps);
58
59   /* Write the data to the file.  */
60   if (write (fd, data, ps) != (ssize_t) ps)
61     {
62       puts ("short write");
63       return 1;
64     }
65
66   mem = mmap (NULL, ps, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
67   if (mem == MAP_FAILED)
68     {
69       printf ("mmap failed: %m\n");
70       return 1;
71     }
72
73   m = (pthread_mutex_t *) (((uintptr_t) mem + __alignof (pthread_mutex_t))
74                            & ~(__alignof (pthread_mutex_t) - 1));
75   p = (char *) (m + 1);
76
77   if (pthread_mutexattr_init (&a) != 0)
78     {
79       puts ("mutexattr_init failed");
80       return 1;
81     }
82
83   if (pthread_mutexattr_setpshared (&a, PTHREAD_PROCESS_SHARED) != 0)
84     {
85       puts ("mutexattr_setpshared failed");
86       return 1;
87     }
88
89   if (pthread_mutexattr_settype (&a, PTHREAD_MUTEX_RECURSIVE) != 0)
90     {
91       puts ("mutexattr_settype failed");
92       return 1;
93     }
94
95   if (pthread_mutex_init (m, &a) != 0)
96     {
97       puts ("mutex_init failed");
98       return 1;
99     }
100
101   if (pthread_mutex_lock (m) != 0)
102     {
103       puts ("mutex_lock failed");
104       return 1;
105     }
106
107   if (pthread_mutexattr_destroy (&a) != 0)
108     {
109       puts ("mutexattr_destroy failed");
110       return 1;
111     }
112
113   puts ("going to fork now");
114   pid = fork ();
115   if (pid == -1)
116     {
117       puts ("fork failed");
118       return 1;
119     }
120   else if (pid == 0)
121     {
122       if (pthread_mutex_trylock (m) == 0)
123         {
124           puts ("child: mutex_trylock succeeded");
125           exit (1);
126         }
127
128       if (pthread_mutex_unlock (m) == 0)
129         {
130           puts ("child: mutex_unlock succeeded");
131           exit (1);
132         }
133
134       struct timeval tv;
135       gettimeofday (&tv, NULL);
136       struct timespec ts;
137       TIMEVAL_TO_TIMESPEC (&tv, &ts);
138       ts.tv_nsec += 500000000;
139       if (ts.tv_nsec >= 1000000000)
140         {
141           ++ts.tv_sec;
142           ts.tv_nsec -= 1000000000;
143         }
144
145       int e = pthread_mutex_timedlock (m, &ts);
146       if (e == 0)
147         {
148           puts ("child: mutex_timedlock succeeded");
149           exit (1);
150         }
151       if (e != ETIMEDOUT)
152         {
153           puts ("child: mutex_timedlock didn't time out");
154           exit (1);
155         }
156
157       alarm (1);
158
159       pthread_mutex_lock (m);
160
161       puts ("child: mutex_lock returned");
162
163       exit (0);
164     }
165
166   sleep (2);
167
168   int status;
169   if (TEMP_FAILURE_RETRY (waitpid (pid, &status, 0)) != pid)
170     {
171       puts ("waitpid failed");
172       return 1;
173     }
174   if (! WIFSIGNALED (status))
175     {
176       puts ("child not killed by signal");
177       return 1;
178     }
179   if (WTERMSIG (status) != SIGALRM)
180     {
181       puts ("child not killed by SIGALRM");
182       return 1;
183     }
184
185   return 0;
186 }
187
188 #define TIMEOUT 3
189 #define TEST_FUNCTION do_test ()
190 #include "../test-skeleton.c"