author | iignatyev |
Fri, 14 Sep 2018 14:02:57 -0700 | |
changeset 51754 | 594919232b8f |
parent 47730 | c7b5b1ce8145 |
child 58134 | 51cd29502ea9 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
23010
6dadb192ad81
8029235: Update copyright year to match last edit in jdk8 jdk repository for 2013
lana
parents:
18160
diff
changeset
|
2 |
* Copyright (c) 2006, 2013, Oracle and/or its affiliates. All rights reserved. |
2 | 3 |
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. |
4 |
* |
|
5 |
* This code is free software; you can redistribute it and/or modify it |
|
6 |
* under the terms of the GNU General Public License version 2 only, as |
|
7 |
* published by the Free Software Foundation. |
|
8 |
* |
|
9 |
* This code is distributed in the hope that it will be useful, but WITHOUT |
|
10 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
11 |
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
12 |
* version 2 for more details (a copy is included in the LICENSE file that |
|
13 |
* accompanied this code). |
|
14 |
* |
|
15 |
* You should have received a copy of the GNU General Public License version |
|
16 |
* 2 along with this work; if not, write to the Free Software Foundation, |
|
17 |
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. |
|
18 |
* |
|
5506 | 19 |
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA |
20 |
* or visit www.oracle.com if you need additional information or have any |
|
21 |
* questions. |
|
2 | 22 |
*/ |
23 |
||
24 |
/* |
|
25 |
* @test |
|
26 |
* @bug 6503247 6574123 |
|
27 |
* @summary Test resilience to tryAcquire methods that throw |
|
28 |
* @author Martin Buchholz |
|
29 |
*/ |
|
30 |
||
38551
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
31 |
import java.util.concurrent.ThreadLocalRandom; |
34347 | 32 |
import java.util.concurrent.CyclicBarrier; |
33 |
import java.util.concurrent.ExecutorService; |
|
34 |
import java.util.concurrent.Executors; |
|
35 |
import java.util.concurrent.TimeUnit; |
|
36 |
import java.util.concurrent.locks.AbstractQueuedLongSynchronizer; |
|
37 |
import java.util.concurrent.locks.Condition; |
|
38 |
import java.util.concurrent.locks.Lock; |
|
2 | 39 |
|
40 |
/** |
|
41 |
* This uses a variant of the standard Mutex demo, except with a |
|
42 |
* tryAcquire method that randomly throws various Throwable |
|
43 |
* subclasses. |
|
44 |
*/ |
|
18160
da854405dc59
8016311: Update j.u.c. tests to avoid using Thread.stop(Throwable)
alanb
parents:
14342
diff
changeset
|
45 |
@SuppressWarnings("serial") |
2 | 46 |
public class FlakyMutex implements Lock { |
47 |
static class MyError extends Error {} |
|
48 |
static class MyException extends Exception {} |
|
49 |
static class MyRuntimeException extends RuntimeException {} |
|
50 |
||
51 |
static void checkThrowable(Throwable t) { |
|
52 |
check((t instanceof MyError) || |
|
53 |
(t instanceof MyException) || |
|
54 |
(t instanceof MyRuntimeException)); |
|
55 |
} |
|
56 |
||
57 |
static void realMain(String[] args) throws Throwable { |
|
58 |
final int nThreads = 3; |
|
38551
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
59 |
final int iterations = 10_000; |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
60 |
final CyclicBarrier startingGate = new CyclicBarrier(nThreads); |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
61 |
final FlakyMutex mutex = new FlakyMutex(); |
2 | 62 |
final ExecutorService es = Executors.newFixedThreadPool(nThreads); |
38551
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
63 |
final Runnable task = () -> { |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
64 |
try { |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
65 |
startingGate.await(); |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
66 |
for (int i = 0; i < iterations; i++) { |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
67 |
for (;;) { |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
68 |
try { mutex.lock(); break; } |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
69 |
catch (Throwable t) { checkThrowable(t); } |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
70 |
} |
2 | 71 |
|
38551
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
72 |
try { check(! mutex.tryLock()); } |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
73 |
catch (Throwable t) { checkThrowable(t); } |
2 | 74 |
|
38551
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
75 |
try { check(! mutex.tryLock(1, TimeUnit.MICROSECONDS)); } |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
76 |
catch (Throwable t) { checkThrowable(t); } |
2 | 77 |
|
38551
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
78 |
mutex.unlock(); |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
79 |
} |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
80 |
} catch (Throwable t) { unexpected(t); } |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
81 |
}; |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
82 |
|
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
83 |
for (int i = 0; i < nThreads; i++) |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
84 |
es.submit(task); |
2 | 85 |
es.shutdown(); |
38551
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
86 |
// Let test harness handle timeout |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
87 |
check(es.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS)); |
2 | 88 |
} |
89 |
||
90 |
private static class FlakySync extends AbstractQueuedLongSynchronizer { |
|
91 |
private static final long serialVersionUID = -1L; |
|
92 |
||
93 |
public boolean isHeldExclusively() { return getState() == 1; } |
|
94 |
||
95 |
public boolean tryAcquire(long acquires) { |
|
96 |
// Sneak in some tests for queue state |
|
97 |
if (hasQueuedPredecessors()) |
|
98 |
check(getFirstQueuedThread() != Thread.currentThread()); |
|
99 |
if (getFirstQueuedThread() == Thread.currentThread()) { |
|
100 |
check(hasQueuedThreads()); |
|
101 |
check(!hasQueuedPredecessors()); |
|
102 |
} else { |
|
103 |
// Might be true, but only transiently |
|
104 |
do {} while (hasQueuedPredecessors() != hasQueuedThreads()); |
|
105 |
} |
|
106 |
||
38551
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
107 |
switch (ThreadLocalRandom.current().nextInt(10)) { |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
108 |
case 0: throw new MyError(); |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
109 |
case 1: throw new MyRuntimeException(); |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
110 |
case 2: FlakyMutex.<RuntimeException>uncheckedThrow(new MyException()); |
47730
c7b5b1ce8145
8189764: Miscellaneous changes imported from jsr166 CVS 2017-11
dl
parents:
47216
diff
changeset
|
111 |
// fall through ... NOT! |
38551
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
112 |
default: return compareAndSetState(0, 1); |
82c48058acc2
8153768: Miscellaneous changes imported from jsr166 CVS 2016-05
dl
parents:
36233
diff
changeset
|
113 |
} |
2 | 114 |
} |
115 |
||
116 |
public boolean tryRelease(long releases) { |
|
117 |
setState(0); |
|
118 |
return true; |
|
119 |
} |
|
120 |
||
121 |
Condition newCondition() { return new ConditionObject(); } |
|
122 |
} |
|
123 |
||
124 |
private final FlakySync sync = new FlakySync(); |
|
125 |
public void lock() { sync.acquire(1); } |
|
126 |
public boolean tryLock() { return sync.tryAcquire(1); } |
|
127 |
public void lockInterruptibly() throws InterruptedException { |
|
128 |
sync.acquireInterruptibly(1); |
|
129 |
} |
|
130 |
public boolean tryLock(long timeout, TimeUnit unit) throws InterruptedException { |
|
131 |
return sync.tryAcquireNanos(1, unit.toNanos(timeout)); |
|
132 |
} |
|
133 |
public void unlock() { sync.release(1); } |
|
134 |
public Condition newCondition() { return sync.newCondition(); } |
|
135 |
public boolean isLocked() { return sync.isHeldExclusively(); } |
|
136 |
public boolean hasQueuedThreads() { return sync.hasQueuedThreads(); } |
|
137 |
||
138 |
//--------------------- Infrastructure --------------------------- |
|
139 |
static volatile int passed = 0, failed = 0; |
|
140 |
static void pass() {passed++;} |
|
141 |
static void fail() {failed++; Thread.dumpStack();} |
|
142 |
static void fail(String msg) {System.out.println(msg); fail();} |
|
143 |
static void unexpected(Throwable t) {failed++; t.printStackTrace();} |
|
144 |
static void check(boolean cond) {if (cond) pass(); else fail();} |
|
145 |
static void equal(Object x, Object y) { |
|
146 |
if (x == null ? y == null : x.equals(y)) pass(); |
|
147 |
else fail(x + " not equal to " + y);} |
|
148 |
public static void main(String[] args) throws Throwable { |
|
149 |
try {realMain(args);} catch (Throwable t) {unexpected(t);} |
|
150 |
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed); |
|
151 |
if (failed > 0) throw new AssertionError("Some tests failed");} |
|
42322
c3474fef4fe4
8166646: Miscellaneous changes imported from jsr166 CVS 2016-10
dl
parents:
38551
diff
changeset
|
152 |
@SuppressWarnings("unchecked") |
c3474fef4fe4
8166646: Miscellaneous changes imported from jsr166 CVS 2016-10
dl
parents:
38551
diff
changeset
|
153 |
static <T extends Throwable> void uncheckedThrow(Throwable t) throws T { |
18160
da854405dc59
8016311: Update j.u.c. tests to avoid using Thread.stop(Throwable)
alanb
parents:
14342
diff
changeset
|
154 |
throw (T)t; // rely on vacuous cast |
da854405dc59
8016311: Update j.u.c. tests to avoid using Thread.stop(Throwable)
alanb
parents:
14342
diff
changeset
|
155 |
} |
2 | 156 |
} |