Skip to content

Commit 3da69b4

Browse files
committed
[GR-18163] Always define CLOCK_BOOTTIME, CLOCK_BOOTTIME_ALARM and CLOCK_REALTIME_ALARM on Linux
PullRequest: truffleruby/3343
2 parents 51b68e7 + f0b313d commit 3da69b4

File tree

10 files changed

+122
-64
lines changed

10 files changed

+122
-64
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ Compatibility:
2828
* `Process.euid=` should accept String (#2615, @ngtban).
2929
* Fix `instance_variable_get` and `instance_variable_set` for immutable objects (@bjfish).
3030
* `Thread#raise(exc, message)` now calls `exc.exception` in the target thread like CRuby (@eregon).
31+
* Define `Process::{CLOCK_BOOTTIME,CLOCK_BOOTTIME_ALARM,CLOCK_REALTIME_ALARM}` (#1480, @eregon).
3132

3233
Performance:
3334

spec/mspec/lib/mspec/guards/version.rb

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,30 @@ def match?
3333
@version >= @requirement
3434
end
3535
end
36+
37+
@kernel_version = nil
38+
def self.kernel_version
39+
if @kernel_version
40+
@kernel_version
41+
else
42+
if v = RUBY_PLATFORM[/darwin(\d+)/, 1] # build time version
43+
uname = v
44+
else
45+
begin
46+
require 'etc'
47+
etc = true
48+
rescue LoadError
49+
etc = false
50+
end
51+
if etc and Etc.respond_to?(:uname)
52+
uname = Etc.uname.fetch(:release)
53+
else
54+
uname = `uname -r`.chomp
55+
end
56+
end
57+
@kernel_version = uname
58+
end
59+
end
3660
end
3761

3862
def version_is(base_version, requirement, &block)
@@ -42,3 +66,7 @@ def version_is(base_version, requirement, &block)
4266
def ruby_version_is(requirement, &block)
4367
VersionGuard.new(VersionGuard::FULL_RUBY_VERSION, requirement).run_if(:ruby_version_is, &block)
4468
end
69+
70+
def kernel_version_is(requirement, &block)
71+
VersionGuard.new(VersionGuard.kernel_version, requirement).run_if(:kernel_version_is, &block)
72+
end

spec/mspec/lib/mspec/runner/formatters/base.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,14 @@ def unload
113113
# evaluating the examples.
114114
def finish
115115
print "\n"
116+
117+
if MSpecOptions.latest && MSpecOptions.latest.config[:print_skips]
118+
print "\nSkips:\n" unless MSpec.skips.empty?
119+
MSpec.skips.each do |skip, block|
120+
print "#{skip.message} in #{(block.source_location || ['?']).join(':')}\n"
121+
end
122+
end
123+
116124
count = 0
117125
@exceptions.each do |exc|
118126
count += 1

spec/mspec/lib/mspec/runner/mspec.rb

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,10 @@ module MSpec
3636
@repeat = 1
3737
@expectation = nil
3838
@expectations = false
39+
@skips = []
3940

4041
class << self
41-
attr_reader :file, :include, :exclude
42+
attr_reader :file, :include, :exclude, :skips
4243
attr_writer :repeat, :randomize
4344
attr_accessor :formatter
4445
end
@@ -116,6 +117,7 @@ def self.protect(location, &block)
116117
rescue SystemExit => e
117118
raise e
118119
rescue SkippedSpecError => e
120+
@skips << [e, block]
119121
return false
120122
rescue Object => exc
121123
register_exit 1

spec/mspec/lib/mspec/utils/options.rb

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,10 @@ def obj.load
423423
end
424424
MSpec.register :load, obj
425425
end
426+
427+
on("--print-skips", "Print skips") do
428+
config[:print_skips] = true
429+
end
426430
end
427431

428432
def interrupt

spec/ruby/core/io/advise_spec.rb

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -73,19 +73,9 @@
7373
end
7474
end
7575

76-
platform_is :linux do
76+
guard -> { platform_is :linux and kernel_version_is '3.6' } do # [ruby-core:65355] tmpfs is not supported
7777
it "supports the willneed advice type" do
78-
require 'etc'
79-
uname = if Etc.respond_to?(:uname)
80-
Etc.uname[:release]
81-
else
82-
`uname -r`.chomp
83-
end
84-
if (uname.split('.').map(&:to_i) <=> [3,6]) < 0
85-
skip "[ruby-core:65355] tmpfs is not supported"
86-
else
87-
@io.advise(:willneed).should be_nil
88-
end
78+
@io.advise(:willneed).should be_nil
8979
end
9080
end
9181

spec/ruby/core/process/clock_gettime_spec.rb

Lines changed: 56 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
end
5353

5454
# These specs need macOS 10.12+ / darwin 16+
55-
guard_not -> { platform_is_not(:darwin) or RUBY_PLATFORM[/darwin\d+/].to_i >= 16 } do
55+
guard -> { platform_is_not(:darwin) or kernel_version_is '16' } do
5656
platform_is :linux, :openbsd, :darwin do
5757
it "CLOCK_PROCESS_CPUTIME_ID" do
5858
Process.clock_gettime(Process::CLOCK_PROCESS_CPUTIME_ID).should be_an_instance_of(Float)
@@ -65,20 +65,6 @@
6565
end
6666
end
6767

68-
platform_is :freebsd, :openbsd do
69-
it "CLOCK_VIRTUAL" do
70-
Process.clock_gettime(Process::CLOCK_VIRTUAL).should be_an_instance_of(Float)
71-
end
72-
73-
it "CLOCK_PROF" do
74-
Process.clock_gettime(Process::CLOCK_PROF).should be_an_instance_of(Float)
75-
end
76-
77-
it "CLOCK_UPTIME" do
78-
Process.clock_gettime(Process::CLOCK_UPTIME).should be_an_instance_of(Float)
79-
end
80-
end
81-
8268
platform_is :linux, :darwin do
8369
it "CLOCK_MONOTONIC_RAW" do
8470
Process.clock_gettime(Process::CLOCK_MONOTONIC_RAW).should be_an_instance_of(Float)
@@ -95,42 +81,69 @@
9581
Process.clock_gettime(Process::CLOCK_UPTIME_RAW_APPROX).should be_an_instance_of(Float)
9682
end
9783
end
84+
end
9885

99-
platform_is :freebsd do
100-
it "CLOCK_REALTIME_FAST and CLOCK_REALTIME_PRECISE" do
101-
Process.clock_gettime(Process::CLOCK_REALTIME_FAST).should be_an_instance_of(Float)
102-
Process.clock_gettime(Process::CLOCK_REALTIME_PRECISE).should be_an_instance_of(Float)
103-
end
86+
platform_is :freebsd, :openbsd do
87+
it "CLOCK_VIRTUAL" do
88+
Process.clock_gettime(Process::CLOCK_VIRTUAL).should be_an_instance_of(Float)
89+
end
10490

105-
it "CLOCK_MONOTONIC_FAST and CLOCK_MONOTONIC_PRECISE" do
106-
Process.clock_gettime(Process::CLOCK_MONOTONIC_FAST).should be_an_instance_of(Float)
107-
Process.clock_gettime(Process::CLOCK_MONOTONIC_PRECISE).should be_an_instance_of(Float)
108-
end
91+
it "CLOCK_PROF" do
92+
Process.clock_gettime(Process::CLOCK_PROF).should be_an_instance_of(Float)
93+
end
10994

110-
it "CLOCK_UPTIME_FAST and CLOCK_UPTIME_PRECISE" do
111-
Process.clock_gettime(Process::CLOCK_UPTIME_FAST).should be_an_instance_of(Float)
112-
Process.clock_gettime(Process::CLOCK_UPTIME_PRECISE).should be_an_instance_of(Float)
113-
end
95+
it "CLOCK_UPTIME" do
96+
Process.clock_gettime(Process::CLOCK_UPTIME).should be_an_instance_of(Float)
97+
end
98+
end
11499

115-
it "CLOCK_SECOND" do
116-
Process.clock_gettime(Process::CLOCK_SECOND).should be_an_instance_of(Float)
117-
end
100+
platform_is :freebsd do
101+
it "CLOCK_REALTIME_FAST and CLOCK_REALTIME_PRECISE" do
102+
Process.clock_gettime(Process::CLOCK_REALTIME_FAST).should be_an_instance_of(Float)
103+
Process.clock_gettime(Process::CLOCK_REALTIME_PRECISE).should be_an_instance_of(Float)
118104
end
119105

120-
platform_is :linux do
121-
it "CLOCK_REALTIME_COARSE and CLOCK_REALTIME_ALARM" do
122-
Process.clock_gettime(Process::CLOCK_REALTIME_COARSE).should be_an_instance_of(Float)
123-
Process.clock_gettime(Process::CLOCK_REALTIME_ALARM).should be_an_instance_of(Float)
124-
end
106+
it "CLOCK_MONOTONIC_FAST and CLOCK_MONOTONIC_PRECISE" do
107+
Process.clock_gettime(Process::CLOCK_MONOTONIC_FAST).should be_an_instance_of(Float)
108+
Process.clock_gettime(Process::CLOCK_MONOTONIC_PRECISE).should be_an_instance_of(Float)
109+
end
125110

126-
it "CLOCK_MONOTONIC_COARSE" do
127-
Process.clock_gettime(Process::CLOCK_MONOTONIC_COARSE).should be_an_instance_of(Float)
128-
end
111+
it "CLOCK_UPTIME_FAST and CLOCK_UPTIME_PRECISE" do
112+
Process.clock_gettime(Process::CLOCK_UPTIME_FAST).should be_an_instance_of(Float)
113+
Process.clock_gettime(Process::CLOCK_UPTIME_PRECISE).should be_an_instance_of(Float)
114+
end
129115

130-
it "CLOCK_BOOTTIME and CLOCK_BOOTTIME_ALARM" do
131-
Process.clock_gettime(Process::CLOCK_BOOTTIME).should be_an_instance_of(Float)
132-
Process.clock_gettime(Process::CLOCK_BOOTTIME_ALARM).should be_an_instance_of(Float)
133-
end
116+
it "CLOCK_SECOND" do
117+
Process.clock_gettime(Process::CLOCK_SECOND).should be_an_instance_of(Float)
118+
end
119+
end
120+
121+
guard -> { platform_is :linux and kernel_version_is '2.6.32' } do
122+
it "CLOCK_REALTIME_COARSE" do
123+
Process.clock_gettime(Process::CLOCK_REALTIME_COARSE).should be_an_instance_of(Float)
124+
end
125+
126+
it "CLOCK_MONOTONIC_COARSE" do
127+
Process.clock_gettime(Process::CLOCK_MONOTONIC_COARSE).should be_an_instance_of(Float)
128+
end
129+
end
130+
131+
guard -> { platform_is :linux and kernel_version_is '2.6.39' } do
132+
it "CLOCK_BOOTTIME" do
133+
skip "No Process::CLOCK_BOOTTIME" unless defined?(Process::CLOCK_BOOTTIME)
134+
Process.clock_gettime(Process::CLOCK_BOOTTIME).should be_an_instance_of(Float)
135+
end
136+
end
137+
138+
guard -> { platform_is "x86_64-linux" and kernel_version_is '3.0' } do
139+
it "CLOCK_REALTIME_ALARM" do
140+
skip "No Process::CLOCK_REALTIME_ALARM" unless defined?(Process::CLOCK_REALTIME_ALARM)
141+
Process.clock_gettime(Process::CLOCK_REALTIME_ALARM).should be_an_instance_of(Float)
142+
end
143+
144+
it "CLOCK_BOOTTIME_ALARM" do
145+
skip "No Process::CLOCK_BOOTTIME_ALARM" unless defined?(Process::CLOCK_BOOTTIME_ALARM)
146+
Process.clock_gettime(Process::CLOCK_BOOTTIME_ALARM).should be_an_instance_of(Float)
134147
end
135148
end
136149
end

src/main/java/org/truffleruby/platform/LinuxAMD64NativeConfiguration.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -744,6 +744,9 @@ public static void load(NativeConfiguration configuration, RubyContext context)
744744
configuration.config("platform.clocks.CLOCK_REALTIME", 0);
745745
configuration.config("platform.clocks.CLOCK_REALTIME_COARSE", 5);
746746
configuration.config("platform.clocks.CLOCK_THREAD_CPUTIME_ID", 3);
747+
configuration.config("platform.clocks.CLOCK_BOOTTIME", 7);
748+
configuration.config("platform.clocks.CLOCK_REALTIME_ALARM", 8);
749+
configuration.config("platform.clocks.CLOCK_BOOTTIME_ALARM", 9);
747750
configuration.config("platform.typedef.int8_t", string(context, "char"));
748751
configuration.config("platform.typedef.int16_t", string(context, "short"));
749752
configuration.config("platform.typedef.int32_t", string(context, "int"));

src/main/java/org/truffleruby/platform/LinuxARM64NativeConfiguration.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -760,16 +760,16 @@ public static void load(NativeConfiguration configuration, RubyContext context)
760760
configuration.config("platform.dlopen.RTLD_GLOBAL", 256);
761761
configuration.config("platform.dlopen.RTLD_NEXT", -1);
762762
configuration.config("platform.dlopen.RTLD_DEFAULT", 0);
763-
configuration.config("platform.clocks.CLOCK_BOOTTIME", 7);
764-
configuration.config("platform.clocks.CLOCK_BOOTTIME_ALARM", 9);
765763
configuration.config("platform.clocks.CLOCK_MONOTONIC", 1);
766764
configuration.config("platform.clocks.CLOCK_MONOTONIC_COARSE", 6);
767765
configuration.config("platform.clocks.CLOCK_MONOTONIC_RAW", 4);
768766
configuration.config("platform.clocks.CLOCK_PROCESS_CPUTIME_ID", 2);
769767
configuration.config("platform.clocks.CLOCK_REALTIME", 0);
770-
configuration.config("platform.clocks.CLOCK_REALTIME_ALARM", 8);
771768
configuration.config("platform.clocks.CLOCK_REALTIME_COARSE", 5);
772769
configuration.config("platform.clocks.CLOCK_THREAD_CPUTIME_ID", 3);
770+
configuration.config("platform.clocks.CLOCK_BOOTTIME", 7);
771+
configuration.config("platform.clocks.CLOCK_REALTIME_ALARM", 8);
772+
configuration.config("platform.clocks.CLOCK_BOOTTIME_ALARM", 9);
773773
configuration.config("platform.typedef.int8_t", string(context, "char"));
774774
configuration.config("platform.typedef.int16_t", string(context, "short"));
775775
configuration.config("platform.typedef.int32_t", string(context, "int"));

tool/generate-native-config.rb

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -266,9 +266,13 @@ def initialize(group)
266266
@constants = {}
267267
end
268268

269+
def const(name, default_value = nil, format = '%ld', cast = '(long)')
270+
@constants[name] = Constant.new(name, format, cast, default_value)
271+
end
272+
269273
def consts(names, format = '%ld', cast = '(long)')
270274
names.each do |name|
271-
@constants[name] = Constant.new(name, format, cast, nil)
275+
const(name, nil, format, cast)
272276
end
273277
end
274278

@@ -774,8 +778,6 @@ def constants(name)
774778
constants 'clocks' do |cg|
775779
cg.include 'time.h'
776780
cg.consts %w[
777-
CLOCK_BOOTTIME
778-
CLOCK_BOOTTIME_ALARM
779781
CLOCK_MONOTONIC
780782
CLOCK_MONOTONIC_COARSE
781783
CLOCK_MONOTONIC_FAST
@@ -785,7 +787,6 @@ def constants(name)
785787
CLOCK_PROCESS_CPUTIME_ID
786788
CLOCK_PROF
787789
CLOCK_REALTIME
788-
CLOCK_REALTIME_ALARM
789790
CLOCK_REALTIME_COARSE
790791
CLOCK_REALTIME_FAST
791792
CLOCK_REALTIME_PRECISE
@@ -797,7 +798,15 @@ def constants(name)
797798
CLOCK_UPTIME_RAW
798799
CLOCK_UPTIME_RAW_APPROX
799800
CLOCK_VIRTUAL
800-
]
801+
]
802+
803+
# Give the following clock ids a default so they works on newer Linux built by older Linux:
804+
# https://github.com/oracle/truffleruby/issues/1480
805+
cg.const 'CLOCK_BOOTTIME', (7 if RUBY_PLATFORM =~ /linux/)
806+
# These 2 are not supported on linux-aarch64:
807+
# https://patchwork.kernel.org/project/linux-arm-kernel/patch/[email protected]/#21274245
808+
cg.const 'CLOCK_REALTIME_ALARM', (8 if RUBY_PLATFORM =~ /x86_64-linux/)
809+
cg.const 'CLOCK_BOOTTIME_ALARM', (9 if RUBY_PLATFORM =~ /x86_64-linux/)
801810
end
802811

803812
TypesGenerator.new.generate

0 commit comments

Comments
 (0)