Skip to content

Commit

Permalink
Fix race with double init
Browse files Browse the repository at this point in the history
  • Loading branch information
jerboaa committed Oct 4, 2023
1 parent 1ae2dc0 commit 318f108
Show file tree
Hide file tree
Showing 2 changed files with 10 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ public static UnsignedWord size() {
if (expired) {
throw new InternalError("Expired latch!");
}
VMError.guarantee(cachedSize != UNSET_SENTINEL, "Expected chached size to be set");
VMError.guarantee(cachedSize != UNSET_SENTINEL, "Expected cached size to be set");
return cachedSize;
} catch (InterruptedException e) {
throw VMError.shouldNotReachHere("Interrupt on countdown latch!");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ final class DirectMemoryAccessors {
* otherwise.
*/
private static boolean isInitialized;
private static final int INITIALIZING = 1;
private static final int INITIALIZED = 2;
private static final AtomicInteger INIT_COUNT = new AtomicInteger();
private static final long STATIC_DIRECT_MEMORY_AMOUNT = 25 * 1024 * 1024;
private static long directMemory;
Expand All @@ -102,9 +104,9 @@ static long getDirectMemory() {
}

private static void initialize() {
if (INIT_COUNT.get() == 2) {
if (INIT_COUNT.get() == INITIALIZED) {
/*
* Shouldn't really happen, but safeguard for recursive init anyway
* Safeguard for recursive init
*/
return;
}
Expand All @@ -130,18 +132,18 @@ private static void initialize() {
* of 1, since we read the directMemory field during container support code
* execution which runs when PhysicalMemory is still initializing.
*/
VMError.guarantee(INIT_COUNT.get() <= 1, "Initial run needs to have init count 0 or 1");
VMError.guarantee(INIT_COUNT.get() <= INITIALIZING, "Initial run needs to have init count 0 or 1");
newDirectMemory = STATIC_DIRECT_MEMORY_AMOUNT; // Static value during initialization
INIT_COUNT.incrementAndGet();
INIT_COUNT.setRelease(INITIALIZING);
} else {
VMError.guarantee(INIT_COUNT.get() <= 1, "Runtime.maxMemory() invariant");
VMError.guarantee(INIT_COUNT.get() <= INITIALIZING, "Runtime.maxMemory() invariant");
/*
* Once we know PhysicalMemory has been properly initialized we can use
* Runtime.maxMemory(). Note that we might end up in this branch for code explicitly
* using the JDK cgroups code. At that point PhysicalMemory has likely been
* initialized.
*/
INIT_COUNT.incrementAndGet();
INIT_COUNT.setRelease(INITIALIZED);
newDirectMemory = Runtime.getRuntime().maxMemory();
}
} else {
Expand All @@ -161,7 +163,7 @@ private static void initialize() {

Unsafe.getUnsafe().storeFence();
directMemory = newDirectMemory;
if (PhysicalMemory.isInitialized()) {
if (PhysicalMemory.isInitialized() && INITIALIZED == INIT_COUNT.get()) {
/*
* Complete initialization hand-shake once PhysicalMemory is properly initialized. Also
* set the VM init level to 1 so as to provoke the NIO code to re-set the internal
Expand Down

0 comments on commit 318f108

Please sign in to comment.