Skip to content

Commit 96a124a

Browse files
committed
[GR-3590] Process::CLOCK_REALTIME has microsecond precision on Java 9+
PullRequest: truffleruby/2410
2 parents 5950406 + 1238ba8 commit 96a124a

File tree

6 files changed

+43
-13
lines changed

6 files changed

+43
-13
lines changed

spec/ruby/core/time/shared/now.rb

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@
1919
end
2020

2121
it "has at least microsecond precision" do
22-
times = []
23-
10_000.times do
24-
times << Time.now.nsec
25-
end
26-
2722
# The clock should not be less accurate than expected (times should
2823
# not all be a multiple of the next precision up, assuming precisions
2924
# are multiples of ten.)
3025
expected = 1_000
31-
times.select { |t| t % (expected * 10) == 0 }.size.should_not == times.size
26+
t = 0
27+
10_000.times.find do
28+
t = Time.now.nsec
29+
t % (expected * 10) != 0
30+
end
31+
(t % (expected * 10)).should != 0
3232
end
3333
end

spec/tags/core/time/now_tags.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
fails:Time.now has at least microsecond precision
1+
java8:Time.now has at least microsecond precision

spec/truffleruby.mspec

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
# truffleruby_primitives: true
2+
13
require 'rbconfig'
24

35
# Inherit from the default configuration
@@ -123,6 +125,10 @@ class MSpecScript
123125
excludes << 'arm64'
124126
end
125127

128+
if defined?(::TruffleRuby) and Primitive.vm_java_version <= 8
129+
excludes << 'java8'
130+
end
131+
126132
# All specs, excluding specs needing C-extensions support.
127133
set :files, get(:command_line) + get(:language) + get(:core) + get(:library) + get(:truffle) + get(:security)
128134

src/main/java/org/truffleruby/core/ProcessNodes.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919

2020
import sun.misc.Signal;
2121

22+
import java.time.Instant;
23+
2224
@CoreModule(value = "Process", isClass = true)
2325
public abstract class ProcessNodes {
2426

@@ -33,13 +35,14 @@ protected long nanoTime() {
3335

3436
}
3537

36-
@Primitive(name = "process_time_currenttimemillis")
37-
public abstract static class ProcessTimeCurrentTimeMillisNode extends PrimitiveArrayArgumentsNode {
38+
@Primitive(name = "process_time_instant")
39+
public abstract static class ProcessTimeInstantNode extends PrimitiveArrayArgumentsNode {
3840

3941
@TruffleBoundary
4042
@Specialization
41-
protected long currentTimeMillis() {
42-
return System.currentTimeMillis();
43+
protected long instant() {
44+
final Instant now = Instant.now();
45+
return (now.getEpochSecond() * 1_000_000_000L) + now.getNano();
4346
}
4447

4548
}

src/main/java/org/truffleruby/core/VMPrimitiveNodes.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -531,4 +531,24 @@ protected Object shouldNotReachHere(Object message,
531531

532532
}
533533

534+
@Primitive(name = "vm_java_version")
535+
public abstract static class VMJavaVersionNode extends PrimitiveArrayArgumentsNode {
536+
537+
private static final int JAVA_SPECIFICATION_VERSION = getJavaSpecificationVersion();
538+
539+
private static int getJavaSpecificationVersion() {
540+
String value = System.getProperty("java.specification.version");
541+
if (value.startsWith("1.")) {
542+
value = value.substring(2);
543+
}
544+
return Integer.parseInt(value);
545+
}
546+
547+
@Specialization
548+
protected int javaVersion() {
549+
return JAVA_SPECIFICATION_VERSION;
550+
}
551+
552+
}
553+
534554
}

src/main/ruby/truffleruby/core/process.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@ def self.clock_getres(id, unit=:float_second)
112112
:CLOCK_BASED_CLOCK_PROCESS_CPUTIME_ID
113113
1_000
114114
when CLOCK_REALTIME
115-
1_000_000
115+
# https://bugs.openjdk.java.net/browse/JDK-8068730
116+
Primitive.vm_java_version >= 9 ? 1000 : 1_000_000
116117
when :TIMES_BASED_CLOCK_MONOTONIC,
117118
:TIMES_BASED_CLOCK_PROCESS_CPUTIME_ID
118119
10_000_000
@@ -156,7 +157,7 @@ def self.clock_gettime(id, unit=:float_second)
156157

157158
case id
158159
when CLOCK_REALTIME
159-
time = Primitive.process_time_currenttimemillis * 1_000_000
160+
time = Primitive.process_time_instant
160161
when CLOCK_MONOTONIC
161162
time = Primitive.process_time_nanotime
162163
else

0 commit comments

Comments
 (0)