From 30b23484452a1090502fecba22f8776ed8db3a8f Mon Sep 17 00:00:00 2001 From: duke Date: Thu, 22 Feb 2024 09:54:43 +0000 Subject: [PATCH] Backport 6037ccdd50acd5424a46120028738b811dff064a --- .../periodic/sampling/jfrThreadSampler.cpp | 24 +++++++++++++------ .../jdk/jfr/event/sampling/TestNative.java | 7 ++++-- 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp index 1422287506b..a95cccf1a5c 100644 --- a/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp +++ b/src/hotspot/share/jfr/periodic/sampling/jfrThreadSampler.cpp @@ -34,6 +34,7 @@ #include "jfr/utilities/jfrTime.hpp" #include "jfrfiles/jfrEventClasses.hpp" #include "logging/log.hpp" +#include "runtime/atomic.hpp" #include "runtime/frame.inline.hpp" #include "runtime/os.hpp" #include "runtime/semaphore.hpp" @@ -350,8 +351,8 @@ class JfrThreadSampler : public NonJavaThread { void run(); static Monitor* transition_block() { return JfrThreadSampler_lock; } static void on_javathread_suspend(JavaThread* thread); - int64_t get_java_period() const { return _java_period_millis; }; - int64_t get_native_period() const { return _native_period_millis; }; + int64_t get_java_period() const { return Atomic::load(&_java_period_millis); }; + int64_t get_native_period() const { return Atomic::load(&_native_period_millis); }; }; static void clear_transition_block(JavaThread* jt) { @@ -412,12 +413,12 @@ JfrThreadSampler::~JfrThreadSampler() { void JfrThreadSampler::set_java_period(int64_t period_millis) { assert(period_millis >= 0, "invariant"); - _java_period_millis = period_millis; + Atomic::store(&_java_period_millis, period_millis); } void JfrThreadSampler::set_native_period(int64_t period_millis) { assert(period_millis >= 0, "invariant"); - _native_period_millis = period_millis; + Atomic::store(&_native_period_millis, period_millis); } static inline bool is_released(JavaThread* jt) { @@ -496,8 +497,17 @@ void JfrThreadSampler::run() { last_native_ms = last_java_ms; } _sample.signal(); - const int64_t java_period_millis = _java_period_millis == 0 ? max_jlong : MAX2(_java_period_millis, 1); - const int64_t native_period_millis = _native_period_millis == 0 ? max_jlong : MAX2(_native_period_millis, 1); + + int64_t java_period_millis = get_java_period(); + java_period_millis = java_period_millis == 0 ? max_jlong : MAX2(java_period_millis, 1); + int64_t native_period_millis = get_native_period(); + native_period_millis = native_period_millis == 0 ? max_jlong : MAX2(native_period_millis, 1); + + // If both periods are max_jlong, it implies the sampler is in the process of + // disenrolling. Loop back for graceful disenroll by means of the semaphore. + if (java_period_millis == max_jlong && native_period_millis == max_jlong) { + continue; + } const int64_t now_ms = get_monotonic_ms(); @@ -516,7 +526,7 @@ void JfrThreadSampler::run() { const int64_t sleep_to_next = MIN2(next_j, next_n); if (sleep_to_next > 0) { - os::naked_short_sleep(sleep_to_next); + os::naked_sleep(sleep_to_next); } if ((next_j - sleep_to_next) <= 0) { diff --git a/test/jdk/jdk/jfr/event/sampling/TestNative.java b/test/jdk/jdk/jfr/event/sampling/TestNative.java index 2e8753d4ea4..66640c2fbd5 100644 --- a/test/jdk/jdk/jfr/event/sampling/TestNative.java +++ b/test/jdk/jdk/jfr/event/sampling/TestNative.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2017, 2020, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2017, 2022, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -48,9 +48,12 @@ public class TestNative { static volatile boolean alive = true; + // Please resist the temptation to speed up the test by decreasing + // the period. It is explicity set to 1100 ms to provoke the 1000 ms + // threshold in the JVM for os::naked_short_sleep(). public static void main(String[] args) throws Exception { try (RecordingStream rs = new RecordingStream()) { - rs.enable(NATIVE_EVENT).withPeriod(Duration.ofMillis(1)); + rs.enable(NATIVE_EVENT).withPeriod(Duration.ofMillis(1100)); rs.onEvent(NATIVE_EVENT, e -> { alive = false; rs.close();