Skip to content

Commit 5f6d250

Browse files
committed
[macOS] Implement mach_timebase_info
Since we return nanoseceonds instead of ticks from `mach_absolute_time`, we don't need to scale the absolute time
1 parent 4545eff commit 5f6d250

File tree

3 files changed

+33
-9
lines changed

3 files changed

+33
-9
lines changed

src/shims/foreign_items/posix/macos.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
6060
this.write_scalar(Scalar::from_u64(result), dest)?;
6161
}
6262

63+
"mach_timebase_info" => {
64+
let result = this.mach_timebase_info(args[0])?;
65+
this.write_scalar(Scalar::from_i32(result), dest)?;
66+
},
67+
6368
// Access to command-line arguments
6469
"_NSGetArgc" => {
6570
this.write_scalar(this.machine.argc.expect("machine must be initialized"), dest)?;

src/shims/time.rs

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ pub fn system_time_to_duration<'tcx>(time: &SystemTime) -> InterpResult<'tcx, Du
1313
.map_err(|_| err_unsup_format!("times before the Unix epoch are not supported").into())
1414
}
1515

16+
1617
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {}
1718
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> {
1819
fn clock_gettime(
@@ -159,4 +160,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx
159160
u64::try_from(duration.as_nanos())
160161
.map_err(|_| err_unsup_format!("programs running longer than 2^64 nanoseconds are not supported").into())
161162
}
163+
164+
fn mach_timebase_info(&mut self, info_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> {
165+
let this = self.eval_context_mut();
166+
167+
this.assert_target_os("macos", "mach_timebase_info");
168+
this.check_no_isolation("mach_timebase_info")?;
169+
170+
let info = this.deref_operand(info_op)?;
171+
172+
// Since we return nanoseceonds instead of ticks from
173+
// `mach_absolute_time`, we don't need to scale the absolute
174+
// time.
175+
let (numer, denom) = (1,1);
176+
let imms = [
177+
immty_from_int_checked(numer, this.libc_ty_layout("uint32_t")?)?,
178+
immty_from_int_checked(denom, this.libc_ty_layout("uint32_t")?)?
179+
];
180+
181+
this.write_packed_immediates(info, &imms)?;
182+
Ok(0)
183+
}
162184
}

tests/run-pass/time.rs

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,10 @@ fn main() {
2525
let now2 = Instant::now();
2626
assert!(now2 > now1);
2727

28-
#[cfg(not(target_os = "macos"))] // TODO: macOS does not support Instant subtraction
29-
{
30-
let diff = now2.duration_since(now1);
31-
assert_eq!(now1 + diff, now2);
32-
assert_eq!(now2 - diff, now1);
33-
// Sanity-check the difference we got.
34-
assert!(diff.as_micros() > 1);
35-
assert!(diff.as_micros() < 1_000_000);
36-
}
28+
let diff = now2.duration_since(now1);
29+
assert_eq!(now1 + diff, now2);
30+
assert_eq!(now2 - diff, now1);
31+
// Sanity-check the difference we got.
32+
assert!(diff.as_micros() > 1);
33+
assert!(diff.as_micros() < 1_000_000);
3734
}

0 commit comments

Comments
 (0)