Skip to content

Commit c2413f9

Browse files
Don't emit internal park events. Test.
1 parent 4f61e16 commit c2413f9

File tree

2 files changed

+136
-0
lines changed

2 files changed

+136
-0
lines changed

substratevm/src/com.oracle.svm.core/src/com/oracle/svm/core/jfr/events/ThreadParkEvent.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,21 @@
3737
import com.oracle.svm.core.jfr.JfrNativeEventWriterDataAccess;
3838
import com.oracle.svm.core.jfr.JfrTicks;
3939
import com.oracle.svm.core.jfr.SubstrateJVM;
40+
import com.oracle.svm.core.monitor.JavaMonitor;
4041

4142
public class ThreadParkEvent {
4243
public static void emit(long startTicks, Object obj, boolean isAbsolute, long time) {
4344
if (HasJfrSupport.get()) {
45+
/*
46+
* Skip emission if corresponding JavaMonitorWait or JavaMonitorEnter events are already
47+
* emitted (this is an internal park).
48+
*/
49+
if (obj != null) {
50+
Class<?> clazz = obj.getClass();
51+
if (clazz.equals(JavaMonitor.class) || (clazz.getEnclosingClass() != null && clazz.getEnclosingClass().isAssignableFrom(JavaMonitor.class))) {
52+
return;
53+
}
54+
}
4455
emit0(startTicks, obj, isAbsolute, time);
4556
}
4657
}
Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
/*
2+
* Copyright (c) 2022, 2022, Oracle and/or its affiliates. All rights reserved.
3+
* Copyright (c) 2022, 2022, Red Hat Inc. All rights reserved.
4+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5+
*
6+
* This code is free software; you can redistribute it and/or modify it
7+
* under the terms of the GNU General Public License version 2 only, as
8+
* published by the Free Software Foundation. Oracle designates this
9+
* particular file as subject to the "Classpath" exception as provided
10+
* by Oracle in the LICENSE file that accompanied this code.
11+
*
12+
* This code is distributed in the hope that it will be useful, but WITHOUT
13+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
15+
* version 2 for more details (a copy is included in the LICENSE file that
16+
* accompanied this code).
17+
*
18+
* You should have received a copy of the GNU General Public License version
19+
* 2 along with this work; if not, write to the Free Software Foundation,
20+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
21+
*
22+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
23+
* or visit www.oracle.com if you need additional information or have any
24+
* questions.
25+
*/
26+
27+
package com.oracle.svm.test.jfr;
28+
29+
import com.oracle.svm.core.jfr.JfrEvent;
30+
import jdk.jfr.Recording;
31+
import jdk.jfr.consumer.RecordedClass;
32+
import jdk.jfr.consumer.RecordedEvent;
33+
import org.junit.Test;
34+
35+
import java.util.List;
36+
import java.util.concurrent.locks.LockSupport;
37+
38+
import static org.junit.Assert.assertFalse;
39+
import static org.junit.Assert.assertTrue;
40+
41+
public class TestOmitInternalParkEvents extends JfrRecordingTest {
42+
private static final int MILLIS = 500;
43+
private final Helper helper = new Helper();
44+
private Thread firstThread;
45+
private Thread secondThread;
46+
private volatile boolean passedCheckpoint;
47+
48+
@Test
49+
public void test() throws Throwable {
50+
String[] events = new String[]{JfrEvent.JavaMonitorEnter.getName(), JfrEvent.JavaMonitorWait.getName(), JfrEvent.ThreadPark.getName()};
51+
Recording recording = startRecording(events);
52+
53+
// Generate monitor enter events
54+
Runnable first = () -> {
55+
try {
56+
helper.doWork();
57+
} catch (InterruptedException e) {
58+
throw new RuntimeException(e);
59+
}
60+
};
61+
62+
Runnable second = () -> {
63+
try {
64+
passedCheckpoint = true;
65+
helper.doWork();
66+
} catch (InterruptedException e) {
67+
throw new RuntimeException(e);
68+
}
69+
};
70+
firstThread = new Thread(first);
71+
secondThread = new Thread(second);
72+
73+
firstThread.start();
74+
75+
firstThread.join();
76+
secondThread.join();
77+
78+
// Generate monitor wait events
79+
try {
80+
helper.timeout();
81+
} catch (InterruptedException e) {
82+
org.junit.Assert.fail(e.getMessage());
83+
}
84+
85+
// Generate thread park events
86+
LockSupport.parkNanos(this, MILLIS);
87+
88+
stopRecording(recording, this::validateEvents);
89+
}
90+
91+
private void validateEvents(List<RecordedEvent> events) {
92+
boolean found = false;
93+
for (RecordedEvent event : events) {
94+
if (event.getEventType().getName().equals(JfrEvent.ThreadPark.getName())) {
95+
RecordedClass parkedClass = event.getValue("parkedClass");
96+
if (parkedClass != null) {
97+
String parkedClassName = parkedClass.getName();
98+
assertFalse(parkedClassName.contains("com.oracle.svm.core.monitor"));
99+
found = true;
100+
}
101+
}
102+
}
103+
assertTrue("Expected jdk.ThreadPark event not found", found);
104+
}
105+
106+
private final class Helper {
107+
private synchronized void doWork() throws InterruptedException {
108+
if (Thread.currentThread().equals(secondThread)) {
109+
return; // second thread doesn't need to do work.
110+
}
111+
// ensure ordering of critical section entry
112+
secondThread.start();
113+
114+
// spin until second thread blocks
115+
while (!secondThread.getState().equals(Thread.State.BLOCKED) || !passedCheckpoint) {
116+
Thread.sleep(100);
117+
}
118+
Thread.sleep(MILLIS);
119+
}
120+
121+
private synchronized void timeout() throws InterruptedException {
122+
wait(MILLIS);
123+
}
124+
}
125+
}

0 commit comments

Comments
 (0)