提交 64211239 编写于 作者: E egahlin

8165675: Trace event for thread park has incorrect unit for timeout

Reviewed-by: mgronlun
上级 501d313d
...@@ -726,6 +726,9 @@ public class RecordedObject { ...@@ -726,6 +726,9 @@ public class RecordedObject {
private Duration getDuration(long timespan, String name) throws InternalError { private Duration getDuration(long timespan, String name) throws InternalError {
ValueDescriptor v = getValueDescriptor(descriptors, name, null); ValueDescriptor v = getValueDescriptor(descriptors, name, null);
if (timespan == Long.MIN_VALUE) {
return Duration.ofSeconds(Long.MIN_VALUE, 0);
}
Timespan ts = v.getAnnotation(Timespan.class); Timespan ts = v.getAnnotation(Timespan.class);
if (ts != null) { if (ts != null) {
switch (ts.value()) { switch (ts.value()) {
...@@ -797,13 +800,16 @@ public class RecordedObject { ...@@ -797,13 +800,16 @@ public class RecordedObject {
return getInstant(Short.toUnsignedLong((Byte) u), name); return getInstant(Short.toUnsignedLong((Byte) u), name);
} }
} }
throw newIllegalArgumentException(name, "java,time.Instant"); throw newIllegalArgumentException(name, "java.time.Instant");
} }
private Instant getInstant(long timestamp, String name) { private Instant getInstant(long timestamp, String name) {
ValueDescriptor v = getValueDescriptor(descriptors, name, null); ValueDescriptor v = getValueDescriptor(descriptors, name, null);
Timestamp ts = v.getAnnotation(Timestamp.class); Timestamp ts = v.getAnnotation(Timestamp.class);
if (ts != null) { if (ts != null) {
if (timestamp == Long.MIN_VALUE) {
return Instant.MIN;
}
switch (ts.value()) { switch (ts.value()) {
case Timestamp.MILLISECONDS_SINCE_EPOCH: case Timestamp.MILLISECONDS_SINCE_EPOCH:
return Instant.ofEpochMilli(timestamp); return Instant.ofEpochMilli(timestamp);
...@@ -884,6 +890,10 @@ public class RecordedObject { ...@@ -884,6 +890,10 @@ public class RecordedObject {
// package private for now. Used by EventWriter // package private for now. Used by EventWriter
OffsetDateTime getOffsetDateTime(String name) { OffsetDateTime getOffsetDateTime(String name) {
Instant instant = getInstant(name);
if (instant.equals(Instant.MIN)) {
return OffsetDateTime.MIN;
}
return OffsetDateTime.ofInstant(getInstant(name), timeConverter.getZoneOffset()); return OffsetDateTime.ofInstant(getInstant(name), timeConverter.getZoneOffset());
} }
......
...@@ -281,7 +281,7 @@ public final class PrettyWriter extends EventPrintWriter { ...@@ -281,7 +281,7 @@ public final class PrettyWriter extends EventPrintWriter {
private void printValue(Object value, ValueDescriptor field, String postFix) { private void printValue(Object value, ValueDescriptor field, String postFix) {
if (value == null) { if (value == null) {
println("null" + postFix); println("N/A" + postFix);
return; return;
} }
if (value instanceof RecordedObject) { if (value instanceof RecordedObject) {
...@@ -320,6 +320,35 @@ public final class PrettyWriter extends EventPrintWriter { ...@@ -320,6 +320,35 @@ public final class PrettyWriter extends EventPrintWriter {
return; return;
} }
} }
if (value instanceof Double) {
Double d = (Double) value;
if (Double.isNaN(d) || d == Double.NEGATIVE_INFINITY) {
println("N/A");
return;
}
}
if (value instanceof Float) {
Float f = (Float) value;
if (Float.isNaN(f) || f == Float.NEGATIVE_INFINITY) {
println("N/A");
return;
}
}
if (value instanceof Long) {
Long l = (Long) value;
if (l == Long.MIN_VALUE) {
println("N/A");
return;
}
}
if (value instanceof Integer) {
Integer i = (Integer) value;
if (i == Integer.MIN_VALUE) {
println("N/A");
return;
}
}
String text = String.valueOf(value); String text = String.valueOf(value);
if (value instanceof String) { if (value instanceof String) {
text = "\"" + text + "\""; text = "\"" + text + "\"";
...@@ -443,6 +472,10 @@ public final class PrettyWriter extends EventPrintWriter { ...@@ -443,6 +472,10 @@ public final class PrettyWriter extends EventPrintWriter {
private boolean printFormatted(ValueDescriptor field, Object value) { private boolean printFormatted(ValueDescriptor field, Object value) {
if (value instanceof Duration) { if (value instanceof Duration) {
Duration d = (Duration) value; Duration d = (Duration) value;
if (d.getSeconds() == Long.MIN_VALUE) {
println("N/A");
return true;
}
double s = d.getNano() / 1000_000_000.0 + (int) (d.getSeconds() % 60); double s = d.getNano() / 1000_000_000.0 + (int) (d.getSeconds() % 60);
if (s < 1.0) { if (s < 1.0) {
if (s < 0.001) { if (s < 0.001) {
...@@ -460,8 +493,12 @@ public final class PrettyWriter extends EventPrintWriter { ...@@ -460,8 +493,12 @@ public final class PrettyWriter extends EventPrintWriter {
return true; return true;
} }
if (value instanceof OffsetDateTime) { if (value instanceof OffsetDateTime) {
OffsetDateTime zdt = (OffsetDateTime) value; OffsetDateTime odt = (OffsetDateTime) value;
println(TIME_FORMAT.format(zdt)); if (odt.equals(OffsetDateTime.MIN)) {
println("N/A");
return true;
}
println(TIME_FORMAT.format(odt));
return true; return true;
} }
Percentage percentage = field.getAnnotation(Percentage.class); Percentage percentage = field.getAnnotation(Percentage.class);
......
...@@ -25,22 +25,25 @@ ...@@ -25,22 +25,25 @@
package jdk.jfr.event.runtime; package jdk.jfr.event.runtime;
import static jdk.test.lib.Asserts.assertFalse;
import static jdk.test.lib.Asserts.assertTrue; import static jdk.test.lib.Asserts.assertTrue;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.time.Duration; import java.time.Duration;
import java.time.Instant;
import java.util.List; import java.util.List;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.LockSupport; import java.util.concurrent.locks.LockSupport;
import java.util.function.Consumer;
import jdk.jfr.Recording; import jdk.jfr.Recording;
import jdk.jfr.consumer.RecordedEvent; import jdk.jfr.consumer.RecordedEvent;
import jdk.test.lib.Asserts;
import jdk.test.lib.jfr.EventNames; import jdk.test.lib.jfr.EventNames;
import jdk.test.lib.jfr.Events; import jdk.test.lib.jfr.Events;
import jdk.test.lib.management.ThreadMXBeanTool; import jdk.test.lib.management.ThreadMXBeanTool;
import jdk.test.lib.thread.TestThread; import jdk.test.lib.thread.TestThread;
/** /**
* @test * @test
* @key jfr * @key jfr
...@@ -58,12 +61,39 @@ public class TestThreadParkEvent { ...@@ -58,12 +61,39 @@ public class TestThreadParkEvent {
} }
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
testParkNoTimeout();
testParkTimeout();
testParkUntil();
}
private static void testParkNoTimeout() throws Exception {
RecordedEvent event = testPark(x -> LockSupport.park(x), Thread.State.WAITING);
Events.assertMissingValue(event, "timeout");
Events.assertMissingValue(event, "until");
}
private static void testParkTimeout() throws Exception {
Duration expected = Duration.ofNanos(1_234_567_890_123L);
RecordedEvent event = testPark(x -> LockSupport.parkNanos(x, expected.toNanos()), Thread.State.TIMED_WAITING);
Events.assertDuration(event, "timeout", expected);
Events.assertMissingValue(event, "until");
}
private static void testParkUntil() throws Exception {
long epochMillis = Instant.now().plusSeconds(1000000).toEpochMilli();
RecordedEvent event = testPark(x -> LockSupport.parkUntil(x, epochMillis), Thread.State.TIMED_WAITING);
Events.assertMissingValue(event, "timeout");
Events.assertInstant(event, "until", Instant.ofEpochMilli(epochMillis));
}
static RecordedEvent testPark(Consumer<Blocker> parkOperation, Thread.State threadState) throws Exception {
final CountDownLatch stop = new CountDownLatch(1); final CountDownLatch stop = new CountDownLatch(1);
final Blocker blocker = new Blocker(); final Blocker blocker = new Blocker();
TestThread parkThread = new TestThread(new Runnable() { TestThread parkThread = new TestThread(new Runnable() {
public void run() { public void run() {
while (stop.getCount() > 0) { while (stop.getCount() > 0) {
LockSupport.park(blocker); parkOperation.accept(blocker);
} }
} }
}); });
...@@ -73,7 +103,7 @@ public class TestThreadParkEvent { ...@@ -73,7 +103,7 @@ public class TestThreadParkEvent {
try { try {
recording.start(); recording.start();
parkThread.start(); parkThread.start();
ThreadMXBeanTool.waitUntilBlockingOnObject(parkThread, Thread.State.WAITING, blocker); ThreadMXBeanTool.waitUntilBlockingOnObject(parkThread, threadState, blocker);
// sleep so we know the event is recorded // sleep so we know the event is recorded
Thread.sleep(2 * THRESHOLD_MILLIS); Thread.sleep(2 * THRESHOLD_MILLIS);
} finally { } finally {
...@@ -82,22 +112,21 @@ public class TestThreadParkEvent { ...@@ -82,22 +112,21 @@ public class TestThreadParkEvent {
parkThread.join(); parkThread.join();
recording.stop(); recording.stop();
} }
List<RecordedEvent> events = Events.fromRecording(recording); List<RecordedEvent> events = Events.fromRecording(recording);
Events.hasEvents(events); Events.hasEvents(events);
boolean isAnyFound = false; RecordedEvent foundEvent = null;
for (RecordedEvent event : events) { for (RecordedEvent event : events) {
System.out.println("Event:" + event); System.out.println("Event:" + event);
String klassName = Events.assertField(event, "parkedClass.name").notNull().getValue(); String klassName = Events.assertField(event, "parkedClass.name").notNull().getValue();
if (klassName.equals(blocker.getClass().getName().replace('.', '/'))) { if (klassName.equals(blocker.getClass().getName().replace('.', '/'))) {
assertFalse(isAnyFound, "Found more than 1 event"); Asserts.assertNull(foundEvent , "Found more than 1 event");
isAnyFound = true;
Events.assertField(event, "timeout").equal(0L);
Events.assertField(event, "address").notEqual(0L); Events.assertField(event, "address").notEqual(0L);
Events.assertEventThread(event, parkThread); Events.assertEventThread(event, parkThread);
foundEvent = event;
} }
} }
assertTrue(isAnyFound, "Correct event not found"); Asserts.assertNotNull(foundEvent, "Correct event not found");
return foundEvent;
} }
} }
...@@ -85,7 +85,7 @@ public class TestEnoughPermission { ...@@ -85,7 +85,7 @@ public class TestEnoughPermission {
System.out.println("E"); System.out.println("E");
bean.stopRecording(recId); bean.stopRecording(recId);
final Path path = Paths.get(".", String.format("rec%d.jfr", recId)); final Path path = Paths.get(".", "rec" + recId + ".jfr");
bean.copyTo(recId, path.toString()); bean.copyTo(recId, path.toString());
//EventSet events = EventSet.fromFile(path); //EventSet events = EventSet.fromFile(path);
return recId; return recId;
......
...@@ -33,6 +33,8 @@ import static jdk.test.lib.Asserts.fail; ...@@ -33,6 +33,8 @@ import static jdk.test.lib.Asserts.fail;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Path; import java.nio.file.Path;
import java.time.Duration;
import java.time.Instant;
import java.util.List; import java.util.List;
import java.lang.management.ManagementFactory; import java.lang.management.ManagementFactory;
...@@ -40,6 +42,8 @@ import jdk.jfr.AnnotationElement; ...@@ -40,6 +42,8 @@ import jdk.jfr.AnnotationElement;
import jdk.jfr.EventType; import jdk.jfr.EventType;
import jdk.jfr.Recording; import jdk.jfr.Recording;
import jdk.jfr.SettingDescriptor; import jdk.jfr.SettingDescriptor;
import jdk.jfr.Timespan;
import jdk.jfr.Timestamp;
import jdk.jfr.ValueDescriptor; import jdk.jfr.ValueDescriptor;
import jdk.jfr.consumer.RecordingFile; import jdk.jfr.consumer.RecordingFile;
import jdk.test.lib.Asserts; import jdk.test.lib.Asserts;
...@@ -184,6 +188,49 @@ public class Events { ...@@ -184,6 +188,49 @@ public class Events {
assertThread(assertField(event, structName).notNull().getValue(), thread); assertThread(assertField(event, structName).notNull().getValue(), thread);
} }
public static void assertDuration(RecordedEvent event, String name, Duration duration) {
assertEquals(event.getDuration(name), duration);
}
public static void assertInstant(RecordedEvent event, String name, Instant instant) {
assertEquals(event.getInstant(name), instant);
}
public static void assertMissingValue(RecordedEvent event, String name) {
ValueDescriptor v = event.getEventType().getField(name);
if (v.getAnnotation(Timespan.class) != null) {
Duration d = event.getDuration(name);
assertTrue(d.getSeconds() == Long.MIN_VALUE && d.getNano() == 0);
return;
}
if (v.getAnnotation(Timestamp.class) != null) {
Instant instant = event.getInstant(name);
assertTrue(instant.equals(Instant.MIN));
return;
}
if (v.getTypeName().equals("double")) {
double d = event.getDouble(name);
assertTrue(Double.isNaN(d) || d == Double.NEGATIVE_INFINITY);
return;
}
if (v.getTypeName().equals("float")) {
float f = event.getFloat(name);
assertTrue(Float.isNaN(f) || f == Float.NEGATIVE_INFINITY);
return;
}
if (v.getTypeName().equals("int")) {
int i = event.getInt(name);
assertTrue(i == Integer.MIN_VALUE);
return;
}
if (v.getTypeName().equals("long")) {
assertEquals(event.getLong(name), Long.MIN_VALUE);
return;
}
Object o = event.getValue(name);
Asserts.assertNull(o);
}
private static void assertThread(RecordedThread eventThread, Thread thread) { private static void assertThread(RecordedThread eventThread, Thread thread) {
assertNotNull(eventThread, "Thread in event was null"); assertNotNull(eventThread, "Thread in event was null");
assertEquals(eventThread.getJavaThreadId(), thread.getId(), "Wrong thread id"); assertEquals(eventThread.getJavaThreadId(), thread.getId(), "Wrong thread id");
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册