20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @bug 6253848 6366811
27 * @summary Basic tests for CyclicBarrier
28 * @library /test/lib
29 * @author Martin Buchholz, David Holmes
30 */
31
32 import static java.util.concurrent.TimeUnit.MILLISECONDS;
33
34 import java.util.ArrayList;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.concurrent.BrokenBarrierException;
38 import java.util.concurrent.CountDownLatch;
39 import java.util.concurrent.CyclicBarrier;
40 import java.util.concurrent.TimeoutException;
41 import java.util.concurrent.atomic.AtomicInteger;
42 import jdk.test.lib.Utils;
43
44 public class Basic {
45 static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
46
47 private static void checkBroken(final CyclicBarrier barrier) {
48 check(barrier.isBroken());
49 equal(barrier.getNumberWaiting(), 0);
50
51 THROWS(BrokenBarrierException.class,
52 () -> barrier.await(),
53 () -> barrier.await(100, MILLISECONDS));
54 }
55
56 private static void reset(CyclicBarrier barrier) {
57 barrier.reset();
58 check(! barrier.isBroken());
59 equal(barrier.getNumberWaiting(), 0);
276 barrier.await();
277 fail("Expected Error not thrown"); }
278 catch (Error e) { pass(); }
279 catch (Throwable t) { unexpected(t); }
280 a1.join();
281 a2.join();
282 checkResult(a1, BrokenBarrierException.class);
283 checkResult(a2, BrokenBarrierException.class);
284 checkBroken(barrier);
285 reset(barrier);
286 }
287 } catch (Throwable t) { unexpected(t); }
288
289 testInterrupts();
290 }
291
292 /**
293 * Handling of extra interrupts while waiting - tests for bug 6366811
294 */
295 private static void testInterrupts() {
296 final int N = 10;
297 final CyclicBarrier startingGate = new CyclicBarrier(N+1);
298
299 /**
300 * A version of Awaiter that also records interrupted state.
301 */
302 class Waiter extends CheckedThread {
303 private boolean timed;
304 private CyclicBarrier barrier;
305 private CountDownLatch doneSignal;
306 private Throwable throwable;
307 private boolean interrupted;
308
309 public Waiter(boolean timed,
310 CountDownLatch doneSignal,
311 CyclicBarrier barrier) {
312 this.timed = timed;
313 this.doneSignal = doneSignal;
314 this.barrier = barrier;
315 }
316 Throwable throwable() { return this.throwable; }
317 boolean interruptBit() { return this.interrupted; }
318 void realRun() throws Throwable {
319 startingGate.await(LONG_DELAY_MS, MILLISECONDS);
320 try {
321 if (timed) barrier.await(LONG_DELAY_MS, MILLISECONDS);
322 else barrier.await(); }
323 catch (Throwable throwable) { this.throwable = throwable; }
324
325 try { doneSignal.await(LONG_DELAY_MS, MILLISECONDS); }
326 catch (InterruptedException e) { interrupted = true; }
327 }
328 }
329
330 //----------------------------------------------------------------
331 // Interrupt occurs during barrier trip
332 //----------------------------------------------------------------
333 try {
334 final CountDownLatch doneSignal = new CountDownLatch(1);
335 final List<Waiter> waiters = new ArrayList<>(N);
336
337 // work around finality of closed-over variables
338 final Runnable[] realAction = new Runnable[1];
339 final Runnable delegateAction =
340 new Runnable() {public void run() {realAction[0].run();}};
341 final CyclicBarrier barrier = new CyclicBarrier(N+1, delegateAction);
342
343 realAction[0] = new Runnable() { public void run() {
344 try {
345 for (int i = 0; i < N/2; i++)
346 waiters.get(i).interrupt();
347 // we need to try and ensure that the waiters get
348 // to process their interruption before we do the
349 // signalAll that trips the barrier. Using sleep
350 // seems to work reliably while yield does not.
351 Thread.sleep(100);
352 } catch (Throwable t) { unexpected(t); }
353 }};
354 for (int i = 0; i < N; i++) {
355 Waiter waiter = new Waiter(i < N/2, doneSignal, barrier);
356 waiter.start();
357 waiters.add(waiter);
358 }
359 startingGate.await(LONG_DELAY_MS, MILLISECONDS);
360 while (barrier.getNumberWaiting() < N) Thread.yield();
361 barrier.await();
362 doneSignal.countDown();
363 int countInterrupted = 0;
364 int countInterruptedException = 0;
365 int countBrokenBarrierException = 0;
366 for (Waiter waiter : waiters) {
367 waiter.join();
368 equal(waiter.throwable(), null);
369 if (waiter.interruptBit())
370 countInterrupted++;
371 }
372 equal(countInterrupted, N/2);
373 check(! barrier.isBroken());
374 } catch (Throwable t) { unexpected(t); }
375
376 //----------------------------------------------------------------
377 // Multiple interrupts occur during barrier await
378 //----------------------------------------------------------------
379 try {
380 final CountDownLatch doneSignal = new CountDownLatch(1);
381 final CyclicBarrier barrier = new CyclicBarrier(N+1);
382 final List<Waiter> waiters = new ArrayList<>(N);
383 for (int i = 0; i < N; i++) {
384 Waiter waiter = new Waiter(i < N/2, doneSignal, barrier);
385 waiter.start();
386 waiters.add(waiter);
387 }
388 startingGate.await(LONG_DELAY_MS, MILLISECONDS);
389 while (barrier.getNumberWaiting() < N) Thread.yield();
390 for (int i = 0; i < N/2; i++)
391 waiters.get(i).interrupt();
392 doneSignal.countDown();
393 int countInterrupted = 0;
394 int countInterruptedException = 0;
395 int countBrokenBarrierException = 0;
396 for (Waiter waiter : waiters) {
397 waiter.join();
398 if (waiter.throwable() instanceof InterruptedException)
399 countInterruptedException++;
400 if (waiter.throwable() instanceof BrokenBarrierException)
401 countBrokenBarrierException++;
402 if (waiter.interruptBit())
403 countInterrupted++;
404 }
405 equal(countInterrupted, N/2-1);
406 equal(countInterruptedException, 1);
407 equal(countBrokenBarrierException, N-1);
408 checkBroken(barrier);
409 reset(barrier);
410 } catch (Throwable t) { unexpected(t); }
411 }
412
413 //--------------------- Infrastructure ---------------------------
414 static volatile int passed = 0, failed = 0;
415 static void pass() {passed++;}
416 static void fail() {failed++; Thread.dumpStack();}
417 static void fail(String msg) {System.out.println(msg); fail();}
418 static void unexpected(Throwable t) {failed++; t.printStackTrace();}
419 static void check(boolean cond) {if (cond) pass(); else fail();}
420 static void equal(Object x, Object y) {
421 if (x == null ? y == null : x.equals(y)) pass();
422 else fail(x + " not equal to " + y);}
423 public static void main(String[] args) throws Throwable {
424 try {realMain(args);} catch (Throwable t) {unexpected(t);}
425 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
426 if (failed > 0) throw new AssertionError("Some tests failed");}
427 interface Fun {void f() throws Throwable;}
428 private static void THROWS(Class<? extends Throwable> k, Fun... fs) {
|
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24 /*
25 * @test
26 * @bug 6253848 6366811
27 * @summary Basic tests for CyclicBarrier
28 * @library /test/lib
29 * @author Martin Buchholz, David Holmes
30 */
31
32 import static java.util.concurrent.TimeUnit.MILLISECONDS;
33
34 import java.util.ArrayList;
35 import java.util.Iterator;
36 import java.util.List;
37 import java.util.concurrent.BrokenBarrierException;
38 import java.util.concurrent.CountDownLatch;
39 import java.util.concurrent.CyclicBarrier;
40 import java.util.concurrent.ThreadLocalRandom;
41 import java.util.concurrent.TimeoutException;
42 import java.util.concurrent.atomic.AtomicInteger;
43 import jdk.test.lib.Utils;
44
45 public class Basic {
46 static final long LONG_DELAY_MS = Utils.adjustTimeout(10_000);
47
48 private static void checkBroken(final CyclicBarrier barrier) {
49 check(barrier.isBroken());
50 equal(barrier.getNumberWaiting(), 0);
51
52 THROWS(BrokenBarrierException.class,
53 () -> barrier.await(),
54 () -> barrier.await(100, MILLISECONDS));
55 }
56
57 private static void reset(CyclicBarrier barrier) {
58 barrier.reset();
59 check(! barrier.isBroken());
60 equal(barrier.getNumberWaiting(), 0);
277 barrier.await();
278 fail("Expected Error not thrown"); }
279 catch (Error e) { pass(); }
280 catch (Throwable t) { unexpected(t); }
281 a1.join();
282 a2.join();
283 checkResult(a1, BrokenBarrierException.class);
284 checkResult(a2, BrokenBarrierException.class);
285 checkBroken(barrier);
286 reset(barrier);
287 }
288 } catch (Throwable t) { unexpected(t); }
289
290 testInterrupts();
291 }
292
293 /**
294 * Handling of extra interrupts while waiting - tests for bug 6366811
295 */
296 private static void testInterrupts() {
297 final int N = ThreadLocalRandom.current().nextInt(2, 10);
298 final CyclicBarrier startingGate = new CyclicBarrier(N+1);
299
300 /**
301 * A version of Awaiter that also records interrupted state.
302 */
303 class Waiter extends CheckedThread {
304 private final boolean timed;
305 private final CyclicBarrier barrier;
306 private final CountDownLatch doneSignal;
307 volatile Throwable throwable;
308 volatile boolean interruptStatusSetAfterAwait;
309
310 public Waiter(CountDownLatch doneSignal, CyclicBarrier barrier) {
311 this.timed = ThreadLocalRandom.current().nextBoolean();
312 this.doneSignal = doneSignal;
313 this.barrier = barrier;
314 }
315
316 void realRun() throws Throwable {
317 startingGate.await(LONG_DELAY_MS, MILLISECONDS);
318
319 try {
320 if (timed) barrier.await(LONG_DELAY_MS, MILLISECONDS);
321 else barrier.await();
322 } catch (Throwable throwable) {
323 this.throwable = throwable;
324 }
325
326 try {
327 check(doneSignal.await(LONG_DELAY_MS, MILLISECONDS));
328 if (Thread.interrupted())
329 interruptStatusSetAfterAwait = true;
330 } catch (InterruptedException e) {
331 interruptStatusSetAfterAwait = true;
332 }
333 }
334 }
335
336 //----------------------------------------------------------------
337 // Interrupt occurs during barrier trip
338 //----------------------------------------------------------------
339 try {
340 final CountDownLatch doneSignal = new CountDownLatch(1);
341 final List<Waiter> waiters = new ArrayList<>(N);
342
343 // work around finality of closed-over variables
344 final Runnable[] realAction = new Runnable[1];
345 final Runnable delegateAction =
346 new Runnable() {public void run() {realAction[0].run();}};
347 final CyclicBarrier barrier = new CyclicBarrier(N+1, delegateAction);
348
349 realAction[0] = new Runnable() { public void run() {
350 try {
351 for (int i = 0; i < N/2; i++)
352 waiters.get(i).interrupt();
353 // we need to try and ensure that the waiters get
354 // to process their interruption before we do the
355 // signalAll that trips the barrier. Using sleep
356 // seems to work reliably while yield does not.
357 Thread.sleep(100);
358 } catch (Throwable t) { unexpected(t); }
359 }};
360 for (int i = 0; i < N; i++) {
361 Waiter waiter = new Waiter(doneSignal, barrier);
362 waiter.start();
363 waiters.add(waiter);
364 }
365 startingGate.await(LONG_DELAY_MS, MILLISECONDS);
366 while (barrier.getNumberWaiting() < N) Thread.yield();
367 barrier.await();
368 doneSignal.countDown();
369 int countInterruptStatusSetAfterAwait = 0;
370 for (Waiter waiter : waiters) {
371 waiter.join();
372 equal(waiter.throwable, null);
373 if (waiter.interruptStatusSetAfterAwait)
374 countInterruptStatusSetAfterAwait++;
375 }
376 equal(countInterruptStatusSetAfterAwait, N/2);
377 check(! barrier.isBroken());
378 } catch (Throwable t) { unexpected(t); }
379
380 //----------------------------------------------------------------
381 // Multiple interrupts occur during barrier await
382 //----------------------------------------------------------------
383 try {
384 final CountDownLatch doneSignal = new CountDownLatch(1);
385 final CyclicBarrier barrier = new CyclicBarrier(N+1);
386 final List<Waiter> waiters = new ArrayList<>(N);
387 for (int i = 0; i < N; i++) {
388 Waiter waiter = new Waiter(doneSignal, barrier);
389 waiter.start();
390 waiters.add(waiter);
391 }
392 startingGate.await(LONG_DELAY_MS, MILLISECONDS);
393 while (barrier.getNumberWaiting() < N) Thread.yield();
394 for (int i = 0; i < N/2; i++) {
395 Thread waiter = waiters.get(i);
396 waiter.interrupt();
397 }
398 doneSignal.countDown();
399 int countInterruptedException = 0;
400 int countBrokenBarrierException = 0;
401 int countInterruptStatusSetAfterAwait = 0;
402 for (Waiter waiter : waiters) {
403 waiter.join();
404 if (waiter.throwable instanceof InterruptedException)
405 countInterruptedException++;
406 if (waiter.throwable instanceof BrokenBarrierException)
407 countBrokenBarrierException++;
408 if (waiter.interruptStatusSetAfterAwait)
409 countInterruptStatusSetAfterAwait++;
410 }
411 equal(countInterruptedException, 1);
412 equal(countBrokenBarrierException, N-1);
413 checkBroken(barrier);
414 equal(countInterruptStatusSetAfterAwait, N/2-1);
415 reset(barrier);
416 } catch (Throwable t) { unexpected(t); }
417 }
418
419 //--------------------- Infrastructure ---------------------------
420 static volatile int passed = 0, failed = 0;
421 static void pass() {passed++;}
422 static void fail() {failed++; Thread.dumpStack();}
423 static void fail(String msg) {System.out.println(msg); fail();}
424 static void unexpected(Throwable t) {failed++; t.printStackTrace();}
425 static void check(boolean cond) {if (cond) pass(); else fail();}
426 static void equal(Object x, Object y) {
427 if (x == null ? y == null : x.equals(y)) pass();
428 else fail(x + " not equal to " + y);}
429 public static void main(String[] args) throws Throwable {
430 try {realMain(args);} catch (Throwable t) {unexpected(t);}
431 System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
432 if (failed > 0) throw new AssertionError("Some tests failed");}
433 interface Fun {void f() throws Throwable;}
434 private static void THROWS(Class<? extends Throwable> k, Fun... fs) {
|