]> git.ipfire.org Git - thirdparty/glibc.git/blame - nptl/tst-rwlock9.c
nptl: pthread_rwlock: Move timeout validation into _full functions
[thirdparty/glibc.git] / nptl / tst-rwlock9.c
CommitLineData
26a526fa 1/* Test program for timedout read/write lock functions.
04277e02 2 Copyright (C) 2000-2019 Free Software Foundation, Inc.
26a526fa
UD
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
59ba27a6
PE
16 License along with the GNU C Library; see the file COPYING.LIB. If
17 not, see <http://www.gnu.org/licenses/>. */
26a526fa
UD
18
19#include <errno.h>
20#include <error.h>
21#include <pthread.h>
22#include <stdio.h>
23#include <stdlib.h>
24#include <time.h>
25#include <unistd.h>
26#include <sys/time.h>
495514ee
MC
27#include <support/check.h>
28#include <support/timespec.h>
26a526fa
UD
29
30
31#define NWRITERS 15
32#define WRITETRIES 10
33#define NREADERS 15
34#define READTRIES 15
35
495514ee
MC
36static const struct timespec timeout = { 0,1000000 };
37static const struct timespec delay = { 0, 1000000 };
26a526fa 38
cc25c8b4
TR
39#ifndef KIND
40# define KIND PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP
d148ed25
UD
41#endif
42
cc25c8b4 43static pthread_rwlock_t lock;
26a526fa
UD
44
45
46static void *
47writer_thread (void *nr)
48{
49 struct timespec ts;
26a526fa
UD
50 int n;
51
26a526fa
UD
52 for (n = 0; n < WRITETRIES; ++n)
53 {
54 int e;
55 do
56 {
495514ee 57 xclock_gettime (CLOCK_REALTIME, &ts);
26a526fa 58
495514ee
MC
59 ts = timespec_add (ts, timeout);
60 ts = timespec_add (ts, timeout);
26a526fa
UD
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)
495514ee 66 FAIL_EXIT1 ("timedwrlock failed");
26a526fa
UD
67 }
68 while (e == ETIMEDOUT);
69
70 printf ("writer thread %ld succeeded\n", (long int) nr);
71
72 nanosleep (&delay, NULL);
73
74 if (pthread_rwlock_unlock (&lock) != 0)
495514ee 75 FAIL_EXIT1 ("unlock for writer failed");
26a526fa
UD
76
77 printf ("writer thread %ld released\n", (long int) nr);
78 }
79
80 return NULL;
81}
82
83
84static void *
85reader_thread (void *nr)
86{
87 struct timespec ts;
26a526fa
UD
88 int n;
89
26a526fa
UD
90 for (n = 0; n < READTRIES; ++n)
91 {
92 int e;
93 do
94 {
495514ee 95 xclock_gettime (CLOCK_REALTIME, &ts);
26a526fa 96
495514ee 97 ts = timespec_add (ts, timeout);
26a526fa
UD
98
99 printf ("reader thread %ld tries again\n", (long int) nr);
100
101 e = pthread_rwlock_timedrdlock (&lock, &ts);
102 if (e != 0 && e != ETIMEDOUT)
495514ee 103 FAIL_EXIT1 ("timedrdlock failed");
26a526fa
UD
104 }
105 while (e == ETIMEDOUT);
106
107 printf ("reader thread %ld succeeded\n", (long int) nr);
108
109 nanosleep (&delay, NULL);
110
111 if (pthread_rwlock_unlock (&lock) != 0)
495514ee 112 FAIL_EXIT1 ("unlock for reader failed");
26a526fa
UD
113
114 printf ("reader thread %ld released\n", (long int) nr);
115 }
116
117 return NULL;
118}
119
120
121static int
122do_test (void)
123{
124 pthread_t thwr[NWRITERS];
125 pthread_t thrd[NREADERS];
126 int n;
127 void *res;
cc25c8b4
TR
128 pthread_rwlockattr_t a;
129
130 if (pthread_rwlockattr_init (&a) != 0)
495514ee 131 FAIL_EXIT1 ("rwlockattr_t failed");
cc25c8b4
TR
132
133 if (pthread_rwlockattr_setkind_np (&a, KIND) != 0)
495514ee 134 FAIL_EXIT1 ("rwlockattr_setkind failed");
cc25c8b4
TR
135
136 if (pthread_rwlock_init (&lock, &a) != 0)
495514ee 137 FAIL_EXIT1 ("rwlock_init failed");
26a526fa
UD
138
139 /* Make standard error the same as standard output. */
140 dup2 (1, 2);
141
142 /* Make sure we see all message, even those on stdout. */
143 setvbuf (stdout, NULL, _IONBF, 0);
144
145 for (n = 0; n < NWRITERS; ++n)
146 if (pthread_create (&thwr[n], NULL, writer_thread,
147 (void *) (long int) n) != 0)
495514ee 148 FAIL_EXIT1 ("writer create failed");
26a526fa
UD
149
150 for (n = 0; n < NREADERS; ++n)
151 if (pthread_create (&thrd[n], NULL, reader_thread,
152 (void *) (long int) n) != 0)
495514ee 153 FAIL_EXIT1 ("reader create failed");
26a526fa
UD
154
155 /* Wait for all the threads. */
156 for (n = 0; n < NWRITERS; ++n)
157 if (pthread_join (thwr[n], &res) != 0)
495514ee 158 FAIL_EXIT1 ("writer join failed");
26a526fa
UD
159 for (n = 0; n < NREADERS; ++n)
160 if (pthread_join (thrd[n], &res) != 0)
495514ee 161 FAIL_EXIT1 ("reader join failed");
26a526fa
UD
162
163 return 0;
164}
165
26a526fa 166#define TIMEOUT 30
495514ee 167#include <support/test-driver.c>