From dbf5d9c526aff117345a886e8fc9cd7aee217cf8 Mon Sep 17 00:00:00 2001 From: Christian Haeubl Date: Wed, 25 Jun 2025 10:26:12 +0200 Subject: [PATCH] Recurring callback fixes. --- .../oracle/svm/core/thread/RecurringCallbackSupport.java | 5 ++++- .../com/oracle/svm/core/thread/SafepointCheckCounter.java | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/RecurringCallbackSupport.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/RecurringCallbackSupport.java index 169d311fefe2..8538404e615e 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/RecurringCallbackSupport.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/RecurringCallbackSupport.java @@ -353,6 +353,10 @@ private void maybeExecuteCallback() { /* * Before executing the callback, reset the safepoint requested counter as we * don't want to trigger another callback execution in the near future. + * + * Recurring callbacks typically execute VM-internal code that performs hardly + * any safepoint checks. We explicitly don't update the recurring callback + * statistics anywhere in this method as this could skew the numbers. */ setCounter(SafepointCheckCounter.MAX_VALUE); try { @@ -364,7 +368,6 @@ private void maybeExecuteCallback() { */ } finally { lastCallbackExecution = System.nanoTime(); - updateStatistics(); } } } finally { diff --git a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/SafepointCheckCounter.java b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/SafepointCheckCounter.java index dc4869046812..3db240da4417 100644 --- a/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/SafepointCheckCounter.java +++ b/substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/thread/SafepointCheckCounter.java @@ -62,8 +62,11 @@ */ public class SafepointCheckCounter { private static final FastThreadLocalInt valueTL = FastThreadLocalFactory.createInt("SafepointCheckCounter.value").setMaxOffset(FastThreadLocal.FIRST_CACHE_LINE); - /** Can be used to reset the thread-local value after a safepoint. */ - static final int MAX_VALUE = Integer.MAX_VALUE; + /** + * Can be used to reset the thread-local value after a safepoint. We explicitly keep some + * distance to {@link Integer#MAX_VALUE} to avoid corner cases. + */ + static final int MAX_VALUE = Integer.MAX_VALUE >>> 1; @Uninterruptible(reason = CALLED_FROM_UNINTERRUPTIBLE_CODE, mayBeInlined = true) static boolean compareAndSet(IsolateThread thread, int oldValue, int newValue) {