ViewVC Help
View File | Revision Log | Show Annotations | Download File | Root Listing
root/jsr166/jsr166/src/test/loops/CheckedLockLoops.java
Revision: 1.12
Committed: Sat Dec 31 18:54:28 2016 UTC (7 years, 4 months ago) by jsr166
Branch: MAIN
Changes since 1.11: +8 -3 lines
Log Message:
organize imports

File Contents

# Content
1 /*
2 * Written by Doug Lea with assistance from members of JCP JSR-166
3 * Expert Group and released to the public domain, as explained at
4 * http://creativecommons.org/publicdomain/zero/1.0/
5 */
6 /*
7 * @test
8 * @summary basic safety and liveness of ReentrantLocks, and other locks based on them
9 */
10
11 import java.util.concurrent.Callable;
12 import java.util.concurrent.CyclicBarrier;
13 import java.util.concurrent.ExecutorService;
14 import java.util.concurrent.Executors;
15 import java.util.concurrent.Semaphore;
16 import java.util.concurrent.locks.Lock;
17 import java.util.concurrent.locks.ReentrantLock;
18 import java.util.concurrent.locks.ReentrantReadWriteLock;
19
20 public final class CheckedLockLoops {
21 static final ExecutorService pool = Executors.newCachedThreadPool();
22 static final LoopHelpers.SimpleRandom rng = new LoopHelpers.SimpleRandom();
23 static boolean print = false;
24 static boolean doBuiltin = true;
25
26 public static void main(String[] args) throws Exception {
27 int maxThreads = 100;
28 int iters = 2000000;
29 if (args.length > 0)
30 maxThreads = Integer.parseInt(args[0]);
31 rng.setSeed(3122688L);
32 warmup(iters);
33 runTest(maxThreads, iters);
34 pool.shutdown();
35 }
36
37 static void runTest(int maxThreads, int iters) throws Exception {
38 print = true;
39 for (int k = 1, i = 1; i <= maxThreads;) {
40 System.out.println("Threads:" + i);
41 oneTest(i, iters / i);
42 if (i == k) {
43 k = i << 1;
44 i = i + (i >>> 1);
45 }
46 else
47 i = k;
48 }
49 }
50
51 static void warmup(int iters) throws Exception {
52 print = false;
53 System.out.println("Warmup...");
54 oneTest(1, iters);
55 oneTest(2, iters / 2);
56 }
57
58 static void oneTest(int nthreads, int iters) throws Exception {
59 int fairIters = (nthreads <= 1) ? iters : iters/20;
60 int v = rng.next();
61
62 if (print)
63 System.out.print("NoLock (1 thread) ");
64 new NoLockLoop().test(v, 1, iters * nthreads);
65 Thread.sleep(10);
66
67 if (print)
68 System.out.print("ReentrantLock ");
69 new ReentrantLockLoop().test(v, nthreads, iters);
70 Thread.sleep(10);
71
72 if (print)
73 System.out.print("FairReentrantLock ");
74 new FairReentrantLockLoop().test(v, nthreads, fairIters);
75 Thread.sleep(10);
76
77 if (doBuiltin) {
78 if (print)
79 System.out.print("builtin lock ");
80 new BuiltinLockLoop().test(v, nthreads, fairIters);
81 Thread.sleep(10);
82 }
83
84 if (print)
85 System.out.print("Mutex ");
86 new MutexLoop().test(v, nthreads, iters);
87 Thread.sleep(10);
88
89 if (print)
90 System.out.print("LongMutex ");
91 new LongMutexLoop().test(v, nthreads, iters);
92 Thread.sleep(10);
93
94 if (print)
95 System.out.print("Semaphore ");
96 new SemaphoreLoop().test(v, nthreads, iters);
97 Thread.sleep(10);
98
99 if (print)
100 System.out.print("FairSemaphore ");
101 new FairSemaphoreLoop().test(v, nthreads, fairIters);
102 Thread.sleep(10);
103
104 if (print)
105 System.out.print("ReentrantWriteLock ");
106 new ReentrantWriteLockLoop().test(v, nthreads, iters);
107 Thread.sleep(10);
108
109 if (print)
110 System.out.print("FairRWriteLock ");
111 new FairReentrantWriteLockLoop().test(v, nthreads, fairIters);
112 Thread.sleep(10);
113
114 if (print)
115 System.out.print("ReentrantReadWriteLock");
116 new ReentrantReadWriteLockLoop().test(v, nthreads, iters);
117 Thread.sleep(10);
118
119 if (print)
120 System.out.print("FairRReadWriteLock ");
121 new FairReentrantReadWriteLockLoop().test(v, nthreads, fairIters);
122 Thread.sleep(10);
123 }
124
125 abstract static class LockLoop implements Runnable {
126 int value;
127 int checkValue;
128 int iters;
129 volatile int result;
130 volatile int failures;
131 final LoopHelpers.BarrierTimer timer = new LoopHelpers.BarrierTimer();
132 CyclicBarrier barrier;
133
134 final int setValue(int v) {
135 checkValue = v ^ 0x55555555;
136 value = v;
137 return v;
138 }
139
140 final int getValue() {
141 int v = value;
142 if (checkValue != ~(v ^ 0xAAAAAAAA))
143 ++failures;
144 return v;
145 }
146
147 final void test(int initialValue, int nthreads, int iters) throws Exception {
148 setValue(initialValue);
149 this.iters = iters;
150 barrier = new CyclicBarrier(nthreads+1, timer);
151 for (int i = 0; i < nthreads; ++i)
152 pool.execute(this);
153 barrier.await();
154 barrier.await();
155 long time = timer.getTime();
156 if (print) {
157 long tpi = time / (iters * nthreads);
158 System.out.print("\t" + LoopHelpers.rightJustify(tpi) + " ns per update");
159 System.out.println();
160 }
161
162 if (result == 0) // avoid overoptimization
163 System.out.println("useless result: " + result);
164 if (failures != 0)
165 throw new Error("lock protection failure");
166 }
167
168 abstract int loop(int n);
169 public final void run() {
170 try {
171 barrier.await();
172 result += loop(iters);
173 barrier.await();
174 }
175 catch (Exception ie) {
176 return;
177 }
178 }
179
180 }
181
182 private static class NoLockLoop extends LockLoop {
183 private volatile int readBarrier;
184 final int loop(int n) {
185 int sum = 0;
186 int x = 0;
187 while (n-- > 0) {
188 int r1 = readBarrier;
189 x = setValue(LoopHelpers.compute1(getValue()));
190 int r2 = readBarrier;
191 if (r1 == r2 && x == r1)
192 ++readBarrier;
193 sum += LoopHelpers.compute2(x);
194 }
195 return sum;
196 }
197 }
198
199 private static class BuiltinLockLoop extends LockLoop {
200 final int loop(int n) {
201 int sum = 0;
202 int x = 0;
203 while (n-- > 0) {
204 synchronized (this) {
205 x = setValue(LoopHelpers.compute1(getValue()));
206 }
207 sum += LoopHelpers.compute2(x);
208 }
209 return sum;
210 }
211 }
212
213 private static class ReentrantLockLoop extends LockLoop {
214 private final ReentrantLock lock = new ReentrantLock();
215 final int loop(int n) {
216 final ReentrantLock lock = this.lock;
217 int sum = 0;
218 int x = 0;
219 while (n-- > 0) {
220 lock.lock();
221 try {
222 x = setValue(LoopHelpers.compute1(getValue()));
223 }
224 finally {
225 lock.unlock();
226 }
227 sum += LoopHelpers.compute2(x);
228 }
229 return sum;
230 }
231 }
232
233 private static class MutexLoop extends LockLoop {
234 private final Mutex lock = new Mutex();
235 final int loop(int n) {
236 final Mutex lock = this.lock;
237 int sum = 0;
238 int x = 0;
239 while (n-- > 0) {
240 lock.lock();
241 try {
242 x = setValue(LoopHelpers.compute1(getValue()));
243 }
244 finally {
245 lock.unlock();
246 }
247 sum += LoopHelpers.compute2(x);
248 }
249 return sum;
250 }
251 }
252
253 private static class LongMutexLoop extends LockLoop {
254 private final LongMutex lock = new LongMutex();
255 final int loop(int n) {
256 final LongMutex lock = this.lock;
257 int sum = 0;
258 int x = 0;
259 while (n-- > 0) {
260 lock.lock();
261 try {
262 x = setValue(LoopHelpers.compute1(getValue()));
263 }
264 finally {
265 lock.unlock();
266 }
267 sum += LoopHelpers.compute2(x);
268 }
269 return sum;
270 }
271 }
272
273 private static class FairReentrantLockLoop extends LockLoop {
274 private final ReentrantLock lock = new ReentrantLock(true);
275 final int loop(int n) {
276 final ReentrantLock lock = this.lock;
277 int sum = 0;
278 int x = 0;
279 while (n-- > 0) {
280 lock.lock();
281 try {
282 x = setValue(LoopHelpers.compute1(getValue()));
283 }
284 finally {
285 lock.unlock();
286 }
287 sum += LoopHelpers.compute2(x);
288 }
289 return sum;
290 }
291 }
292
293 private static class ReentrantWriteLockLoop extends LockLoop {
294 private final Lock lock = new ReentrantReadWriteLock().writeLock();
295 final int loop(int n) {
296 final Lock lock = this.lock;
297 int sum = 0;
298 int x = 0;
299 while (n-- > 0) {
300 lock.lock();
301 try {
302 x = setValue(LoopHelpers.compute1(getValue()));
303 }
304 finally {
305 lock.unlock();
306 }
307 sum += LoopHelpers.compute2(x);
308 }
309 return sum;
310 }
311 }
312
313 private static class FairReentrantWriteLockLoop extends LockLoop {
314 final Lock lock = new ReentrantReadWriteLock(true).writeLock();
315 final int loop(int n) {
316 final Lock lock = this.lock;
317 int sum = 0;
318 int x = 0;
319 while (n-- > 0) {
320 lock.lock();
321 try {
322 x = setValue(LoopHelpers.compute1(getValue()));
323 }
324 finally {
325 lock.unlock();
326 }
327 sum += LoopHelpers.compute2(x);
328 }
329 return sum;
330 }
331 }
332
333 private static class SemaphoreLoop extends LockLoop {
334 private final Semaphore sem = new Semaphore(1, false);
335 final int loop(int n) {
336 final Semaphore sem = this.sem;
337 int sum = 0;
338 int x = 0;
339 while (n-- > 0) {
340 sem.acquireUninterruptibly();
341 try {
342 x = setValue(LoopHelpers.compute1(getValue()));
343 }
344 finally {
345 sem.release();
346 }
347 sum += LoopHelpers.compute2(x);
348 }
349 return sum;
350 }
351 }
352 private static class FairSemaphoreLoop extends LockLoop {
353 private final Semaphore sem = new Semaphore(1, true);
354 final int loop(int n) {
355 final Semaphore sem = this.sem;
356 int sum = 0;
357 int x = 0;
358 while (n-- > 0) {
359 sem.acquireUninterruptibly();
360 try {
361 x = setValue(LoopHelpers.compute1(getValue()));
362 }
363 finally {
364 sem.release();
365 }
366 sum += LoopHelpers.compute2(x);
367 }
368 return sum;
369 }
370 }
371
372 private static class ReentrantReadWriteLockLoop extends LockLoop {
373 private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
374 final int loop(int n) {
375 final Lock rlock = lock.readLock();
376 final Lock wlock = lock.writeLock();
377 int sum = 0;
378 int x = 0;
379 while (n-- > 0) {
380 if ((n & 16) != 0) {
381 rlock.lock();
382 try {
383 x = LoopHelpers.compute1(getValue());
384 x = LoopHelpers.compute2(x);
385 }
386 finally {
387 rlock.unlock();
388 }
389 }
390 else {
391 wlock.lock();
392 try {
393 setValue(x);
394 }
395 finally {
396 wlock.unlock();
397 }
398 sum += LoopHelpers.compute2(x);
399 }
400 }
401 return sum;
402 }
403
404 }
405
406 private static class FairReentrantReadWriteLockLoop extends LockLoop {
407 private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
408 final int loop(int n) {
409 final Lock rlock = lock.readLock();
410 final Lock wlock = lock.writeLock();
411 int sum = 0;
412 int x = 0;
413 while (n-- > 0) {
414 if ((n & 16) != 0) {
415 rlock.lock();
416 try {
417 x = LoopHelpers.compute1(getValue());
418 x = LoopHelpers.compute2(x);
419 }
420 finally {
421 rlock.unlock();
422 }
423 }
424 else {
425 wlock.lock();
426 try {
427 setValue(x);
428 }
429 finally {
430 wlock.unlock();
431 }
432 sum += LoopHelpers.compute2(x);
433 }
434 }
435 return sum;
436 }
437
438 }
439 }