2018-06-01 15:48:55 -07:00
|
|
|
/*
|
2020-01-27 15:35:10 -08:00
|
|
|
* Copyright (c) 2013, 2020, Oracle and/or its affiliates. All rights reserved.
|
2018-06-01 15:48:55 -07:00
|
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
|
|
*
|
|
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
|
|
* 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.
|
|
|
|
*/
|
|
|
|
package jit.escape.LockCoarsening;
|
|
|
|
|
|
|
|
import nsk.share.TestFailure;
|
|
|
|
|
2020-01-27 15:35:10 -08:00
|
|
|
public class LockCoarsening {
|
2018-06-01 15:48:55 -07:00
|
|
|
// JVM option '-XX:+EliminateLocks' specified
|
|
|
|
public static boolean eliminateLocks = false;
|
|
|
|
// Number of chances Thread 2 has to acquire the lock
|
|
|
|
public static int numChances = 16;
|
|
|
|
|
|
|
|
// Signals to Threads_2 that Thread_1 started execuition
|
|
|
|
public static volatile boolean start;
|
|
|
|
// Signals to Thread_2 to stop execution
|
|
|
|
public static volatile boolean done;
|
|
|
|
// Thread_2 has acquired the lock
|
|
|
|
public static volatile boolean acquiredLock;
|
|
|
|
// Actually running the test
|
|
|
|
public static volatile boolean realrun;
|
|
|
|
// Thread 2 'acquire lock chance' number
|
|
|
|
public static volatile int currentChance;
|
|
|
|
|
|
|
|
static Thread_2 t2;
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
parseArgs(args);
|
|
|
|
|
|
|
|
Thread.currentThread().getThreadGroup().setMaxPriority(Thread.MAX_PRIORITY);
|
|
|
|
|
|
|
|
currentChance = 1;
|
|
|
|
|
|
|
|
do {
|
|
|
|
System.out.println("Chance " + currentChance + ":");
|
|
|
|
|
|
|
|
Thread_1 t1 = new Thread_1();
|
|
|
|
t1.getThreadGroup().setMaxPriority(Thread.MAX_PRIORITY);
|
|
|
|
t1.setPriority(Thread.MIN_PRIORITY);
|
|
|
|
t1.start();
|
|
|
|
|
|
|
|
try {
|
|
|
|
t1.join();
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
}
|
|
|
|
|
|
|
|
System.out.println();
|
|
|
|
|
|
|
|
// if thread 2 hasn't acquired lock and we are not eliminating them, give it one more try...
|
|
|
|
} while (!eliminateLocks && !acquiredLock && ++currentChance <= numChances);
|
|
|
|
|
|
|
|
System.out.println("Thread 2 has acquired lock: " + acquiredLock);
|
|
|
|
|
|
|
|
boolean failed = false;
|
|
|
|
|
|
|
|
if (!eliminateLocks) {
|
|
|
|
if (!acquiredLock) {
|
|
|
|
failed = true;
|
|
|
|
|
|
|
|
throw new TestFailure("acquiredLock == false, though, '-XX:-EliminateLocks' specified");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
if (acquiredLock) {
|
|
|
|
failed = true;
|
|
|
|
|
|
|
|
throw new TestFailure("acquiredLock == true, though, '-XX:+EliminateLocks' specified");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!failed)
|
|
|
|
System.out.println("TEST PASSED");
|
|
|
|
else
|
|
|
|
throw new TestFailure("TEST FAILED");
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void parseArgs(String[] args) {
|
|
|
|
eliminateLocks = false;
|
|
|
|
|
|
|
|
for (int i = 0; i < args.length; ++i) {
|
|
|
|
String arg = args[i];
|
|
|
|
String val;
|
|
|
|
|
|
|
|
if (arg.equals("-eliminateLocks")) {
|
|
|
|
eliminateLocks = true;
|
|
|
|
} else if (arg.equals("-numChances")) {
|
|
|
|
if (++i >= args.length)
|
|
|
|
throw new TestFailure("'numChances' parameter requires an integer value");
|
|
|
|
val = args[i];
|
|
|
|
try {
|
|
|
|
numChances = Integer.parseInt(val);
|
|
|
|
} catch (NumberFormatException e) {
|
|
|
|
throw new TestFailure("invalid value for 'numChances'");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
System.out.println("Invalid argument: " + args);
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Thread that enters synchronized parts which are subject of
|
|
|
|
* lock coarsening
|
|
|
|
*/
|
|
|
|
public static class Thread_1 extends Thread {
|
|
|
|
public void run() {
|
|
|
|
Dummy lock = new Dummy();
|
|
|
|
|
|
|
|
// An ugly-terrible hack to force JIT to compile Thread_1.doit():
|
|
|
|
// 1: call method from a static method of another class within a loop
|
|
|
|
System.out.println("**** Compilation warm-up *****");
|
|
|
|
realrun = false;
|
|
|
|
Helper.callMethod(this, lock);
|
|
|
|
|
|
|
|
// 2: call method normally
|
|
|
|
System.out.println("**** Starting real run ****");
|
|
|
|
realrun = true;
|
|
|
|
this.doit(lock);
|
|
|
|
}
|
|
|
|
|
|
|
|
public final void doit(Dummy _lock) {
|
|
|
|
Dummy lock = new Dummy();
|
|
|
|
|
|
|
|
start = false;
|
|
|
|
done = false;
|
|
|
|
acquiredLock = false;
|
|
|
|
|
|
|
|
/*Thread_2*/
|
|
|
|
t2 = new Thread_2(lock);
|
|
|
|
t2.getThreadGroup().setMaxPriority(Thread.MAX_PRIORITY);
|
|
|
|
t2.setPriority(Thread.MAX_PRIORITY);
|
|
|
|
t2.start();
|
|
|
|
|
|
|
|
//waiting for the Thread_2 to invoke lock.wait()
|
|
|
|
while (t2.getState() != Thread.State.WAITING) { }
|
|
|
|
start = true;
|
|
|
|
|
|
|
|
// The following code is subject to lock coarsening if eliminateLocks == true
|
|
|
|
{
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
}
|
|
|
|
|
|
|
|
// Footer
|
|
|
|
synchronized (lock) {
|
|
|
|
lock.foo();
|
|
|
|
|
|
|
|
done = true;
|
|
|
|
|
|
|
|
lock.notify();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
t2.join();
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Thread that tries to acquire lock during lock coarsening.
|
|
|
|
* If it unable to do it then lock coarsening occurred.
|
|
|
|
*/
|
|
|
|
private static class Thread_2 extends Thread {
|
|
|
|
private Dummy lock;
|
|
|
|
|
|
|
|
public Thread_2(Dummy lock) {
|
|
|
|
this.lock = lock;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void run() {
|
|
|
|
Dummy lock = this.lock;
|
|
|
|
|
|
|
|
synchronized (lock) {
|
|
|
|
if (!done) {
|
|
|
|
while (!start) {
|
|
|
|
try {
|
|
|
|
lock.wait();
|
|
|
|
} catch (InterruptedException e) {
|
|
|
|
System.out.println("Interrupted!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!done) {
|
|
|
|
done = true;
|
|
|
|
|
|
|
|
acquiredLock = true;
|
|
|
|
|
|
|
|
if (realrun) {
|
|
|
|
System.out.println("Acquired lock at " + lock.counter + " iteration of " + currentChance + " chance");
|
|
|
|
} else if (eliminateLocks) {
|
|
|
|
//forcibly stop warm-up as we see that lock coarsening occurs
|
|
|
|
Helper.allowExec = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Helper class to make method Thread_1.doit() be compiled.
|
|
|
|
*/
|
|
|
|
public static class Helper {
|
|
|
|
public static volatile boolean allowExec = false;
|
|
|
|
private static int iterations = 10000;
|
|
|
|
|
|
|
|
public static void callMethod(Thread_1 t, Dummy lock) {
|
|
|
|
for (int i = 0; i < iterations; ++i) {
|
|
|
|
t.doit(lock);
|
|
|
|
if (allowExec)
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Class to count number of synchronized statement.
|
|
|
|
* If test fails Dummy.counter shows iteration when lock coarsening did not happen
|
|
|
|
*/
|
|
|
|
public static class Dummy {
|
|
|
|
public volatile int counter = 0;
|
|
|
|
|
|
|
|
public void foo() {
|
|
|
|
if (done)
|
|
|
|
return;
|
|
|
|
|
|
|
|
while (t2.getState() != Thread.State.BLOCKED && t2.getState() != Thread.State.WAITING) {
|
|
|
|
this.notifyAll();
|
|
|
|
|
|
|
|
Thread.yield();
|
|
|
|
}
|
|
|
|
|
|
|
|
this.notifyAll();
|
|
|
|
|
|
|
|
while (t2.getState() != Thread.State.BLOCKED) {
|
|
|
|
Thread.yield();
|
|
|
|
}
|
|
|
|
|
|
|
|
++counter;
|
|
|
|
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
Thread.yield();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|