summaryrefslogtreecommitdiffstats
path: root/jsr166-tests/src/test/java/jsr166/LockSupportTest.java
diff options
context:
space:
mode:
authorCalin Juravle <calin@google.com>2013-08-01 17:26:00 +0100
committerCalin Juravle <calin@google.com>2013-08-14 19:15:59 +0100
commit8f0d92bba199d906c70a5e40d7f3516c1a424117 (patch)
tree3762e8e4275ac7535ce011915fb0e0f7a343deea /jsr166-tests/src/test/java/jsr166/LockSupportTest.java
parent75a06e56a4cc4599946e21422513e4bafa759509 (diff)
downloadlibcore-8f0d92bba199d906c70a5e40d7f3516c1a424117.zip
libcore-8f0d92bba199d906c70a5e40d7f3516c1a424117.tar.gz
libcore-8f0d92bba199d906c70a5e40d7f3516c1a424117.tar.bz2
Added jsr166 tck tests as part of the libcore testsuite.
Change-Id: I6094d734f818fa043f2b277cf2b4ec7fec68e26e
Diffstat (limited to 'jsr166-tests/src/test/java/jsr166/LockSupportTest.java')
-rw-r--r--jsr166-tests/src/test/java/jsr166/LockSupportTest.java362
1 files changed, 362 insertions, 0 deletions
diff --git a/jsr166-tests/src/test/java/jsr166/LockSupportTest.java b/jsr166-tests/src/test/java/jsr166/LockSupportTest.java
new file mode 100644
index 0000000..051de35
--- /dev/null
+++ b/jsr166-tests/src/test/java/jsr166/LockSupportTest.java
@@ -0,0 +1,362 @@
+/*
+ * Written by Doug Lea and Martin Buchholz with assistance from
+ * members of JCP JSR-166 Expert Group and released to the public
+ * domain, as explained at
+ * http://creativecommons.org/publicdomain/zero/1.0/
+ * Other contributors include Andrew Wright, Jeffrey Hayes,
+ * Pat Fisher, Mike Judd.
+ */
+
+package jsr166;
+
+import junit.framework.*;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.LockSupport;
+import static java.util.concurrent.TimeUnit.MILLISECONDS;
+
+public class LockSupportTest extends JSR166TestCase {
+
+ /**
+ * Returns the blocker object used by tests in this file.
+ * Any old object will do; we'll return a convenient one.
+ */
+ static Object theBlocker() {
+ return LockSupportTest.class;
+ }
+
+ enum ParkMethod {
+ park() {
+ void park() {
+ LockSupport.park();
+ }
+ void park(long millis) {
+ throw new UnsupportedOperationException();
+ }
+ },
+ parkUntil() {
+ void park(long millis) {
+ LockSupport.parkUntil(deadline(millis));
+ }
+ },
+ parkNanos() {
+ void park(long millis) {
+ LockSupport.parkNanos(MILLISECONDS.toNanos(millis));
+ }
+ },
+ parkBlocker() {
+ void park() {
+ LockSupport.park(theBlocker());
+ }
+ void park(long millis) {
+ throw new UnsupportedOperationException();
+ }
+ },
+ parkUntilBlocker() {
+ void park(long millis) {
+ LockSupport.parkUntil(theBlocker(), deadline(millis));
+ }
+ },
+ parkNanosBlocker() {
+ void park(long millis) {
+ LockSupport.parkNanos(theBlocker(),
+ MILLISECONDS.toNanos(millis));
+ }
+ };
+
+ void park() { park(2 * LONG_DELAY_MS); }
+ abstract void park(long millis);
+
+ /** Returns a deadline to use with parkUntil. */
+ long deadline(long millis) {
+ // beware of rounding
+ return System.currentTimeMillis() + millis + 1;
+ }
+ }
+
+ /**
+ * park is released by subsequent unpark
+ */
+ public void testParkBeforeUnpark_park() {
+ testParkBeforeUnpark(ParkMethod.park);
+ }
+ public void testParkBeforeUnpark_parkNanos() {
+ testParkBeforeUnpark(ParkMethod.parkNanos);
+ }
+ public void testParkBeforeUnpark_parkUntil() {
+ testParkBeforeUnpark(ParkMethod.parkUntil);
+ }
+ public void testParkBeforeUnpark_parkBlocker() {
+ testParkBeforeUnpark(ParkMethod.parkBlocker);
+ }
+ public void testParkBeforeUnpark_parkNanosBlocker() {
+ testParkBeforeUnpark(ParkMethod.parkNanosBlocker);
+ }
+ public void testParkBeforeUnpark_parkUntilBlocker() {
+ testParkBeforeUnpark(ParkMethod.parkUntilBlocker);
+ }
+ public void testParkBeforeUnpark(final ParkMethod parkMethod) {
+ final CountDownLatch pleaseUnpark = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ pleaseUnpark.countDown();
+ parkMethod.park();
+ }});
+
+ await(pleaseUnpark);
+ LockSupport.unpark(t);
+ awaitTermination(t);
+ }
+
+ /**
+ * park is released by preceding unpark
+ */
+ public void testParkAfterUnpark_park() {
+ testParkAfterUnpark(ParkMethod.park);
+ }
+ public void testParkAfterUnpark_parkNanos() {
+ testParkAfterUnpark(ParkMethod.parkNanos);
+ }
+ public void testParkAfterUnpark_parkUntil() {
+ testParkAfterUnpark(ParkMethod.parkUntil);
+ }
+ public void testParkAfterUnpark_parkBlocker() {
+ testParkAfterUnpark(ParkMethod.parkBlocker);
+ }
+ public void testParkAfterUnpark_parkNanosBlocker() {
+ testParkAfterUnpark(ParkMethod.parkNanosBlocker);
+ }
+ public void testParkAfterUnpark_parkUntilBlocker() {
+ testParkAfterUnpark(ParkMethod.parkUntilBlocker);
+ }
+ public void testParkAfterUnpark(final ParkMethod parkMethod) {
+ final CountDownLatch pleaseUnpark = new CountDownLatch(1);
+ final AtomicBoolean pleasePark = new AtomicBoolean(false);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ pleaseUnpark.countDown();
+ while (!pleasePark.get())
+ Thread.yield();
+ parkMethod.park();
+ }});
+
+ await(pleaseUnpark);
+ LockSupport.unpark(t);
+ pleasePark.set(true);
+ awaitTermination(t);
+ }
+
+ /**
+ * park is released by subsequent interrupt
+ */
+ public void testParkBeforeInterrupt_park() {
+ testParkBeforeInterrupt(ParkMethod.park);
+ }
+ public void testParkBeforeInterrupt_parkNanos() {
+ testParkBeforeInterrupt(ParkMethod.parkNanos);
+ }
+ public void testParkBeforeInterrupt_parkUntil() {
+ testParkBeforeInterrupt(ParkMethod.parkUntil);
+ }
+ public void testParkBeforeInterrupt_parkBlocker() {
+ testParkBeforeInterrupt(ParkMethod.parkBlocker);
+ }
+ public void testParkBeforeInterrupt_parkNanosBlocker() {
+ testParkBeforeInterrupt(ParkMethod.parkNanosBlocker);
+ }
+ public void testParkBeforeInterrupt_parkUntilBlocker() {
+ testParkBeforeInterrupt(ParkMethod.parkUntilBlocker);
+ }
+ public void testParkBeforeInterrupt(final ParkMethod parkMethod) {
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ pleaseInterrupt.countDown();
+ do {
+ parkMethod.park();
+ // park may return spuriously
+ } while (! Thread.currentThread().isInterrupted());
+ }});
+
+ await(pleaseInterrupt);
+ assertThreadStaysAlive(t);
+ t.interrupt();
+ awaitTermination(t);
+ }
+
+ /**
+ * park is released by preceding interrupt
+ */
+ public void testParkAfterInterrupt_park() {
+ testParkAfterInterrupt(ParkMethod.park);
+ }
+ public void testParkAfterInterrupt_parkNanos() {
+ testParkAfterInterrupt(ParkMethod.parkNanos);
+ }
+ public void testParkAfterInterrupt_parkUntil() {
+ testParkAfterInterrupt(ParkMethod.parkUntil);
+ }
+ public void testParkAfterInterrupt_parkBlocker() {
+ testParkAfterInterrupt(ParkMethod.parkBlocker);
+ }
+ public void testParkAfterInterrupt_parkNanosBlocker() {
+ testParkAfterInterrupt(ParkMethod.parkNanosBlocker);
+ }
+ public void testParkAfterInterrupt_parkUntilBlocker() {
+ testParkAfterInterrupt(ParkMethod.parkUntilBlocker);
+ }
+ public void testParkAfterInterrupt(final ParkMethod parkMethod) {
+ final CountDownLatch pleaseInterrupt = new CountDownLatch(1);
+ final AtomicBoolean pleasePark = new AtomicBoolean(false);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() throws Exception {
+ pleaseInterrupt.countDown();
+ while (!pleasePark.get())
+ Thread.yield();
+ assertTrue(Thread.currentThread().isInterrupted());
+ parkMethod.park();
+ assertTrue(Thread.currentThread().isInterrupted());
+ }});
+
+ await(pleaseInterrupt);
+ t.interrupt();
+ pleasePark.set(true);
+ awaitTermination(t);
+ }
+
+ /**
+ * timed park times out if not unparked
+ */
+ public void testParkTimesOut_parkNanos() {
+ testParkTimesOut(ParkMethod.parkNanos);
+ }
+ public void testParkTimesOut_parkUntil() {
+ testParkTimesOut(ParkMethod.parkUntil);
+ }
+ public void testParkTimesOut_parkNanosBlocker() {
+ testParkTimesOut(ParkMethod.parkNanosBlocker);
+ }
+ public void testParkTimesOut_parkUntilBlocker() {
+ testParkTimesOut(ParkMethod.parkUntilBlocker);
+ }
+ public void testParkTimesOut(final ParkMethod parkMethod) {
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ for (;;) {
+ long startTime = System.nanoTime();
+ parkMethod.park(timeoutMillis());
+ // park may return spuriously
+ if (millisElapsedSince(startTime) >= timeoutMillis())
+ return;
+ }
+ }});
+
+ awaitTermination(t);
+ }
+
+ /**
+ * getBlocker(null) throws NullPointerException
+ */
+ public void testGetBlockerNull() {
+ try {
+ LockSupport.getBlocker(null);
+ shouldThrow();
+ } catch (NullPointerException success) {}
+ }
+
+ /**
+ * getBlocker returns the blocker object passed to park
+ */
+ public void testGetBlocker_parkBlocker() {
+ testGetBlocker(ParkMethod.parkBlocker);
+ }
+ public void testGetBlocker_parkNanosBlocker() {
+ testGetBlocker(ParkMethod.parkNanosBlocker);
+ }
+ public void testGetBlocker_parkUntilBlocker() {
+ testGetBlocker(ParkMethod.parkUntilBlocker);
+ }
+ public void testGetBlocker(final ParkMethod parkMethod) {
+ final CountDownLatch started = new CountDownLatch(1);
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ Thread t = Thread.currentThread();
+ started.countDown();
+ do {
+ assertNull(LockSupport.getBlocker(t));
+ parkMethod.park();
+ assertNull(LockSupport.getBlocker(t));
+ // park may return spuriously
+ } while (! Thread.currentThread().isInterrupted());
+ }});
+
+ long startTime = System.nanoTime();
+ await(started);
+ for (;;) {
+ Object x = LockSupport.getBlocker(t);
+ if (x == theBlocker()) { // success
+ t.interrupt();
+ awaitTermination(t);
+ assertNull(LockSupport.getBlocker(t));
+ return;
+ } else {
+ assertNull(x); // ok
+ if (millisElapsedSince(startTime) > LONG_DELAY_MS)
+ fail("timed out");
+ Thread.yield();
+ }
+ }
+ }
+
+ /**
+ * timed park(0) returns immediately.
+ *
+ * Requires hotspot fix for:
+ * 6763959 java.util.concurrent.locks.LockSupport.parkUntil(0) blocks forever
+ * which is in jdk7-b118 and 6u25.
+ */
+ public void testPark0_parkNanos() {
+ testPark0(ParkMethod.parkNanos);
+ }
+ public void testPark0_parkUntil() {
+ testPark0(ParkMethod.parkUntil);
+ }
+ public void testPark0_parkNanosBlocker() {
+ testPark0(ParkMethod.parkNanosBlocker);
+ }
+ public void testPark0_parkUntilBlocker() {
+ testPark0(ParkMethod.parkUntilBlocker);
+ }
+ public void testPark0(final ParkMethod parkMethod) {
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ parkMethod.park(0L);
+ }});
+
+ awaitTermination(t);
+ }
+
+ /**
+ * timed park(Long.MIN_VALUE) returns immediately.
+ */
+ public void testParkNeg_parkNanos() {
+ testParkNeg(ParkMethod.parkNanos);
+ }
+ public void testParkNeg_parkUntil() {
+ testParkNeg(ParkMethod.parkUntil);
+ }
+ public void testParkNeg_parkNanosBlocker() {
+ testParkNeg(ParkMethod.parkNanosBlocker);
+ }
+ public void testParkNeg_parkUntilBlocker() {
+ testParkNeg(ParkMethod.parkUntilBlocker);
+ }
+ public void testParkNeg(final ParkMethod parkMethod) {
+ Thread t = newStartedThread(new CheckedRunnable() {
+ public void realRun() {
+ parkMethod.park(Long.MIN_VALUE);
+ }});
+
+ awaitTermination(t);
+ }
+}