This source file includes following definitions.
- random_account
- check_accounts
- rwlock_mutator_thread
- rwlock_checker_thread
- test_rwlock
- main
- main
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 #include <config.h>
20
21 #if USE_ISOC_THREADS || USE_POSIX_THREADS || USE_ISOC_AND_POSIX_THREADS || USE_WINDOWS_THREADS
22
23
24
25
26 #define ENABLE_LOCKING 1
27
28
29
30 #define EXPLICIT_YIELD 1
31
32
33 #define ENABLE_DEBUGGING 0
34
35
36 #define THREAD_COUNT 10
37
38
39
40
41 #define REPEAT_COUNT 50000
42
43 #include <pthread.h>
44 #include <stdint.h>
45 #include <stdio.h>
46 #include <stdlib.h>
47 #include <string.h>
48
49 #if EXPLICIT_YIELD
50 # include <sched.h>
51 #endif
52
53 #if HAVE_DECL_ALARM
54 # include <signal.h>
55 # include <unistd.h>
56 #endif
57
58 #include "macros.h"
59 #include "atomic-int-posix.h"
60
61 #if ENABLE_DEBUGGING
62 # define dbgprintf printf
63 #else
64 # define dbgprintf if (0) printf
65 #endif
66
67 #if EXPLICIT_YIELD
68 # define yield() sched_yield ()
69 #else
70 # define yield()
71 #endif
72
73
74 #if defined __MVS__
75
76
77
78 # define pthread_self_pointer() (*((void **) pthread_self ().__))
79 #else
80 # define pthread_self_pointer() ((void *) (uintptr_t) pthread_self ())
81 #endif
82
83 #define ACCOUNT_COUNT 4
84
85 static int account[ACCOUNT_COUNT];
86
87 static int
88 random_account (void)
89 {
90 return ((unsigned int) rand () >> 3) % ACCOUNT_COUNT;
91 }
92
93 static void
94 check_accounts (void)
95 {
96 int i, sum;
97
98 sum = 0;
99 for (i = 0; i < ACCOUNT_COUNT; i++)
100 sum += account[i];
101 if (sum != ACCOUNT_COUNT * 1000)
102 abort ();
103 }
104
105
106
107
108
109
110
111
112 static pthread_rwlock_t my_rwlock = PTHREAD_RWLOCK_INITIALIZER;
113
114 static void *
115 rwlock_mutator_thread (void *arg)
116 {
117 int repeat;
118
119 for (repeat = REPEAT_COUNT; repeat > 0; repeat--)
120 {
121 int i1, i2, value;
122
123 dbgprintf ("Mutator %p before wrlock\n", pthread_self_pointer ());
124 ASSERT (pthread_rwlock_wrlock (&my_rwlock) == 0);
125 dbgprintf ("Mutator %p after wrlock\n", pthread_self_pointer ());
126
127 i1 = random_account ();
128 i2 = random_account ();
129 value = ((unsigned int) rand () >> 3) % 10;
130 account[i1] += value;
131 account[i2] -= value;
132
133 dbgprintf ("Mutator %p before unlock\n", pthread_self_pointer ());
134 ASSERT (pthread_rwlock_unlock (&my_rwlock) == 0);
135 dbgprintf ("Mutator %p after unlock\n", pthread_self_pointer ());
136
137 yield ();
138 }
139
140 dbgprintf ("Mutator %p dying.\n", pthread_self_pointer ());
141 return NULL;
142 }
143
144 static struct atomic_int rwlock_checker_done;
145
146 static void *
147 rwlock_checker_thread (void *arg)
148 {
149 while (get_atomic_int_value (&rwlock_checker_done) == 0)
150 {
151 dbgprintf ("Checker %p before check rdlock\n", pthread_self_pointer ());
152 ASSERT (pthread_rwlock_rdlock (&my_rwlock) == 0);
153 check_accounts ();
154 ASSERT (pthread_rwlock_unlock (&my_rwlock) == 0);
155 dbgprintf ("Checker %p after check unlock\n", pthread_self_pointer ());
156
157 yield ();
158 }
159
160 dbgprintf ("Checker %p dying.\n", pthread_self_pointer ());
161 return NULL;
162 }
163
164 static void
165 test_rwlock (void)
166 {
167 int i;
168 pthread_t checkerthreads[THREAD_COUNT];
169 pthread_t threads[THREAD_COUNT];
170
171
172 for (i = 0; i < ACCOUNT_COUNT; i++)
173 account[i] = 1000;
174 init_atomic_int (&rwlock_checker_done);
175 set_atomic_int_value (&rwlock_checker_done, 0);
176
177
178 for (i = 0; i < THREAD_COUNT; i++)
179 ASSERT (pthread_create (&checkerthreads[i], NULL,
180 rwlock_checker_thread, NULL)
181 == 0);
182 for (i = 0; i < THREAD_COUNT; i++)
183 ASSERT (pthread_create (&threads[i], NULL, rwlock_mutator_thread, NULL)
184 == 0);
185
186
187 for (i = 0; i < THREAD_COUNT; i++)
188 ASSERT (pthread_join (threads[i], NULL) == 0);
189 set_atomic_int_value (&rwlock_checker_done, 1);
190 for (i = 0; i < THREAD_COUNT; i++)
191 ASSERT (pthread_join (checkerthreads[i], NULL) == 0);
192 check_accounts ();
193 }
194
195
196
197
198 int
199 main ()
200 {
201 #if HAVE_DECL_ALARM
202
203
204 int alarm_value = 600;
205 signal (SIGALRM, SIG_DFL);
206 alarm (alarm_value);
207 #endif
208
209 printf ("Starting test_rwlock ..."); fflush (stdout);
210 test_rwlock ();
211 printf (" OK\n"); fflush (stdout);
212
213 return 0;
214 }
215
216 #else
217
218
219
220 #include <stdio.h>
221
222 int
223 main ()
224 {
225 fputs ("Skipping test: multithreading not enabled\n", stderr);
226 return 77;
227 }
228
229 #endif