8279398: jdk/jfr/api/recording/time/TestTimeMultiple.java failed with "RuntimeException: getStopTime() > afterStop"
Reviewed-by: mgronlun
This commit is contained in:
parent
ad34f03b54
commit
40df5df95e
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 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
|
||||||
@ -280,9 +280,12 @@ public final class MetadataRepository {
|
|||||||
if (staleMetadata) {
|
if (staleMetadata) {
|
||||||
storeDescriptorInJVM();
|
storeDescriptorInJVM();
|
||||||
}
|
}
|
||||||
awaitUniqueTimestamp();
|
|
||||||
jvm.setOutput(filename);
|
jvm.setOutput(filename);
|
||||||
long nanos = jvm.getChunkStartNanos();
|
// Each chunk needs a unique start timestamp and
|
||||||
|
// if the clock resolution is low, two chunks may
|
||||||
|
// get the same timestamp. Utils.getChunkStartNanos()
|
||||||
|
// ensures the timestamp is unique for the next chunk
|
||||||
|
long chunkStart = Utils.getChunkStartNanos();
|
||||||
if (filename != null) {
|
if (filename != null) {
|
||||||
RepositoryFiles.notifyNewFile();
|
RepositoryFiles.notifyNewFile();
|
||||||
}
|
}
|
||||||
@ -293,29 +296,7 @@ public final class MetadataRepository {
|
|||||||
}
|
}
|
||||||
unregistered = false;
|
unregistered = false;
|
||||||
}
|
}
|
||||||
return Utils.epochNanosToInstant(nanos);
|
return Utils.epochNanosToInstant(chunkStart);
|
||||||
}
|
|
||||||
|
|
||||||
// Each chunk needs a unique start timestamp and
|
|
||||||
// if the clock resolution is low, two chunks may
|
|
||||||
// get the same timestamp.
|
|
||||||
private void awaitUniqueTimestamp() {
|
|
||||||
if (outputChange == null) {
|
|
||||||
outputChange = Instant.now();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
while (true) {
|
|
||||||
Instant time = Instant.now();
|
|
||||||
if (!time.equals(outputChange)) {
|
|
||||||
outputChange = time;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
Thread.sleep(0, 100);
|
|
||||||
} catch (InterruptedException iex) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void unregisterUnloaded() {
|
private void unregisterUnloaded() {
|
||||||
|
@ -248,7 +248,7 @@ public final class PlatformRecorder {
|
|||||||
}
|
}
|
||||||
currentChunk = newChunk;
|
currentChunk = newChunk;
|
||||||
jvm.beginRecording();
|
jvm.beginRecording();
|
||||||
startNanos = jvm.getChunkStartNanos();
|
startNanos = Utils.getChunkStartNanos();
|
||||||
startTime = Utils.epochNanosToInstant(startNanos);
|
startTime = Utils.epochNanosToInstant(startNanos);
|
||||||
if (currentChunk != null) {
|
if (currentChunk != null) {
|
||||||
currentChunk.setStartTime(startTime);
|
currentChunk.setStartTime(startTime);
|
||||||
@ -269,7 +269,7 @@ public final class PlatformRecorder {
|
|||||||
startTime = MetadataRepository.getInstance().setOutput(p);
|
startTime = MetadataRepository.getInstance().setOutput(p);
|
||||||
newChunk.setStartTime(startTime);
|
newChunk.setStartTime(startTime);
|
||||||
}
|
}
|
||||||
startNanos = jvm.getChunkStartNanos();
|
startNanos = Utils.getChunkStartNanos();
|
||||||
startTime = Utils.epochNanosToInstant(startNanos);
|
startTime = Utils.epochNanosToInstant(startNanos);
|
||||||
recording.setStartTime(startTime);
|
recording.setStartTime(startTime);
|
||||||
recording.setState(RecordingState.RUNNING);
|
recording.setState(RecordingState.RUNNING);
|
||||||
@ -316,7 +316,7 @@ public final class PlatformRecorder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
OldObjectSample.emit(recording);
|
OldObjectSample.emit(recording);
|
||||||
recording.setFinalStartnanos(jvm.getChunkStartNanos());
|
recording.setFinalStartnanos(Utils.getChunkStartNanos());
|
||||||
|
|
||||||
if (endPhysical) {
|
if (endPhysical) {
|
||||||
RequestEngine.doChunkEnd();
|
RequestEngine.doChunkEnd();
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2021, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2016, 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
|
||||||
@ -97,6 +97,7 @@ public final class Utils {
|
|||||||
* The possible data race is benign and is worth of not introducing any contention here.
|
* The possible data race is benign and is worth of not introducing any contention here.
|
||||||
*/
|
*/
|
||||||
private static Metrics[] metrics;
|
private static Metrics[] metrics;
|
||||||
|
private static Instant lastTimestamp;
|
||||||
|
|
||||||
public static void checkAccessFlightRecorder() throws SecurityException {
|
public static void checkAccessFlightRecorder() throws SecurityException {
|
||||||
@SuppressWarnings("removal")
|
@SuppressWarnings("removal")
|
||||||
@ -866,4 +867,30 @@ public final class Utils {
|
|||||||
throw new IllegalArgumentException("'" + name + "' is not a valid Java identifier");
|
throw new IllegalArgumentException("'" + name + "' is not a valid Java identifier");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static long getChunkStartNanos() {
|
||||||
|
long nanos = JVM.getJVM().getChunkStartNanos();
|
||||||
|
// JVM::getChunkStartNanos() may return a bumped timestamp, +1 ns or +2 ns.
|
||||||
|
// Spin here to give Instant.now() a chance to catch up.
|
||||||
|
awaitUniqueTimestamp();
|
||||||
|
return nanos;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void awaitUniqueTimestamp() {
|
||||||
|
if (lastTimestamp == null) {
|
||||||
|
lastTimestamp = Instant.now(); // lazy initialization
|
||||||
|
}
|
||||||
|
while (true) {
|
||||||
|
Instant time = Instant.now();
|
||||||
|
if (!time.equals(lastTimestamp)) {
|
||||||
|
lastTimestamp = time;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(0, 100);
|
||||||
|
} catch (InterruptedException iex) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user