Merge
This commit is contained in:
commit
5b583e4792
@ -55,7 +55,9 @@ BUILD_JDK_JTREG_EXECUTABLES_CFLAGS_exeJliLaunchTest := \
|
|||||||
|
|
||||||
# Platform specific setup
|
# Platform specific setup
|
||||||
ifeq ($(call isTargetOs, windows), true)
|
ifeq ($(call isTargetOs, windows), true)
|
||||||
BUILD_JDK_JTREG_EXCLUDE += libDirectIO.c libInheritedChannel.c exelauncher.c
|
BUILD_JDK_JTREG_EXCLUDE += libDirectIO.c libInheritedChannel.c \
|
||||||
|
libExplicitAttach.c libImplicitAttach.c \
|
||||||
|
exelauncher.c
|
||||||
|
|
||||||
WIN_LIB_JAVA := $(SUPPORT_OUTPUTDIR)/native/java.base/libjava/java.lib
|
WIN_LIB_JAVA := $(SUPPORT_OUTPUTDIR)/native/java.base/libjava/java.lib
|
||||||
BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := $(WIN_LIB_JAVA)
|
BUILD_JDK_JTREG_LIBRARIES_LIBS_libstringPlatformChars := $(WIN_LIB_JAVA)
|
||||||
@ -84,6 +86,9 @@ else
|
|||||||
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libLinkerInvokerUnnamed := $(LIBCXX) -pthread
|
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libLinkerInvokerUnnamed := $(LIBCXX) -pthread
|
||||||
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libLinkerInvokerModule := $(LIBCXX) -pthread
|
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libLinkerInvokerModule := $(LIBCXX) -pthread
|
||||||
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libLoaderLookupInvoker := $(LIBCXX) -pthread
|
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libLoaderLookupInvoker := $(LIBCXX) -pthread
|
||||||
|
BUILD_JDK_JTREG_LIBRARIES_LIBS_libExplicitAttach := -ljvm
|
||||||
|
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libExplicitAttach := -pthread
|
||||||
|
BUILD_JDK_JTREG_LIBRARIES_LDFLAGS_libImplicitAttach := -pthread
|
||||||
BUILD_JDK_JTREG_EXCLUDE += exerevokeall.c
|
BUILD_JDK_JTREG_EXCLUDE += exerevokeall.c
|
||||||
ifeq ($(call isTargetOs, linux), true)
|
ifeq ($(call isTargetOs, linux), true)
|
||||||
BUILD_JDK_JTREG_LIBRARIES_LIBS_libInheritedChannel := -ljava
|
BUILD_JDK_JTREG_LIBRARIES_LIBS_libInheritedChannel := -ljava
|
||||||
|
@ -35,6 +35,7 @@
|
|||||||
#include "jfr/utilities/jfrTime.hpp"
|
#include "jfr/utilities/jfrTime.hpp"
|
||||||
#include "jfrfiles/jfrEventClasses.hpp"
|
#include "jfrfiles/jfrEventClasses.hpp"
|
||||||
#include "logging/log.hpp"
|
#include "logging/log.hpp"
|
||||||
|
#include "runtime/atomic.hpp"
|
||||||
#include "runtime/frame.inline.hpp"
|
#include "runtime/frame.inline.hpp"
|
||||||
#include "runtime/javaThread.inline.hpp"
|
#include "runtime/javaThread.inline.hpp"
|
||||||
#include "runtime/os.hpp"
|
#include "runtime/os.hpp"
|
||||||
@ -353,8 +354,8 @@ class JfrThreadSampler : public NonJavaThread {
|
|||||||
void run();
|
void run();
|
||||||
static Monitor* transition_block() { return JfrThreadSampler_lock; }
|
static Monitor* transition_block() { return JfrThreadSampler_lock; }
|
||||||
static void on_javathread_suspend(JavaThread* thread);
|
static void on_javathread_suspend(JavaThread* thread);
|
||||||
int64_t get_java_period() const { return _java_period_millis; };
|
int64_t get_java_period() const { return Atomic::load(&_java_period_millis); };
|
||||||
int64_t get_native_period() const { return _native_period_millis; };
|
int64_t get_native_period() const { return Atomic::load(&_native_period_millis); };
|
||||||
};
|
};
|
||||||
|
|
||||||
static void clear_transition_block(JavaThread* jt) {
|
static void clear_transition_block(JavaThread* jt) {
|
||||||
@ -417,12 +418,12 @@ JfrThreadSampler::~JfrThreadSampler() {
|
|||||||
|
|
||||||
void JfrThreadSampler::set_java_period(int64_t period_millis) {
|
void JfrThreadSampler::set_java_period(int64_t period_millis) {
|
||||||
assert(period_millis >= 0, "invariant");
|
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) {
|
void JfrThreadSampler::set_native_period(int64_t period_millis) {
|
||||||
assert(period_millis >= 0, "invariant");
|
assert(period_millis >= 0, "invariant");
|
||||||
_native_period_millis = period_millis;
|
Atomic::store(&_native_period_millis, period_millis);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline bool is_released(JavaThread* jt) {
|
static inline bool is_released(JavaThread* jt) {
|
||||||
@ -501,8 +502,17 @@ void JfrThreadSampler::run() {
|
|||||||
last_native_ms = last_java_ms;
|
last_native_ms = last_java_ms;
|
||||||
}
|
}
|
||||||
_sample.signal();
|
_sample.signal();
|
||||||
const int64_t java_period_millis = _java_period_millis == 0 ? max_jlong : MAX2<int64_t>(_java_period_millis, 1);
|
|
||||||
const int64_t native_period_millis = _native_period_millis == 0 ? max_jlong : MAX2<int64_t>(_native_period_millis, 1);
|
int64_t java_period_millis = get_java_period();
|
||||||
|
java_period_millis = java_period_millis == 0 ? max_jlong : MAX2<int64_t>(java_period_millis, 1);
|
||||||
|
int64_t native_period_millis = get_native_period();
|
||||||
|
native_period_millis = native_period_millis == 0 ? max_jlong : MAX2<int64_t>(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();
|
const int64_t now_ms = get_monotonic_ms();
|
||||||
|
|
||||||
@ -521,7 +531,7 @@ void JfrThreadSampler::run() {
|
|||||||
const int64_t sleep_to_next = MIN2<int64_t>(next_j, next_n);
|
const int64_t sleep_to_next = MIN2<int64_t>(next_j, next_n);
|
||||||
|
|
||||||
if (sleep_to_next > 0) {
|
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) {
|
if ((next_j - sleep_to_next) <= 0) {
|
||||||
|
@ -652,35 +652,39 @@ public class Thread implements Runnable {
|
|||||||
@SuppressWarnings("removal")
|
@SuppressWarnings("removal")
|
||||||
Thread(ThreadGroup g, String name, int characteristics, Runnable task,
|
Thread(ThreadGroup g, String name, int characteristics, Runnable task,
|
||||||
long stackSize, AccessControlContext acc) {
|
long stackSize, AccessControlContext acc) {
|
||||||
if (name == null) {
|
|
||||||
throw new InternalError("name cannot be null");
|
|
||||||
}
|
|
||||||
|
|
||||||
Thread parent = currentThread();
|
Thread parent = currentThread();
|
||||||
boolean attached = (parent == this); // primordial or JNI attached
|
boolean attached = (parent == this); // primordial or JNI attached
|
||||||
if (attached && g == null) {
|
|
||||||
throw new InternalError("group cannot be null when attaching");
|
|
||||||
}
|
|
||||||
|
|
||||||
SecurityManager security = System.getSecurityManager();
|
if (attached) {
|
||||||
if (g == null) {
|
|
||||||
// the security manager can choose the thread group
|
|
||||||
if (security != null) {
|
|
||||||
g = security.getThreadGroup();
|
|
||||||
}
|
|
||||||
|
|
||||||
// default to current thread's group
|
|
||||||
if (g == null) {
|
if (g == null) {
|
||||||
g = parent.getThreadGroup();
|
throw new InternalError("group cannot be null when attaching");
|
||||||
}
|
}
|
||||||
}
|
this.holder = new FieldHolder(g, task, stackSize, NORM_PRIORITY, false);
|
||||||
|
} else {
|
||||||
|
SecurityManager sm = System.getSecurityManager();
|
||||||
|
if (g == null) {
|
||||||
|
// the security manager can choose the thread group
|
||||||
|
if (sm != null) {
|
||||||
|
g = sm.getThreadGroup();
|
||||||
|
}
|
||||||
|
|
||||||
// permission checks when creating a child Thread
|
// default to current thread's group
|
||||||
if (!attached && security != null) {
|
if (g == null) {
|
||||||
security.checkAccess(g);
|
g = parent.getThreadGroup();
|
||||||
if (isCCLOverridden(getClass())) {
|
}
|
||||||
security.checkPermission(SecurityConstants.SUBCLASS_IMPLEMENTATION_PERMISSION);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// permission checks when creating a child Thread
|
||||||
|
if (sm != null) {
|
||||||
|
sm.checkAccess(g);
|
||||||
|
if (isCCLOverridden(getClass())) {
|
||||||
|
sm.checkPermission(SecurityConstants.SUBCLASS_IMPLEMENTATION_PERMISSION);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int priority = Math.min(parent.getPriority(), g.getMaxPriority());
|
||||||
|
this.holder = new FieldHolder(g, task, stackSize, priority, parent.isDaemon());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (attached && VM.initLevel() < 1) {
|
if (attached && VM.initLevel() < 1) {
|
||||||
@ -688,7 +692,8 @@ public class Thread implements Runnable {
|
|||||||
} else {
|
} else {
|
||||||
this.tid = ThreadIdentifiers.next();
|
this.tid = ThreadIdentifiers.next();
|
||||||
}
|
}
|
||||||
this.name = name;
|
this.name = (name != null) ? name : genThreadName();
|
||||||
|
|
||||||
if (acc != null) {
|
if (acc != null) {
|
||||||
this.inheritedAccessControlContext = acc;
|
this.inheritedAccessControlContext = acc;
|
||||||
} else {
|
} else {
|
||||||
@ -720,18 +725,6 @@ public class Thread implements Runnable {
|
|||||||
this.contextClassLoader = ClassLoader.getSystemClassLoader();
|
this.contextClassLoader = ClassLoader.getSystemClassLoader();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int priority;
|
|
||||||
boolean daemon;
|
|
||||||
if (attached) {
|
|
||||||
// primordial or attached thread
|
|
||||||
priority = NORM_PRIORITY;
|
|
||||||
daemon = false;
|
|
||||||
} else {
|
|
||||||
priority = Math.min(parent.getPriority(), g.getMaxPriority());
|
|
||||||
daemon = parent.isDaemon();
|
|
||||||
}
|
|
||||||
this.holder = new FieldHolder(g, task, stackSize, priority, daemon);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1153,7 +1146,7 @@ public class Thread implements Runnable {
|
|||||||
* @see <a href="#inheritance">Inheritance when creating threads</a>
|
* @see <a href="#inheritance">Inheritance when creating threads</a>
|
||||||
*/
|
*/
|
||||||
public Thread() {
|
public Thread() {
|
||||||
this(null, genThreadName(), 0, null, 0, null);
|
this(null, null, 0, null, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1174,7 +1167,7 @@ public class Thread implements Runnable {
|
|||||||
* @see <a href="#inheritance">Inheritance when creating threads</a>
|
* @see <a href="#inheritance">Inheritance when creating threads</a>
|
||||||
*/
|
*/
|
||||||
public Thread(Runnable task) {
|
public Thread(Runnable task) {
|
||||||
this(null, genThreadName(), 0, task, 0, null);
|
this(null, null, 0, task, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1183,7 +1176,7 @@ public class Thread implements Runnable {
|
|||||||
* This is not a public constructor.
|
* This is not a public constructor.
|
||||||
*/
|
*/
|
||||||
Thread(Runnable task, @SuppressWarnings("removal") AccessControlContext acc) {
|
Thread(Runnable task, @SuppressWarnings("removal") AccessControlContext acc) {
|
||||||
this(null, genThreadName(), 0, task, 0, acc);
|
this(null, null, 0, task, 0, acc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -1216,7 +1209,7 @@ public class Thread implements Runnable {
|
|||||||
* @see <a href="#inheritance">Inheritance when creating threads</a>
|
* @see <a href="#inheritance">Inheritance when creating threads</a>
|
||||||
*/
|
*/
|
||||||
public Thread(ThreadGroup group, Runnable task) {
|
public Thread(ThreadGroup group, Runnable task) {
|
||||||
this(group, genThreadName(), 0, task, 0, null);
|
this(group, null, 0, task, 0, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -39,27 +39,27 @@
|
|||||||
* <li><strong>Document Type Definition (DTD)</strong>
|
* <li><strong>Document Type Definition (DTD)</strong>
|
||||||
* - XML's built-in schema language.
|
* - XML's built-in schema language.
|
||||||
* </li>
|
* </li>
|
||||||
* <li><strong><a href="http://www.w3.org/XML/Schema">W3C XML Schema (WXS)</a></strong> -
|
* <li><strong><a href="https://www.w3.org/XML/Schema">W3C XML Schema (WXS)</a></strong> -
|
||||||
* an object-oriented XML schema language. WXS also provides a type system
|
* an object-oriented XML schema language. WXS also provides a type system
|
||||||
* for constraining the character data of an XML document. WXS is maintained
|
* for constraining the character data of an XML document. WXS is maintained
|
||||||
* by the <a href="http://www.w3.org">World Wide Web Consortium (W3C)</a>
|
* by the <a href="https://www.w3.org">World Wide Web Consortium (W3C)</a>
|
||||||
* and is a W3C Recommendation (that is, a ratified W3C standard specification).
|
* and is a W3C Recommendation (that is, a ratified W3C standard specification).
|
||||||
* </li>
|
* </li>
|
||||||
* <li><strong><a href="http://www.relaxng.org">RELAX NG (RNG)</a></strong> -
|
* <li><strong><a href="https://relaxng.org/">RELAX NG (RNG)</a></strong> -
|
||||||
* a pattern-based, user-friendly XML schema language. RNG schemas may
|
* a pattern-based, user-friendly XML schema language. RNG schemas may
|
||||||
* also use types to constrain XML character data. RNG is maintained by
|
* also use types to constrain XML character data. RNG is maintained by
|
||||||
* the <a href="http://www.oasis-open.org">Organization for the Advancement
|
* the <a href="https://www.oasis-open.org">Organization for the Advancement
|
||||||
* of Structured Information Standards (OASIS)</a> and is both an OASIS
|
* of Structured Information Standards (OASIS)</a> and is both an OASIS
|
||||||
* and an <a href="http://www.iso.org">ISO (International Organization
|
* and an <a href="https://www.iso.org/home.html">ISO (International Organization
|
||||||
* for Standardization)</a> standard.
|
* for Standardization)</a> standard.
|
||||||
* </li>
|
* </li>
|
||||||
* <li><strong><a href="http://standards.iso.org/ittf/PubliclyAvailableStandards/c055982_ISO_IEC_19757-3_2016.zip">Schematron</a></strong> -
|
* <li><strong><a href="https://standards.iso.org/ittf/PubliclyAvailableStandards/c055982_ISO_IEC_19757-3_2016.zip">Schematron</a></strong> -
|
||||||
* a rules-based XML schema language. Whereas DTD, WXS, and RNG are designed
|
* a rules-based XML schema language. Whereas DTD, WXS, and RNG are designed
|
||||||
* to express the structure of a content model, Schematron is designed to
|
* to express the structure of a content model, Schematron is designed to
|
||||||
* enforce individual rules that are difficult or impossible to express
|
* enforce individual rules that are difficult or impossible to express
|
||||||
* with other schema languages. Schematron is intended to supplement a
|
* with other schema languages. Schematron is intended to supplement a
|
||||||
* schema written in structural schema language such as the aforementioned.
|
* schema written in structural schema language such as the aforementioned.
|
||||||
* Schematron is <a href="http://standards.iso.org/ittf/PubliclyAvailableStandards/index.html">an ISO standard</a>.
|
* Schematron is <a href="https://standards.iso.org/ittf/PubliclyAvailableStandards/index.html">an ISO standard</a>.
|
||||||
* </li>
|
* </li>
|
||||||
* </ul>
|
* </ul>
|
||||||
* <p>
|
* <p>
|
||||||
|
@ -27,7 +27,6 @@ package jdk.incubator.concurrent;
|
|||||||
/**
|
/**
|
||||||
* Thrown when a structure violation is detected.
|
* Thrown when a structure violation is detected.
|
||||||
*
|
*
|
||||||
* @see StructuredTaskScope#fork(Callable)
|
|
||||||
* @see StructuredTaskScope#close()
|
* @see StructuredTaskScope#close()
|
||||||
*
|
*
|
||||||
* @since 19
|
* @since 19
|
||||||
|
@ -38,3 +38,5 @@ vmTestbase/nsk/jvmti/scenarios/sampling/SP07/sp07t002/TestDescription.java 82456
|
|||||||
vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java 8265295 linux-x64,windows-x64
|
vmTestbase/vm/mlvm/mixed/stress/regression/b6969574/INDIFY_Test.java 8265295 linux-x64,windows-x64
|
||||||
|
|
||||||
serviceability/jvmti/VMObjectAlloc/VMObjectAllocTest.java 8288430 generic-all
|
serviceability/jvmti/VMObjectAlloc/VMObjectAllocTest.java 8288430 generic-all
|
||||||
|
|
||||||
|
serviceability/jvmti/vthread/ContStackDepthTest/ContStackDepthTest.java 8288949 generic-all
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 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
|
||||||
|
* 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
|
||||||
|
* @bug 8287982
|
||||||
|
* @summary Test native threads attaching to the VM with JNI AttachCurrentThread
|
||||||
|
* @requires (os.family == "linux" | os.family == "mac")
|
||||||
|
* @library /test/lib
|
||||||
|
* @compile ExplicitAttach.java
|
||||||
|
* @run main AttachTest ExplicitAttach 1
|
||||||
|
* @run main AttachTest ExplicitAttach 2
|
||||||
|
* @run main AttachTest ExplicitAttach 4
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @test
|
||||||
|
* @summary Test native threads attaching implicitly to the VM by means of an upcall
|
||||||
|
* @requires (os.family == "linux" | os.family == "mac") & (sun.arch.data.model == "64")
|
||||||
|
* @library /test/lib
|
||||||
|
* @compile --enable-preview -source ${jdk.version} ImplicitAttach.java
|
||||||
|
* @run main AttachTest --enable-preview --enable-native-access=ALL-UNNAMED ImplicitAttach 1
|
||||||
|
* @run main AttachTest --enable-preview --enable-native-access=ALL-UNNAMED ImplicitAttach 2
|
||||||
|
* @run main AttachTest --enable-preview --enable-native-access=ALL-UNNAMED ImplicitAttach 4
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.stream.Stream;
|
||||||
|
import jdk.test.lib.process.ProcessTools;
|
||||||
|
import jdk.test.lib.process.OutputAnalyzer;
|
||||||
|
|
||||||
|
public class AttachTest {
|
||||||
|
static final String TEST_CLASSES = System.getProperty("test.classes");
|
||||||
|
static final String JAVA_LIBRARY_PATH = System.getProperty("java.library.path");
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
// prepend -cp ${test.classes} -Djava.library.path=${java.library.path}
|
||||||
|
String[] opts = Stream.concat(Stream.of(
|
||||||
|
"-cp", TEST_CLASSES,
|
||||||
|
"-Djava.library.path=" + JAVA_LIBRARY_PATH),
|
||||||
|
Stream.of(args))
|
||||||
|
.toArray(String[]::new);
|
||||||
|
OutputAnalyzer outputAnalyzer = ProcessTools
|
||||||
|
.executeTestJava(opts)
|
||||||
|
.outputTo(System.out)
|
||||||
|
.errorTo(System.out);
|
||||||
|
int exitValue = outputAnalyzer.getExitValue();
|
||||||
|
if (exitValue != 0)
|
||||||
|
throw new RuntimeException("Test failed");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 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
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test native threads attaching to the VM with JNI AttachCurrentThread.
|
||||||
|
*/
|
||||||
|
public class ExplicitAttach {
|
||||||
|
private static volatile CountDownLatch latch;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
int threadCount;
|
||||||
|
if (args.length > 0) {
|
||||||
|
threadCount = Integer.parseInt(args[0]);
|
||||||
|
} else {
|
||||||
|
threadCount = 2;
|
||||||
|
}
|
||||||
|
latch = new CountDownLatch(threadCount);
|
||||||
|
|
||||||
|
// start the threads and wait for the threads to call home
|
||||||
|
startThreads(threadCount);
|
||||||
|
latch.await();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoked by attached threads.
|
||||||
|
*/
|
||||||
|
private static void callback() {
|
||||||
|
System.out.println(Thread.currentThread());
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Start n native threads that attach to the VM and invoke callback.
|
||||||
|
*/
|
||||||
|
private static native void startThreads(int n);
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.loadLibrary("ExplicitAttach");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 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
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.lang.foreign.*;
|
||||||
|
import java.lang.invoke.MethodHandle;
|
||||||
|
import java.lang.invoke.MethodHandles;
|
||||||
|
import java.lang.invoke.MethodType;
|
||||||
|
import java.util.concurrent.CountDownLatch;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Test native threads attaching implicitly to the VM by means of an upcall.
|
||||||
|
*/
|
||||||
|
public class ImplicitAttach {
|
||||||
|
private static final ValueLayout.OfInt C_INT = ValueLayout.JAVA_INT.withBitAlignment(32);
|
||||||
|
private static final ValueLayout.OfAddress C_POINTER = ValueLayout.ADDRESS.withBitAlignment(64);
|
||||||
|
|
||||||
|
private static volatile CountDownLatch latch;
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Throwable {
|
||||||
|
int threadCount;
|
||||||
|
if (args.length > 0) {
|
||||||
|
threadCount = Integer.parseInt(args[0]);
|
||||||
|
} else {
|
||||||
|
threadCount = 2;
|
||||||
|
}
|
||||||
|
latch = new CountDownLatch(threadCount);
|
||||||
|
|
||||||
|
Linker abi = Linker.nativeLinker();
|
||||||
|
|
||||||
|
// stub to invoke callback
|
||||||
|
MethodHandle callback = MethodHandles.lookup()
|
||||||
|
.findStatic(ImplicitAttach.class, "callback", MethodType.methodType(void.class));
|
||||||
|
MemorySegment upcallStub = abi.upcallStub(callback,
|
||||||
|
FunctionDescriptor.ofVoid(),
|
||||||
|
MemorySession.openImplicit());
|
||||||
|
|
||||||
|
// void start_threads(int count, void *(*f)(void *))
|
||||||
|
SymbolLookup symbolLookup = SymbolLookup.loaderLookup();
|
||||||
|
MemorySegment symbol = symbolLookup.lookup("start_threads").orElseThrow();
|
||||||
|
FunctionDescriptor desc = FunctionDescriptor.ofVoid(C_INT, C_POINTER);
|
||||||
|
MethodHandle start_threads = abi.downcallHandle(symbol, desc);
|
||||||
|
|
||||||
|
// start the threads and wait for the threads to call home
|
||||||
|
start_threads.invoke(threadCount, upcallStub);
|
||||||
|
latch.await();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Invoked from native thread.
|
||||||
|
*/
|
||||||
|
private static void callback() {
|
||||||
|
System.out.println(Thread.currentThread());
|
||||||
|
latch.countDown();
|
||||||
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
System.loadLibrary("ImplicitAttach");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,90 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 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
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include "jni.h"
|
||||||
|
|
||||||
|
#define STACK_SIZE 0x100000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attach the current thread with JNI AttachCurrentThread, call a method, and detach.
|
||||||
|
*/
|
||||||
|
void* thread_main(void* arg) {
|
||||||
|
JavaVM *vm;
|
||||||
|
JNIEnv *env;
|
||||||
|
JavaVMInitArgs vm_args;
|
||||||
|
jsize count;
|
||||||
|
jint res;
|
||||||
|
|
||||||
|
res = JNI_GetCreatedJavaVMs(&vm, 1, &count);
|
||||||
|
if (res != JNI_OK) {
|
||||||
|
fprintf(stderr, "JNI_GetCreatedJavaVMs failed: %d\n", res);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
res = (*vm)->AttachCurrentThread(vm, (void **) &env, NULL);
|
||||||
|
if (res != JNI_OK) {
|
||||||
|
fprintf(stderr, "AttachCurrentThreadAsDaemon failed: %d\n", res);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// call ExplicitAttach.callback()
|
||||||
|
jclass clazz = (*env)->FindClass(env, "ExplicitAttach");
|
||||||
|
if (clazz == NULL) {
|
||||||
|
fprintf(stderr, "FindClass failed\n");
|
||||||
|
goto detach;
|
||||||
|
}
|
||||||
|
jmethodID mid = (*env)->GetStaticMethodID(env, clazz, "callback", "()V");
|
||||||
|
if (mid == NULL) {
|
||||||
|
fprintf(stderr, "GetStaticMethodID failed\n");
|
||||||
|
goto detach;
|
||||||
|
}
|
||||||
|
(*env)->CallStaticVoidMethod(env, clazz, mid);
|
||||||
|
if ((*env)->ExceptionOccurred(env)) {
|
||||||
|
fprintf(stderr, "CallStaticVoidMethod failed\n");
|
||||||
|
goto detach;
|
||||||
|
}
|
||||||
|
|
||||||
|
detach:
|
||||||
|
res = (*vm)->DetachCurrentThread(vm);
|
||||||
|
if (res != JNI_OK) {
|
||||||
|
fprintf(stderr, "DetachCurrentThread failed: %d\n", res);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT void JNICALL Java_ExplicitAttach_startThreads(JNIEnv *env, jclass clazz, int n) {
|
||||||
|
pthread_t tid;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setstacksize(&attr, STACK_SIZE);
|
||||||
|
for (i = 0; i < n ; i++) {
|
||||||
|
int res = pthread_create(&tid, &attr, thread_main, NULL);
|
||||||
|
if (res != 0) {
|
||||||
|
fprintf(stderr, "pthread_create failed: %d\n", res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,44 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 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
|
||||||
|
* 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.
|
||||||
|
*/
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
|
||||||
|
#define STACK_SIZE 0x100000
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates n threads to execute the given function.
|
||||||
|
*/
|
||||||
|
void start_threads(int n, void *(*f)(void *)) {
|
||||||
|
pthread_t tid;
|
||||||
|
pthread_attr_t attr;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
pthread_attr_init(&attr);
|
||||||
|
pthread_attr_setstacksize(&attr, STACK_SIZE);
|
||||||
|
for (i = 0; i < n ; i++) {
|
||||||
|
int res = pthread_create(&tid, &attr, f, NULL);
|
||||||
|
if (res != 0) {
|
||||||
|
fprintf(stderr, "pthread_create failed: %d\n", res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* 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;
|
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 {
|
public static void main(String[] args) throws Exception {
|
||||||
try (RecordingStream rs = new RecordingStream()) {
|
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 -> {
|
rs.onEvent(NATIVE_EVENT, e -> {
|
||||||
alive = false;
|
alive = false;
|
||||||
rs.close();
|
rs.close();
|
||||||
|
Loading…
Reference in New Issue
Block a user