From 318f1083a75735a19f162f586ff2f815a771b1b1 Mon Sep 17 00:00:00 2001 From: Severin Gehwolf Date: Wed, 4 Oct 2023 18:37:11 +0200 Subject: [PATCH] Fix race with double init --- .../com/oracle/svm/core/heap/PhysicalMemory.java | 2 +- .../core/jdk/Target_jdk_internal_misc_VM.java | 16 +++++++++------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/PhysicalMemory.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/PhysicalMemory.java index fc557390a017..8b4663ab0ef1 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/PhysicalMemory.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/heap/PhysicalMemory.java @@ -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!"); diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_jdk_internal_misc_VM.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_jdk_internal_misc_VM.java index c14c745afed4..058880077c5c 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_jdk_internal_misc_VM.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jdk/Target_jdk_internal_misc_VM.java @@ -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; @@ -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; } @@ -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 { @@ -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