Skip to content
This repository has been archived by the owner on Oct 23, 2024. It is now read-only.

Commit

Permalink
Merge upstream-jdk
Browse files Browse the repository at this point in the history
  • Loading branch information
corretto-github-robot committed Apr 18, 2024
2 parents f5c8e3b + 1188d40 commit 347d904
Show file tree
Hide file tree
Showing 10 changed files with 112 additions and 22 deletions.
19 changes: 4 additions & 15 deletions src/hotspot/os_cpu/linux_riscv/atomic_linux_riscv.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,10 @@

#if defined(__clang_major__)
#define FULL_COMPILER_ATOMIC_SUPPORT
#elif (__GNUC__ > 13) || ((__GNUC__ == 13) && (__GNUC_MINOR__ >= 2))
#elif (__GNUC__ > 13) || ((__GNUC__ == 13) && (__GNUC_MINOR__ > 2))
#define FULL_COMPILER_ATOMIC_SUPPORT
#endif

#if defined(__clang_major__)
#define CORRECT_COMPILER_ATOMIC_SUPPORT
#elif defined(__GNUC__) && (__riscv_xlen <= 32 || __GNUC__ > 13)
#define CORRECT_COMPILER_ATOMIC_SUPPORT
#endif

template<size_t byte_size>
struct Atomic::PlatformAdd {
template<typename D, typename I>
Expand Down Expand Up @@ -120,9 +114,9 @@ inline T Atomic::PlatformCmpxchg<1>::operator()(T volatile* dest __attribute__((
}
#endif

#ifndef CORRECT_COMPILER_ATOMIC_SUPPORT
#ifndef FULL_COMPILER_ATOMIC_SUPPORT
// The implementation of `__atomic_compare_exchange` lacks sign extensions
// in GCC 13 and lower when using with 32-bit unsigned integers on RV64,
// in GCC 13.2 and lower when using with 32-bit unsigned integers on RV64,
// so we should implement it manually.
// GCC bug: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=114130.
// See also JDK-8326936.
Expand Down Expand Up @@ -192,11 +186,7 @@ inline T Atomic::PlatformCmpxchg<byte_size>::operator()(T volatile* dest __attri
atomic_memory_order order) const {

#ifndef FULL_COMPILER_ATOMIC_SUPPORT
STATIC_ASSERT(byte_size >= 4);
#endif

#ifndef CORRECT_COMPILER_ATOMIC_SUPPORT
STATIC_ASSERT(byte_size != 4);
STATIC_ASSERT(byte_size > 4);
#endif

STATIC_ASSERT(byte_size == sizeof(T));
Expand Down Expand Up @@ -235,6 +225,5 @@ struct Atomic::PlatformOrderedStore<byte_size, RELEASE_X_FENCE>
};

#undef FULL_COMPILER_ATOMIC_SUPPORT
#undef CORRECT_COMPILER_ATOMIC_SUPPORT

#endif // OS_CPU_LINUX_RISCV_ATOMIC_LINUX_RISCV_HPP
2 changes: 2 additions & 0 deletions src/hotspot/share/jfr/instrumentation/jfrJvmtiAgent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,8 @@ void JfrJvmtiAgent::retransform_classes(JNIEnv* env, jobjectArray classes_array,
return;
}
ResourceMark rm(THREAD);
// WXWrite is needed before entering the vm below and in callee methods.
MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, THREAD));
jclass* const classes = create_classes_array(classes_count, CHECK);
assert(classes != nullptr, "invariant");
for (jint i = 0; i < classes_count; i++) {
Expand Down
4 changes: 3 additions & 1 deletion src/hotspot/share/jfr/jni/jfrJniMethod.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,9 @@ NO_TRANSITION_END
NO_TRANSITION(void, jfr_set_enabled(JNIEnv* env, jclass jvm, jlong event_type_id, jboolean enabled))
JfrEventSetting::set_enabled(event_type_id, JNI_TRUE == enabled);
if (EventOldObjectSample::eventId == event_type_id) {
ThreadInVMfromNative transition(JavaThread::thread_from_jni_environment(env));
JavaThread* thread = JavaThread::thread_from_jni_environment(env);
MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, thread));
ThreadInVMfromNative transition(thread);
if (JNI_TRUE == enabled) {
LeakProfiler::start(JfrOptionSet::old_object_queue_size());
} else {
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/jfr/recorder/storage/jfrStorage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ void JfrStorage::register_full(BufferPtr buffer, Thread* thread) {
JavaThread* jt = JavaThread::cast(thread);
if (jt->thread_state() == _thread_in_native) {
// Transition java thread to vm so it can issue a notify.
MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, jt));
ThreadInVMfromNative transition(jt);
_post_box.post(MSG_FULLBUFFER);
return;
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/jfr/support/jfrIntrinsics.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ void* JfrIntrinsicSupport::write_checkpoint(JavaThread* jt) {
assert(JfrThreadLocal::is_vthread(jt), "invariant");
const u2 vthread_thread_local_epoch = JfrThreadLocal::vthread_epoch(jt);
const u2 current_epoch = ThreadIdAccess::current_epoch();
MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, jt));
if (vthread_thread_local_epoch == current_epoch) {
// After the epoch test in the intrinsic, the thread sampler interleaved
// and suspended the thread. As part of taking a sample, it updated
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/jfr/writers/jfrJavaEventWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ void JfrJavaEventWriter::flush(jobject writer, jint used, jint requested, JavaTh
u1* const new_current_position = is_valid ? buffer->pos() + used : buffer->pos();
assert(start_pos_offset != invalid_offset, "invariant");
// can safepoint here
MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, jt));
ThreadInVMfromNative transition(jt);
oop const w = JNIHandles::resolve_non_null(writer);
assert(w != nullptr, "invariant");
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/prims/jvmtiExport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,7 @@ JvmtiExport::get_jvmti_interface(JavaVM *jvm, void **penv, jint version) {
if (JvmtiEnv::get_phase() == JVMTI_PHASE_LIVE) {
JavaThread* current_thread = JavaThread::current();
// transition code: native to VM
MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, current_thread));
ThreadInVMfromNative __tiv(current_thread);
VM_ENTRY_BASE(jvmtiEnv*, JvmtiExport::get_jvmti_interface, current_thread)
debug_only(VMNativeEntryWrapper __vew;)
Expand Down
1 change: 1 addition & 0 deletions src/hotspot/share/prims/jvmtiExtensions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ static jvmtiError JNICALL GetCarrierThread(const jvmtiEnv* env, ...) {
thread_ptr = va_arg(ap, jthread*);
va_end(ap);

MACOS_AARCH64_ONLY(ThreadWXEnable __wx(WXWrite, current_thread));
ThreadInVMfromNative tiv(current_thread);
JvmtiVTMSTransitionDisabler disabler;

Expand Down
13 changes: 7 additions & 6 deletions src/java.base/share/classes/java/lang/Thread.java
Original file line number Diff line number Diff line change
Expand Up @@ -1697,20 +1697,21 @@ public final void stop() {
public void interrupt() {
if (this != Thread.currentThread()) {
checkAccess();
}

// Setting the interrupt status must be done before reading nioBlocker.
interrupted = true;
interrupt0(); // inform VM of interrupt

// thread may be blocked in an I/O operation
// thread may be blocked in an I/O operation
if (this != Thread.currentThread()) {
synchronized (interruptLock) {
Interruptible b = nioBlocker;
if (b != null) {
interrupted = true;
interrupt0(); // inform VM of interrupt
b.interrupt(this);
return;
}
}
}
interrupted = true;
interrupt0(); // inform VM of interrupt
}

/**
Expand Down
91 changes: 91 additions & 0 deletions test/jdk/java/nio/channels/Selector/LotsOfInterrupts.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
/*
* Copyright (c) 2024, 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
* 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.
*/

/*
* @test id=platform
* @bug 8323782
* @summary Stress test Thread.interrupt on a target Thread doing a selection operation
* @run main LotsOfInterrupts 200000
*/

/*
* @test id=virtual
* @run main/othervm -DthreadFactory=virtual LotsOfInterrupts 200000
*/

import java.nio.channels.Selector;
import java.time.Instant;
import java.util.concurrent.Phaser;
import java.util.concurrent.ThreadFactory;

public class LotsOfInterrupts {

public static void main(String[] args) throws Exception {
int iterations;
if (args.length > 0) {
iterations = Integer.parseInt(args[0]);
} else {
iterations = 500_000;
}

ThreadFactory factory;
String value = System.getProperty("threadFactory");
if ("virtual".equals(value)) {
factory = Thread.ofVirtual().factory();
} else {
factory = Thread.ofPlatform().factory();
}

var phaser = new Phaser(2);

Thread thread = factory.newThread(() -> {
try (Selector sel = Selector.open()) {
for (int i = 0; i < iterations; i++) {
phaser.arriveAndAwaitAdvance();
sel.select();

// clear interrupt status and consume wakeup
Thread.interrupted();
sel.selectNow();
}
} catch (Throwable ex) {
ex.printStackTrace();
}
});
thread.start();

long lastTimestamp = System.currentTimeMillis();
for (int i = 0; i < iterations; i++) {
phaser.arriveAndAwaitAdvance();
thread.interrupt();

long currentTime = System.currentTimeMillis();
if ((currentTime - lastTimestamp) > 500) {
System.out.format("%s %d iterations remaining ...%n", Instant.now(), (iterations - i));
lastTimestamp = currentTime;
}
}

thread.join();
}
}

0 comments on commit 347d904

Please sign in to comment.