About JDK-6772009
chen zero
stzdzyhs at gmail.com
Fri Jan 6 01:23:55 UTC 2017
Hi Martin,
I just curious and to get self more familiar with java.
and that's what I try to do, simplify the test case, only waiting 1 round
on the barrier
In my previous email, I said I saw BrokenCarrierException, however, it's
very rare to occur, and even I can not reproduce it now.
anyway, I will see the latest code in jdk9....
Thanks,
chenzero
On Fri, Jan 6, 2017 at 2:20 AM, Martin Buchholz <martinrb at google.com> wrote:
> jtreg CancelledLockLoops is not a great test. There have been changes to
> it in jdk9 and it is not known to fail currently.
>
> But chen, why are you working on this test? If you see it failing, try
> simply replacing with the jdk9 version. Otherwise, I'd like to see such
> tests replaced with more focused understandable correctness tests rather
> than patched.
>
> On Wed, Jan 4, 2017 at 9:20 PM, chen zero <stzdzyhs at gmail.com> wrote:
>
>> Yes, the problem is related to the interrupt, timing and combine with
>> BrokenBarrierException, the whole testcase very complex.
>> so, I change the testcase as following:
>> in the main:
>> left 2 thread Un-interrupt.
>> wait on the barrier. // if wait return, that means all threads
>> end.
>> verify completed > 2
>>
>> in the working thread:
>> try lock and do calculation....
>> if interrupted, skip calculation
>> wait on the barrier.
>>
>> yes, the barrier will be only wait 1 time, (in original code the barrier
>> will wait 2 times),
>> in my testing, sometime, in the 2nd time wait, BrokenBarrierException will
>> be thrown, however, it's not catch and make
>> the whole test case skipped.
>> anyway, two times wait on barrier are very complex....
>> so, only 1 time wait on barrier and in my testing, anything is as expected
>> :)
>>
>> My code is from from jdk8u branch from git, and I compare with the code
>> posted in the JiRA, also same.
>>
>>
>> On Thu, Jan 5, 2017 at 12:48 PM, David Holmes <david.holmes at oracle.com>
>> wrote:
>>
>> > Hi,
>> >
>> > You seem to be looking at an older version of the test code.
>> >
>> > As I said in my previous mail I think the problem is that an interrupted
>> > thread can follow this path:
>> >
>> > if (!interrupted) {
>> > if (print)
>> > System.out.printf("completed after %d millis%n",
>> > NANOSECONDS.toMillis(System.nanoTime() - startTime));
>> > lock.lock();
>> > try {
>> > ++completed;
>> > }
>> > finally {
>> > lock.unlock();
>> > }
>> > }
>> >
>> > because interrupted is only set when InterruptedException is caught:
>> >
>> > while (!done || Thread.currentThread().isInterrupted()) {
>> > try {
>> > lock.lockInterruptibly();
>> > }
>> > catch (InterruptedException ie) {
>> > interrupted = true;
>> >
>> > but we can also exit the loop due to interruption, without recording the
>> > fact we were interrupted. In which case the completed count will be too
>> > high.
>> >
>> > Cheers,
>> > David
>> >
>> >
>> > On 5/01/2017 2:39 PM, chen zero wrote:
>> >
>> >> Hi David,
>> >> Thank you for reminding.
>> >> I post the code here.
>> >>
>> >>
>> >> import java.util.Arrays;
>> >> import java.util.Collections;
>> >> import java.util.Random;
>> >> import java.util.concurrent.BrokenBarrierException;
>> >> import java.util.concurrent.CyclicBarrier;
>> >> import java.util.concurrent.locks.ReentrantLock;
>> >>
>> >> // https://bugs.openjdk.java.net/browse/JDK-6772009
>> >>
>> >> public final class CancelledLockLoops {
>> >> static final Random rng = new Random();
>> >> static boolean print = false;
>> >> //static final int ITERS = 1000000;
>> >> static final int ITERS = 10000000;
>> >>
>> >> static final long TIMEOUT = 100;
>> >>
>> >> public static void main(String[] args) throws Exception {
>> >> int maxThreads = 5;
>> >> if (args.length > 0) {
>> >> maxThreads = Integer.parseInt(args[0]);
>> >> }
>> >>
>> >> print = true;
>> >>
>> >> for (int i = 2; i <= maxThreads; i += (i+1) >>> 1) {
>> >> System.out.print("Threads: " + i);
>> >>
>> >> try {
>> >> new ReentrantLockLoop(i).test();
>> >> }
>> >> catch (BrokenBarrierException bb) {
>> >> // OK, ignore
>> >> bb.printStackTrace();
>> >> }
>> >> Thread.sleep(TIMEOUT);
>> >> }
>> >> }
>> >>
>> >> static final class ReentrantLockLoop implements Runnable {
>> >> private int v = rng.nextInt();
>> >> private int completed;
>> >> private volatile int result = 17;
>> >> private final ReentrantLock lock = new ReentrantLock();
>> >> private final LoopHelpers.BarrierTimer timer = new
>> >> LoopHelpers.BarrierTimer();
>> >> private final CyclicBarrier barrier;
>> >> private final int nthreads;
>> >>
>> >> ReentrantLockLoop(int nthreads) {
>> >> this.nthreads = nthreads;
>> >> barrier = new CyclicBarrier(nthreads+1, timer);
>> >> }
>> >>
>> >> void checkBarrierStatus() {
>> >> if(this.barrier.isBroken()) {
>> >> throw new Error("barrier is broken !!!");
>> >> }
>> >> }
>> >>
>> >> final void test() throws Exception {
>> >> checkBarrierStatus();
>> >>
>> >> timer.run();
>> >>
>> >> Thread[] threads = new Thread[nthreads];
>> >> for (int i = 0; i < threads.length; ++i) {
>> >> threads[i] = new Thread(this, "th"+i);
>> >> }
>> >>
>> >> for (int i = 0; i < threads.length; ++i) {
>> >> threads[i].start();
>> >> }
>> >>
>> >> Thread[] cancels = (Thread[])(threads.clone());
>> >>
>> >> Collections.shuffle(Arrays.asList(cancels), rng);
>> >> Thread.sleep(TIMEOUT);
>> >> for (int i = 0; i < cancels.length-2; ++i) {
>> >> cancels[i].interrupt();
>> >> // make sure all OK even when cancellations spaced out
>> >> if ((i & 3) == 0) {
>> >> Thread.sleep(1 + rng.nextInt(10));
>> >> }
>> >> }
>> >>
>> >> Thread.sleep(TIMEOUT);
>> >>
>> >> try {
>> >> // in here, the barrier might be broken because some
>> >> working threads is interrupted.
>> >> // so, catching the BrokenBarrierException to let
>> >> testcase continue running
>> >> barrier.await();
>> >> }
>> >> catch(BrokenBarrierException e) {
>> >> // nop
>> >> }
>> >>
>> >> if (print) {
>> >> // since the barrier might be broken ( the barrier
>> >> action will not run),
>> >> // running here to ensure time is set.
>> >> timer.run();
>> >> long time = timer.getTime();
>> >> double secs = (double)(time) / 1000000000.0;
>> >> System.out.println("\t " + secs + "s run time");
>> >> }
>> >>
>> >> int c;
>> >> lock.lock();
>> >> //System.out.println("main to verify completed.....");
>> >>
>> >> try {
>> >> c = completed;
>> >> }
>> >> finally {
>> >> lock.unlock();
>> >> }
>> >> // here the completed should not < 2, it can not guarantee
>> >> that always == 2.
>> >> if (c < 2) {
>> >> throw new Error("Completed < 2 : " + c);
>> >> }
>> >>
>> >> int r = result;
>> >> if (r == 0) { // avoid overoptimization
>> >> System.out.println("useless result: " + r);
>> >> }
>> >> }
>> >>
>> >> public final void run() {
>> >> try {
>> >> checkBarrierStatus();
>> >>
>> >> int sum = v;
>> >> int x = 0;
>> >> int n = ITERS;
>> >> do {
>> >> try {
>> >> lock.lockInterruptibly();
>> >> }
>> >> catch (InterruptedException ie) {
>> >> break;
>> >> }
>> >> try {
>> >> v = x = LoopHelpers.compute1(v);
>> >> }
>> >> finally {
>> >> lock.unlock();
>> >> }
>> >> sum += LoopHelpers.compute2(x);
>> >> } while (n-- > 0);
>> >>
>> >> /*
>> >> * in the main thread, two threads are un-interrupted,
>> >> others threads are interrupted.
>> >> * this line, however, can not guarantee that only
>> >> "un-interrupted" threads can go in,
>> >> * but also interrupted threads can go in,
>> >> * so, the "completed" will not always == 2, might be
>> > 2
>> >> */
>> >> if (n < 0) {
>> >> lock.lock();
>> >> try {
>> >> ++completed;
>> >> }
>> >> finally {
>> >> lock.unlock();
>> >> }
>> >> }
>> >>
>> >> result += sum;
>> >> barrier.await();
>> >> }
>> >> catch(BrokenBarrierException ex) {
>> >> //ex.printStackTrace();
>> >> }
>> >> catch(InterruptedException ex) {
>> >> //ex.printStackTrace();
>> >> }
>> >> catch (Exception ex) {
>> >> ex.printStackTrace();
>> >> return;
>> >> }
>> >> }
>> >> }
>> >>
>> >> }
>> >>
>> >>
>> >> On Thu, Jan 5, 2017 at 12:20 PM, David Holmes <david.holmes at oracle.com
>> >> <mailto:david.holmes at oracle.com>> wrote:
>> >>
>> >> Hi chenzero,
>> >>
>> >> Attachments get stripped from the mailing lists so you'll need to
>> >> include your patch inline, or else get someone to host it for you
>> on
>> >> cr.openjdk.java.net <http://cr.openjdk.java.net>
>> >>
>> >> Thanks,
>> >> David
>> >> .....
>> >>
>> >>
>>
>
>
More information about the core-libs-dev
mailing list