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