5b6b3001b27d43a27d9c66dfc851245eb7e4fb60
[platform/upstream/linaro-glibc.git] / nptl / tst-rwlock9.c
1 /* Test program for timedout read/write lock functions.
2    Copyright (C) 2000, 2003 Free Software Foundation, Inc.
3    Contributed by Ulrich Drepper <drepper@redhat.com>, 2000.
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 License as
7    published by the Free Software Foundation; either version 2.1 of the
8    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; see the file COPYING.LIB.  If not,
17    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18    Boston, MA 02111-1307, USA.  */
19
20 #include <errno.h>
21 #include <error.h>
22 #include <pthread.h>
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <time.h>
26 #include <unistd.h>
27 #include <sys/time.h>
28
29
30 #define NWRITERS 15
31 #define WRITETRIES 10
32 #define NREADERS 15
33 #define READTRIES 15
34
35 #define TIMEOUT 1000000
36 #define DELAY   1000000
37
38 static pthread_rwlock_t lock = PTHREAD_RWLOCK_WRITER_NONRECURSIVE_INITIALIZER_NP;
39
40
41 static void *
42 writer_thread (void *nr)
43 {
44   struct timespec ts;
45   struct timespec delay;
46   int n;
47
48   delay.tv_sec = 0;
49   delay.tv_nsec = DELAY;
50
51   for (n = 0; n < WRITETRIES; ++n)
52     {
53       int e;
54       do
55         {
56           struct timeval tv;
57           (void) gettimeofday (&tv, NULL);
58           TIMEVAL_TO_TIMESPEC (&tv, &ts);
59
60           ts.tv_nsec += 2 * TIMEOUT;
61
62           printf ("writer thread %ld tries again\n", (long int) nr);
63
64           e = pthread_rwlock_timedwrlock (&lock, &ts);
65           if (e != 0 && e != ETIMEDOUT)
66             {
67               puts ("timedwrlock failed");
68               exit (1);
69             }
70         }
71       while (e == ETIMEDOUT);
72
73       printf ("writer thread %ld succeeded\n", (long int) nr);
74
75       nanosleep (&delay, NULL);
76
77       if (pthread_rwlock_unlock (&lock) != 0)
78         {
79           puts ("unlock for writer failed");
80           exit (1);
81         }
82
83       printf ("writer thread %ld released\n", (long int) nr);
84     }
85
86   return NULL;
87 }
88
89
90 static void *
91 reader_thread (void *nr)
92 {
93   struct timespec ts;
94   struct timespec delay;
95   int n;
96
97   delay.tv_sec = 0;
98   delay.tv_nsec = DELAY;
99
100   for (n = 0; n < READTRIES; ++n)
101     {
102       int e;
103       do
104         {
105           struct timeval tv;
106           (void) gettimeofday (&tv, NULL);
107           TIMEVAL_TO_TIMESPEC (&tv, &ts);
108
109           ts.tv_nsec += TIMEOUT;
110
111           printf ("reader thread %ld tries again\n", (long int) nr);
112
113           e = pthread_rwlock_timedrdlock (&lock, &ts);
114           if (e != 0 && e != ETIMEDOUT)
115             {
116               puts ("timedrdlock failed");
117               exit (1);
118             }
119         }
120       while (e == ETIMEDOUT);
121
122       printf ("reader thread %ld succeeded\n", (long int) nr);
123
124       nanosleep (&delay, NULL);
125
126       if (pthread_rwlock_unlock (&lock) != 0)
127         {
128           puts ("unlock for reader failed");
129           exit (1);
130         }
131
132       printf ("reader thread %ld released\n", (long int) nr);
133     }
134
135   return NULL;
136 }
137
138
139 static int
140 do_test (void)
141 {
142   pthread_t thwr[NWRITERS];
143   pthread_t thrd[NREADERS];
144   int n;
145   void *res;
146
147   /* Make standard error the same as standard output.  */
148   dup2 (1, 2);
149
150   /* Make sure we see all message, even those on stdout.  */
151   setvbuf (stdout, NULL, _IONBF, 0);
152
153   for (n = 0; n < NWRITERS; ++n)
154     if (pthread_create (&thwr[n], NULL, writer_thread,
155                         (void *) (long int) n) != 0)
156       {
157         puts ("writer create failed");
158         exit (1);
159       }
160
161   for (n = 0; n < NREADERS; ++n)
162     if (pthread_create (&thrd[n], NULL, reader_thread,
163                         (void *) (long int) n) != 0)
164       {
165         puts ("reader create failed");
166         exit (1);
167       }
168
169   /* Wait for all the threads.  */
170   for (n = 0; n < NWRITERS; ++n)
171     if (pthread_join (thwr[n], &res) != 0)
172       {
173         puts ("writer join failed");
174         exit (1);
175       }
176   for (n = 0; n < NREADERS; ++n)
177     if (pthread_join (thrd[n], &res) != 0)
178       {
179         puts ("reader join failed");
180         exit (1);
181       }
182
183   return 0;
184 }
185
186 #undef TIMEOUT
187 #define TIMEOUT 30
188 #define TEST_FUNCTION do_test ()
189 #include "../test-skeleton.c"