Initial revision
[kopensolaris-gnu/glibc.git] / nptl / tst-rwlock6.c
1 /* Copyright (C) 2002 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, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <errno.h>
21 #include <pthread.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 #include <string.h>
25 #include <sys/time.h>
26
27
28 static int kind[] =
29   {
30     PTHREAD_RWLOCK_PREFER_READER_NP,
31     PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP,
32     PTHREAD_RWLOCK_PREFER_WRITER_NP,
33   };
34
35
36 static void *
37 tf (void *arg)
38 {
39   pthread_rwlock_t *r = arg;
40
41   /* Timeout: 0.3 secs.  */
42   struct timeval tv;
43   (void) gettimeofday (&tv, NULL);
44
45   struct timespec ts;
46   TIMEVAL_TO_TIMESPEC (&tv, &ts);
47   ts.tv_nsec += 300000000;
48   if (ts.tv_nsec >= 1000000000)
49     {
50       ts.tv_nsec -= 1000000000;
51       ++ts.tv_sec;
52     }
53
54   int err = pthread_rwlock_timedrdlock (r, &ts);
55   if (err == 0)
56     {
57       puts ("rwlock_timedrdlock returned");
58       pthread_exit ((void *) 1l);
59     }
60
61   if (err != ETIMEDOUT)
62     {
63       printf ("err = %s (%d), expected %s (%d)\n",
64               strerror (err), err, strerror (ETIMEDOUT), ETIMEDOUT);
65       pthread_exit ((void *) 1l);
66     }
67
68   struct timeval tv2;
69   (void) gettimeofday (&tv2, NULL);
70
71   timersub (&tv2, &tv, &tv);
72
73   if (tv.tv_usec < 200000)
74     {
75       puts ("timeout too short");
76       pthread_exit ((void *) 1l);
77     }
78
79   return NULL;
80 }
81
82
83 static int
84 do_test (void)
85 {
86   int cnt;
87   for (cnt = 0; cnt < sizeof (kind) / sizeof (kind[0]); ++cnt)
88     {
89       pthread_rwlock_t r;
90       pthread_rwlockattr_t a;
91
92       if (pthread_rwlockattr_init (&a) != 0)
93         {
94           printf ("round %d: rwlockattr_t failed\n", cnt);
95           exit (1);
96         }
97
98       if (pthread_rwlockattr_setkind_np (&a, kind[cnt]) != 0)
99         {
100           printf ("round %d: rwlockattr_setkind failed\n", cnt);
101           exit (1);
102         }
103
104       if (pthread_rwlock_init (&r, &a) != 0)
105         {
106           printf ("round %d: rwlock_init failed\n", cnt);
107           exit (1);
108         }
109
110       if (pthread_rwlockattr_destroy (&a) != 0)
111         {
112           printf ("round %d: rwlockattr_destroy failed\n", cnt);
113           exit (1);
114         }
115
116       struct timeval tv;
117       (void) gettimeofday (&tv, NULL);
118
119       struct timespec ts;
120       TIMEVAL_TO_TIMESPEC (&tv, &ts);
121
122       ++ts.tv_sec;
123
124       /* Get a write lock.  */
125       if (pthread_rwlock_timedwrlock (&r, &ts) != 0)
126         {
127           printf ("round %d: rwlock_wrlock failed\n", cnt);
128           exit (1);
129         }
130
131       pthread_t th;
132       if (pthread_create (&th, NULL, tf, &r) != 0)
133         {
134           printf ("round %d: create failed\n", cnt);
135           exit (1);
136         }
137
138       void *status;
139       if (pthread_join (th, &status) != 0)
140         {
141           printf ("round %d: join failed\n", cnt);
142           exit (1);
143         }
144       if (status != NULL)
145         {
146           printf ("failure in round %d\n", cnt);
147           exit (1);
148         }
149
150       if (pthread_rwlock_destroy (&r) != 0)
151         {
152           printf ("round %d: rwlock_destroy failed\n", cnt);
153           exit (1);
154         }
155     }
156
157   return 0;
158 }
159
160 #define TEST_FUNCTION do_test ()
161 #include "../test-skeleton.c"