Skip to content

Commit c8014de

Browse files
committed
Auto merge of #2679 - RalfJung:clock_gettime, r=RalfJung
implement clock_gettime on macos and pull in rustc changes so we can test this against rust-lang/rust#103594.
2 parents 6d75804 + d6fdb5e commit c8014de

File tree

5 files changed

+51
-28
lines changed

5 files changed

+51
-28
lines changed

rust-version

+1-1
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
9340e5c1b9dee53fd32a18f7bfb54faabfe00b7b
1+
2f8d8040166a730d0da7bba0f2864f0ef7ff6364

src/shims/time.rs

+35-12
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,51 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
2222

2323
let this = self.eval_context_mut();
2424

25-
this.assert_target_os("linux", "clock_gettime");
25+
this.assert_target_os_is_unix("clock_gettime");
2626

2727
let clk_id = this.read_scalar(clk_id_op)?.to_i32()?;
2828

29-
// Linux has two main kinds of clocks. REALTIME clocks return the actual time since the
30-
// Unix epoch, including effects which may cause time to move backwards such as NTP.
31-
// Linux further distinguishes regular and "coarse" clocks, but the "coarse" version
32-
// is just specified to be "faster and less precise", so we implement both the same way.
33-
let absolute_clocks =
34-
[this.eval_libc_i32("CLOCK_REALTIME")?, this.eval_libc_i32("CLOCK_REALTIME_COARSE")?];
35-
// The second kind is MONOTONIC clocks for which 0 is an arbitrary time point, but they are
36-
// never allowed to go backwards. We don't need to do any additonal monotonicity
37-
// enforcement because std::time::Instant already guarantees that it is monotonic.
38-
let relative_clocks =
39-
[this.eval_libc_i32("CLOCK_MONOTONIC")?, this.eval_libc_i32("CLOCK_MONOTONIC_COARSE")?];
29+
let absolute_clocks;
30+
let relative_clocks;
31+
32+
match this.tcx.sess.target.os.as_ref() {
33+
"linux" => {
34+
// Linux has two main kinds of clocks. REALTIME clocks return the actual time since the
35+
// Unix epoch, including effects which may cause time to move backwards such as NTP.
36+
// Linux further distinguishes regular and "coarse" clocks, but the "coarse" version
37+
// is just specified to be "faster and less precise", so we implement both the same way.
38+
absolute_clocks = vec![
39+
this.eval_libc_i32("CLOCK_REALTIME")?,
40+
this.eval_libc_i32("CLOCK_REALTIME_COARSE")?,
41+
];
42+
// The second kind is MONOTONIC clocks for which 0 is an arbitrary time point, but they are
43+
// never allowed to go backwards. We don't need to do any additonal monotonicity
44+
// enforcement because std::time::Instant already guarantees that it is monotonic.
45+
relative_clocks = vec![
46+
this.eval_libc_i32("CLOCK_MONOTONIC")?,
47+
this.eval_libc_i32("CLOCK_MONOTONIC_COARSE")?,
48+
];
49+
}
50+
"macos" => {
51+
absolute_clocks = vec![this.eval_libc_i32("CLOCK_REALTIME")?];
52+
// `CLOCK_UPTIME_RAW` supposed to not increment while the system is asleep... but
53+
// that's not really something a program running inside Miri can tell, anyway.
54+
// We need to support it because std uses it.
55+
relative_clocks = vec![
56+
this.eval_libc_i32("CLOCK_MONOTONIC")?,
57+
this.eval_libc_i32("CLOCK_UPTIME_RAW")?,
58+
];
59+
}
60+
target => throw_unsup_format!("`clock_gettime` is not supported on target OS {target}"),
61+
}
4062

4163
let duration = if absolute_clocks.contains(&clk_id) {
4264
this.check_no_isolation("`clock_gettime` with `REALTIME` clocks")?;
4365
system_time_to_duration(&SystemTime::now())?
4466
} else if relative_clocks.contains(&clk_id) {
4567
this.machine.clock.now().duration_since(this.machine.clock.anchor())
4668
} else {
69+
// Unsupported clock.
4770
let einval = this.eval_libc("EINVAL")?;
4871
this.set_last_error(einval)?;
4972
return Ok(Scalar::from_i32(-1));

src/shims/unix/foreign_items.rs

+6
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
180180
let result = this.gettimeofday(tv, tz)?;
181181
this.write_scalar(Scalar::from_i32(result), dest)?;
182182
}
183+
"clock_gettime" => {
184+
let [clk_id, tp] =
185+
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
186+
let result = this.clock_gettime(clk_id, tp)?;
187+
this.write_scalar(result, dest)?;
188+
}
183189

184190
// Allocation
185191
"posix_memalign" => {

src/shims/unix/linux/foreign_items.rs

-9
Original file line numberDiff line numberDiff line change
@@ -43,15 +43,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
4343
this.write_scalar(result, dest)?;
4444
}
4545

46-
// Time related shims
47-
"clock_gettime" => {
48-
// This is a POSIX function but it has only been tested on linux.
49-
let [clk_id, tp] =
50-
this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
51-
let result = this.clock_gettime(clk_id, tp)?;
52-
this.write_scalar(result, dest)?;
53-
}
54-
5546
// Threading
5647
"pthread_condattr_setclock" => {
5748
let [attr, clock_id] =

tests/pass-dep/shims/libc-misc.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -181,17 +181,20 @@ fn test_thread_local_errno() {
181181
}
182182

183183
/// Tests whether clock support exists at all
184-
#[cfg(target_os = "linux")]
185184
fn test_clocks() {
186185
let mut tp = std::mem::MaybeUninit::<libc::timespec>::uninit();
187186
let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME, tp.as_mut_ptr()) };
188187
assert_eq!(is_error, 0);
189-
let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, tp.as_mut_ptr()) };
190-
assert_eq!(is_error, 0);
191188
let is_error = unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC, tp.as_mut_ptr()) };
192189
assert_eq!(is_error, 0);
193-
let is_error = unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC_COARSE, tp.as_mut_ptr()) };
194-
assert_eq!(is_error, 0);
190+
#[cfg(target_os = "linux")]
191+
{
192+
let is_error = unsafe { libc::clock_gettime(libc::CLOCK_REALTIME_COARSE, tp.as_mut_ptr()) };
193+
assert_eq!(is_error, 0);
194+
let is_error =
195+
unsafe { libc::clock_gettime(libc::CLOCK_MONOTONIC_COARSE, tp.as_mut_ptr()) };
196+
assert_eq!(is_error, 0);
197+
}
195198
}
196199

197200
fn test_posix_gettimeofday() {
@@ -293,11 +296,11 @@ fn main() {
293296
test_thread_local_errno();
294297

295298
test_isatty();
299+
test_clocks();
296300

297301
#[cfg(target_os = "linux")]
298302
{
299303
test_posix_fadvise();
300304
test_sync_file_range();
301-
test_clocks();
302305
}
303306
}

0 commit comments

Comments
 (0)