]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/test/nptl/tst-rwlock6.c
update
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / test / nptl / tst-rwlock6.c
1 /* Copyright (C) 2002, 2003 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 <stdlib.h>
22 #include <stdio.h>
23 #include <string.h>
24 #include <sys/time.h>
25
26
27 static int kind[] =
28   {
29     PTHREAD_RWLOCK_PREFER_READER_NP,
30     PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,
31     PTHREAD_RWLOCK_PREFER_WRITER_NP,
32   };
33
34
35 static void *
36 tf (void *arg)
37 {
38   pthread_rwlock_t *r = arg;
39
40   /* Timeout: 0.3 secs.  */
41   struct timeval tv;
42   (void) gettimeofday (&tv, NULL);
43
44   struct timespec ts;
45   TIMEVAL_TO_TIMESPEC (&tv, &ts);
46   ts.tv_nsec += 300000000;
47   if (ts.tv_nsec >= 1000000000)
48     {
49       ts.tv_nsec -= 1000000000;
50       ++ts.tv_sec;
51     }
52
53   puts ("child calling timedrdlock");
54
55   int err = pthread_rwlock_timedrdlock (r, &ts);
56   if (err == 0)
57     {
58       puts ("rwlock_timedrdlock returned");
59       pthread_exit ((void *) 1l);
60     }
61
62   if (err != ETIMEDOUT)
63     {
64       printf ("err = %s (%d), expected %s (%d)\n",
65               strerror (err), err, strerror (ETIMEDOUT), ETIMEDOUT);
66       pthread_exit ((void *) 1l);
67     }
68
69   puts ("1st child timedrdlock done");
70
71   struct timeval tv2;
72   (void) gettimeofday (&tv2, NULL);
73
74   timersub (&tv2, &tv, &tv);
75
76   if (tv.tv_usec < 200000)
77     {
78       puts ("timeout too short");
79       pthread_exit ((void *) 1l);
80     }
81
82   (void) gettimeofday (&tv, NULL);
83   TIMEVAL_TO_TIMESPEC (&tv, &ts);
84   ts.tv_sec += 10;
85   /* Note that the following operation makes ts invalid.  */
86   ts.tv_nsec += 1000000000;
87
88   err = pthread_rwlock_timedrdlock (r, &ts);
89   if (err == 0)
90     {
91       puts ("2nd timedrdlock succeeded");
92       pthread_exit ((void *) 1l);
93     }
94   if (err != EINVAL)
95     {
96       puts ("2nd timedrdlock did not return EINVAL");
97       pthread_exit ((void *) 1l);
98     }
99
100   puts ("2nd child timedrdlock done");
101
102   return NULL;
103 }
104
105
106 static int
107 do_test (void)
108 {
109   size_t cnt;
110   for (cnt = 0; cnt < sizeof (kind) / sizeof (kind[0]); ++cnt)
111     {
112       pthread_rwlock_t r;
113       pthread_rwlockattr_t a;
114
115       if (pthread_rwlockattr_init (&a) != 0)
116         {
117           printf ("round %Zu: rwlockattr_t failed\n", cnt);
118           exit (1);
119         }
120
121       if (pthread_rwlockattr_setkind_np (&a, kind[cnt]) != 0)
122         {
123           printf ("round %Zu: rwlockattr_setkind failed\n", cnt);
124           exit (1);
125         }
126
127       if (pthread_rwlock_init (&r, &a) != 0)
128         {
129           printf ("round %Zu: rwlock_init failed\n", cnt);
130           exit (1);
131         }
132
133       if (pthread_rwlockattr_destroy (&a) != 0)
134         {
135           printf ("round %Zu: rwlockattr_destroy failed\n", cnt);
136           exit (1);
137         }
138
139       struct timeval tv;
140       (void) gettimeofday (&tv, NULL);
141
142       struct timespec ts;
143       TIMEVAL_TO_TIMESPEC (&tv, &ts);
144
145       ++ts.tv_sec;
146
147       /* Get a write lock.  */
148       int e = pthread_rwlock_timedwrlock (&r, &ts);
149       if (e != 0)
150         {
151           printf ("round %Zu: rwlock_timedwrlock failed (%d)\n", cnt, e);
152           exit (1);
153         }
154
155       puts ("1st timedwrlock done");
156
157       (void) gettimeofday (&tv, NULL);
158       TIMEVAL_TO_TIMESPEC (&tv, &ts);
159       ++ts.tv_sec;
160       e = pthread_rwlock_timedrdlock (&r, &ts);
161       if (e == 0)
162         {
163           puts ("timedrdlock succeeded");
164           exit (1);
165         }
166       if (e != EDEADLK)
167         {
168           puts ("timedrdlock did not return EDEADLK");
169           exit (1);
170         }
171
172       puts ("1st timedrdlock done");
173
174       (void) gettimeofday (&tv, NULL);
175       TIMEVAL_TO_TIMESPEC (&tv, &ts);
176       ++ts.tv_sec;
177       e = pthread_rwlock_timedwrlock (&r, &ts);
178       if (e == 0)
179         {
180           puts ("2nd timedwrlock succeeded");
181           exit (1);
182         }
183       if (e != EDEADLK)
184         {
185           puts ("2nd timedwrlock did not return EDEADLK");
186           exit (1);
187         }
188
189       puts ("2nd timedwrlock done");
190
191       pthread_t th;
192       if (pthread_create (&th, NULL, tf, &r) != 0)
193         {
194           printf ("round %Zu: create failed\n", cnt);
195           exit (1);
196         }
197
198       puts ("started thread");
199
200       void *status;
201       if (pthread_join (th, &status) != 0)
202         {
203           printf ("round %Zu: join failed\n", cnt);
204           exit (1);
205         }
206       if (status != NULL)
207         {
208           printf ("failure in round %Zu\n", cnt);
209           exit (1);
210         }
211
212       puts ("joined thread");
213
214       if (pthread_rwlock_destroy (&r) != 0)
215         {
216           printf ("round %Zu: rwlock_destroy failed\n", cnt);
217           exit (1);
218         }
219     }
220
221   return 0;
222 }
223
224 #define TEST_FUNCTION do_test ()
225 #include "../test-skeleton.c"