Skip to content

Commit

Permalink
JDK-8141031: j.u.c.Phaser Basic test fails intermittently
Browse files Browse the repository at this point in the history
  • Loading branch information
retrostreams committed Nov 18, 2015
1 parent f42c779 commit f48168a
Showing 1 changed file with 84 additions and 30 deletions.
114 changes: 84 additions & 30 deletions src/tests/java/org/openjdk/other/tests/phaser/Basic.java
Expand Up @@ -34,22 +34,28 @@
/*
* @test
* @bug 6445158
* @key intermittent
* @summary Basic tests for Phaser
* @author Chris Hegarty
*/
package org.openjdk.other.tests.phaser;

import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.SECONDS;

import java.lang.management.ManagementFactory;
import java.lang.management.ThreadInfo;
import java.lang.management.ThreadMXBean;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import java.util.concurrent.atomic.AtomicInteger;

import org.testng.annotations.Test;

import static java.util.concurrent.TimeUnit.*;
import java8.util.concurrent.Phaser;

import org.testng.annotations.Test;

public class Basic {

private static void checkTerminated(final Phaser phaser) {
Expand Down Expand Up @@ -89,25 +95,30 @@ private static void checkResult(Arriver a, Class<? extends Throwable> c) {
//----------------------------------------------------------------
// Mechanism to get all test threads into "running" mode.
//----------------------------------------------------------------
private static Phaser atTheStartingGate = new Phaser(3);
private static Phaser startingGate = new Phaser(3);

private static void toTheStartingGate() {
try {
boolean expectNextPhase = false;
if (atTheStartingGate.getUnarrivedParties() == 1) {
expectNextPhase = true;
boolean expectNextPhase = (startingGate.getUnarrivedParties() == 1);
int phase = startingGate.getPhase();
equal(phase, startingGate.arrive());
int awaitPhase;
for (boolean interrupted = false;;) {
try {
awaitPhase = startingGate.awaitAdvanceInterruptibly
(phase, 30, SECONDS);
if (interrupted) Thread.currentThread().interrupt();
break;
} catch (InterruptedException ie) {
interrupted = true;
}
}
int phase = atTheStartingGate.getPhase();
equal(phase, atTheStartingGate.arrive());
int awaitPhase = atTheStartingGate.awaitAdvanceInterruptibly
(phase, 30, SECONDS);
if (expectNextPhase) check(awaitPhase == phase + 1);
else check(awaitPhase == phase || awaitPhase == phase + 1);

pass();
} catch (Throwable t) {
unexpected(t);
// reset(atTheStartingGate);
// reset(startingGate);
throw new Error(t);
}
}
Expand Down Expand Up @@ -214,14 +225,25 @@ public Awaiter next() {
public void remove() {throw new UnsupportedOperationException();}};
}

private static void realMain(String[] args) throws Throwable {
// static long millisElapsedSince(long startTime) {
// return NANOSECONDS.toMillis(System.nanoTime() - startTime);
// }

// static void trace(String msg, long startTime) {
// System.err.println(msg);
// System.err.println(""+millisElapsedSince(startTime));
// }

private static void realMain(String[] args) throws Throwable {
@SuppressWarnings("unused")
long startTime = System.nanoTime();
Thread.currentThread().setName("mainThread");

//----------------------------------------------------------------
// Normal use
//----------------------------------------------------------------
try {
//trace("normal use", startTime);
Phaser phaser = new Phaser(3);
equal(phaser.getRegisteredParties(), 3);
equal(phaser.getArrivedParties(), 0);
Expand Down Expand Up @@ -252,6 +274,7 @@ private static void realMain(String[] args) throws Throwable {
// One thread interrupted
//----------------------------------------------------------------
try {
//trace("1 thread interrupted", startTime);
Phaser phaser = new Phaser(3);
Iterator<Arriver> arrivers = arriverIterator(phaser);
int phase = phaser.getPhase();
Expand All @@ -277,6 +300,7 @@ private static void realMain(String[] args) throws Throwable {
// Phaser is terminated while threads are waiting
//----------------------------------------------------------------
try {
//trace("terminated while waiting", startTime);
for (int i = 0; i < 10; i++) {
Phaser phaser = new Phaser(3);
Iterator<Awaiter> awaiters = awaiterIterator(phaser);
Expand All @@ -300,12 +324,13 @@ private static void realMain(String[] args) throws Throwable {
// Adds new unarrived parties to this phaser
//----------------------------------------------------------------
try {
//trace("new unarrived parties", startTime);
Phaser phaser = new Phaser(1);
Iterator<Arriver> arrivers = arriverIterator(phaser);
LinkedList<Arriver> arriverList = new LinkedList<Arriver>();
int phase = phaser.getPhase();
for (int i = 1; i < 5; i++) {
atTheStartingGate = new Phaser(1+(3*i));
startingGate = new Phaser(1+(3*i));
check(phaser.getPhase() == phase);
// register 3 more
phaser.register(); phaser.register(); phaser.register();
Expand All @@ -327,34 +352,36 @@ private static void realMain(String[] args) throws Throwable {
arriverList.clear();
phase++;
}
atTheStartingGate = new Phaser(3);
startingGate = new Phaser(3);
} catch (Throwable t) { unexpected(t); }

//----------------------------------------------------------------
// One thread timed out
//----------------------------------------------------------------
try {
//trace("1 thread timed out", startTime);
Phaser phaser = new Phaser(3);
Iterator<Arriver> arrivers = arriverIterator(phaser);
for (long timeout : new long[] { 0L, 5L }) {
for (int i = 0; i < 2; i++) {
Awaiter a1 = awaiter(phaser, timeout, SECONDS); a1.start();
Arriver a2 = arrivers.next(); a2.start();
toTheStartingGate();
a1.join();
checkResult(a1, TimeoutException.class);
phaser.arrive();
a2.join();
checkResult(a2, null);
check(!phaser.isTerminated());
}
for (long timeout : new long[] { 0L, 12L }) {
Awaiter a1 = awaiter(phaser, timeout, MILLISECONDS);
a1.start();
Arriver a2 = arrivers.next();
a2.start();
toTheStartingGate();
a1.join();
checkResult(a1, TimeoutException.class);
phaser.arrive();
a2.join();
checkResult(a2, null);
check(!phaser.isTerminated());
}
} catch (Throwable t) { unexpected(t); }

//----------------------------------------------------------------
// Barrier action completed normally
//----------------------------------------------------------------
try {
//trace("barrier action", startTime);
final AtomicInteger count = new AtomicInteger(0);
final Phaser[] kludge = new Phaser[1];
Phaser phaser = new Phaser(3) {
Expand Down Expand Up @@ -398,11 +425,38 @@ protected boolean onAdvance(int phase, int registeredParties) {
}

//--------------------- Infrastructure ---------------------------

/**
* A debugging tool to print stack traces of most threads, as jstack does.
* Uninteresting threads are filtered out.
*/
static void dumpTestThreads() {
ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
System.err.println("------ stacktrace dump start ------");
for (ThreadInfo info : threadMXBean.dumpAllThreads(true, true)) {
String name = info.getThreadName();
if ("Signal Dispatcher".equals(name))
continue;
if ("Reference Handler".equals(name)
&& info.getLockName().startsWith("java.lang.ref.Reference$Lock"))
continue;
if ("Finalizer".equals(name)
&& info.getLockName().startsWith("java.lang.ref.ReferenceQueue$Lock"))
continue;
if ("process reaper".equals(name))
continue;
if (name != null && name.startsWith("ForkJoinPool.commonPool-worker"))
continue;
System.err.print(info);
}
System.err.println("------ stacktrace dump end ------");
}

static volatile int passed = 0, failed = 0;
static void pass() {passed++;}
static void fail() {failed++; Thread.dumpStack();}
static void fail(String msg) {System.out.println(msg); fail();}
static void unexpected(Throwable t) {failed++; t.printStackTrace();}
static void unexpected(Throwable t) {failed++; t.printStackTrace(); dumpTestThreads();}
static void check(boolean cond) {if (cond) pass(); else fail();}
static void equal(Object x, Object y) {
if (x == null ? y == null : x.equals(y)) pass();
Expand All @@ -416,5 +470,5 @@ public static void test() {
public static void main(String[] args) {
try {realMain(args);} catch (Throwable t) {unexpected(t);}
System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
if (failed > 0) throw new AssertionError(failed + " tests failed");}
if (failed > 0) throw new AssertionError("Some tests failed");}
}

0 comments on commit f48168a

Please sign in to comment.