Skip to content

Commit 90449d3

Browse files
committed
Add missing exclusive access for thread iteration
Acquire exclusive when allocating the local JFR buffers so if any new threads are created in this period they must wait for the iteration to complete. After the iteration is complete the thread creation hook is added so new threads will trigger that. Also instead of requesting threadCPU sample on the requestor thread, trigger the async check so threadCPU is captured on all threads. Signed-off-by: Tobi Ajila <atobia@ca.ibm.com>
1 parent 16776fb commit 90449d3

6 files changed

Lines changed: 44 additions & 5 deletions

File tree

runtime/jcl/common/com_ibm_oti_vm_VM.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,9 @@ Java_com_ibm_oti_vm_VM_startJFR(JNIEnv *env, jclass unused)
262262

263263
if (!vmFuncs->isJFRRecordingStarted(vm)) {
264264
/* this is to initalize JFR late after VM startup */
265+
vmFuncs->internalEnterVMFromJNI(currentThread);
265266
rc = vmFuncs->initializeJFR(vm);
267+
vmFuncs->internalExitVMToJNI(currentThread);
266268
}
267269

268270
return rc;

runtime/jcl/common/jdk_jfr_internal_JVM_common.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,7 @@ Java_jdk_jfr_internal_JVM_createJFR(JNIEnv *env, jobject obj, jboolean simulateF
377377
vmFuncs->internalEnterVMFromJNI(currentThread);
378378
if (JNI_OK != vmFuncs->initializeJFR(vm)) {
379379
rc = JNI_FALSE;
380+
goto done;
380381
}
381382

382383
if (!vm->internalVMFunctions->setupChunkMonitor(currentThread)) {

runtime/vm/jfr.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -950,7 +950,9 @@ initializeJFR(J9JavaVM *vm)
950950

951951
U_8 *buffer = NULL;
952952
UDATA timeSuccess = 0;
953+
J9VMThread *currentThread = currentVMThread(vm);
953954
J9VMThread *walkThread = NULL;
955+
J9HookInterface **vmHooks = getVMHookInterface(vm);
954956

955957
Assert_VM_false(vm->jfrState.isCreated);
956958

@@ -1031,6 +1033,7 @@ initializeJFR(J9JavaVM *vm)
10311033
goto fail;
10321034
}
10331035

1036+
acquireExclusiveVMAccess(currentThread);
10341037
/* Go through existing threads. */
10351038
walkThread = J9_LINKED_LIST_START_DO(vm->mainThread);
10361039
while (NULL != walkThread) {
@@ -1050,6 +1053,12 @@ initializeJFR(J9JavaVM *vm)
10501053
walkThread = J9_LINKED_LIST_NEXT_DO(vm->mainThread, walkThread);
10511054
}
10521055

1056+
if ((*vmHooks)->J9HookRegisterWithCallSite(vmHooks, J9HOOK_VM_THREAD_CREATED, jfrThreadCreated, OMR_GET_CALLSITE(), NULL)) {
1057+
goto done;
1058+
}
1059+
1060+
releaseExclusiveVMAccess(currentThread);
1061+
10531062
vm->jfrState.isCreated = TRUE;
10541063

10551064
if (!isJFRV2SupportEnabled(vm)) {
@@ -2216,7 +2225,8 @@ JfrPeriodicEventSet::requestCPULoad(J9VMThread *currentThread)
22162225
void
22172226
JfrPeriodicEventSet::requestThreadCPULoad(J9VMThread *currentThread)
22182227
{
2219-
jfrThreadCPULoad(currentThread, currentThread);
2228+
J9JavaVM *vm = currentThread->javaVM;
2229+
J9SignalAsyncEvent(vm, NULL, vm->jfrThreadCPULoadAsyncKey);
22202230
}
22212231

22222232
void

test/functional/cmdLineTests/jfr/jfrV2.xml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,4 +107,30 @@ SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0-only WITH Classpath-ex
107107
<output type="failure" caseSensitive="yes" regex="no">Found additional fields in mirror class</output>
108108
<output type="failure" caseSensitive="yes" regex="no">Error</output>
109109
</test>
110+
<test id="test jfr summary - approx 5 seconds">
111+
<command>$JFR_EXE$ summary testrecording.jfr</command>
112+
<output type="required" caseSensitive="yes" regex="no">Version: 2.1</output>
113+
<output type="required" caseSensitive="yes" regex="no">jdk.ExecutionSample</output>
114+
<output type="success" caseSensitive="yes" regex="no">jdk.CPULoad</output>
115+
<output type="success" caseSensitive="yes" regex="no">jdk.JavaThreadStatistics</output>
116+
<output type="success" caseSensitive="yes" regex="no">jdk.ClassLoadingStatistics</output>
117+
<output type="success" caseSensitive="yes" regex="no">jdk.ThreadCPULoad</output>
118+
<output type="required" caseSensitive="yes" regex="no">jdk.Metadata</output>
119+
</test>
120+
<test id="test jfr execution sample - approx 5 seconds">
121+
<command>$JFR_EXE$ print --xml --events "ExecutionSample" --stack-depth 1 testrecording.jfr</command>
122+
<output type="required" caseSensitive="yes" regex="no">http://www.w3.org/2001/XMLSchema-instance</output>
123+
<output type="required" caseSensitive="yes" regex="no">jdk.ExecutionSample</output>
124+
<output type="required" caseSensitive="yes" regex="no">startTime</output>
125+
<output type="required" caseSensitive="yes" regex="no">sampledThread</output>
126+
<output type="required" caseSensitive="yes" regex="no">stackTrace</output>
127+
<output type="required" caseSensitive="yes" regex="no">frames</output>
128+
<output type="success" caseSensitive="yes" regex="no">STATE_RUNNABLE</output>
129+
<output type="failure" caseSensitive="yes" regex="no">jfr print: could not read recording</output>
130+
</test>
131+
<test id="Test JFRv2 with profile config">
132+
<command>$EXE$ -XX:+EnableOpenJ9ExperimentalFlightRecording -XX:StartFlightRecording:filename=profile.jfr,dumponexit=true,settings=profile.jfc --add-opens jdk.jfr/jdk.jfr.internal=ALL-UNNAMED -cp $RESJAR$ org.openj9.test.WorkLoad</command>
133+
<output type="success" caseSensitive="yes" regex="no">All runs complete</output>
134+
<output type="required" caseSensitive="yes" regex="no">0 / 100 complete</output>
135+
</test>
110136
</suite>

test/functional/cmdLineTests/jfr/src/org/openj9/test/VMAPITest.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@
2525

2626
public class VMAPITest {
2727
public static void main(String[] args) throws Throwable {
28-
final WorkLoad workLoad = new WorkLoad(200, 20000, 200, false);
29-
int sleepDuration = 1000;
28+
final WorkLoad workLoad = new WorkLoad(50, 2000, 20, false);
29+
int sleepDuration = 2000;
3030

3131
if (args.length > 1) {
3232
sleepDuration = Integer.parseInt(args[0]);
@@ -42,7 +42,7 @@ public static void main(String[] args) throws Throwable {
4242
});
4343
app.start();
4444

45-
for (int i = 0; i < 15; i++) {
45+
for (int i = 0; i < 10; i++) {
4646
Thread.sleep(100);
4747

4848
if (VM.startJFR() != 0) {

test/functional/cmdLineTests/jfr/src/org/openj9/test/VMAPITest2.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
public class VMAPITest2 {
2727
public static void main(String[] args) throws Throwable {
28-
final WorkLoad workLoad = new WorkLoad(200, 20000, 200, false);
28+
final WorkLoad workLoad = new WorkLoad(50, 2000, 20, false);
2929

3030
Thread app = new Thread(() -> {
3131
workLoad.runWork();

0 commit comments

Comments
 (0)