/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* @test
* @bug 6253848 6366811
* @summary Basic tests for CyclicBarrier
* @author Martin Buchholz, David Holmes
*/
public class Basic {
THROWS(BrokenBarrierException.class,
}
}
// t.printStackTrace();
fail("Mismatch in thread " +
a.getName() + ": " +
t + ", " +
} else {
pass();
}
}
//----------------------------------------------------------------
// Mechanism to get all victim threads into "running" mode.
// The fact that this also uses CyclicBarrier is entirely coincidental.
//----------------------------------------------------------------
private static void toTheStartingGate() {
catch (Throwable t) {
unexpected(t);
throw new Error(t);
}
}
//----------------------------------------------------------------
// Convenience methods for creating threads that call CyclicBarrier.await
//----------------------------------------------------------------
{
this.setDaemon(true);
}
}
}
final long millis) {
}
// Returns an infinite lazy list of all possible awaiter pair combinations.
int i = 0;
public boolean hasNext() { return true; }
switch ((i++)&7) {
case 0: case 2: case 4: case 5:
default:
public void remove() {throw new UnsupportedOperationException();}};
}
//----------------------------------------------------------------
// Normal use
//----------------------------------------------------------------
try {
for (boolean doReset : new boolean[] {false, true})
for (int i = 0; i < 4; i++) {
}
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
// One thread interrupted
//----------------------------------------------------------------
try {
for (int i = 0; i < 4; i++) {
}
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
// Barrier is reset while threads are waiting
//----------------------------------------------------------------
try {
for (int i = 0; i < 4; i++) {
}
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
// One thread timed out
//----------------------------------------------------------------
try {
for (int i = 0; i < 2; i++) {
}
}
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
// Barrier action completed normally
//----------------------------------------------------------------
try {
for (int i = 0; i < 4; i++) {
catch (Throwable t) { unexpected(t); }
}
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
// Barrier action threw exception
//----------------------------------------------------------------
try {
for (int i = 0; i < 4; i++) {
try {
fail("Expected Error not thrown"); }
catch (Throwable t) { unexpected(t); }
}
} catch (Throwable t) { unexpected(t); }
}
/**
* Handling of extra interrupts while waiting - tests for bug 6366811
*/
private static void testInterrupts() {
final int N = 10;
/**
* A version of Awaiter that also records interrupted state.
*/
class Waiter extends CheckedThread {
private boolean timed;
private CyclicBarrier barrier;
private CountDownLatch doneSignal;
private boolean interrupted;
this.doneSignal = doneSignal;
}
boolean interruptBit() { return this.interrupted; }
try {
catch (InterruptedException e) { interrupted = true; }
}
}
//----------------------------------------------------------------
// Interrupt occurs during barrier trip
//----------------------------------------------------------------
try {
// work around finality of closed-over variables
final Runnable delegateAction =
try {
for (int i = 0; i < N/2; i++)
// we need to try and ensure that the waiters get
// to process their interruption before we do the
// signalAll that trips the barrier. Using sleep
// seems to work reliably while yield does not.
} catch (Throwable t) { unexpected(t); }
}};
for (int i = 0; i < N; i++) {
}
int countInterrupted = 0;
int countInterruptedException = 0;
int countBrokenBarrierException = 0;
if (waiter.interruptBit())
}
} catch (Throwable t) { unexpected(t); }
//----------------------------------------------------------------
// Multiple interrupts occur during barrier await
//----------------------------------------------------------------
try {
for (int i = 0; i < N; i++) {
}
for (int i = 0; i < N/2; i++)
int countInterrupted = 0;
int countInterruptedException = 0;
int countBrokenBarrierException = 0;
if (waiter.interruptBit())
}
} catch (Throwable t) { unexpected(t); }
}
//--------------------- Infrastructure ---------------------------
else fail(x + " not equal to " + y);}
catch (Throwable t) {
else unexpected(t);}}
public void run() {
}