From 5f6d250b303d839896ead366153997d0e8e013e0 Mon Sep 17 00:00:00 2001 From: Samrat Man Singh Date: Mon, 13 Apr 2020 21:18:34 +0530 Subject: [PATCH] [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 --- src/shims/foreign_items/posix/macos.rs | 5 +++++ src/shims/time.rs | 22 ++++++++++++++++++++++ tests/run-pass/time.rs | 15 ++++++--------- 3 files changed, 33 insertions(+), 9 deletions(-) diff --git a/src/shims/foreign_items/posix/macos.rs b/src/shims/foreign_items/posix/macos.rs index 9810a77ffde1..e7baacf7274d 100644 --- a/src/shims/foreign_items/posix/macos.rs +++ b/src/shims/foreign_items/posix/macos.rs @@ -60,6 +60,11 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx this.write_scalar(Scalar::from_u64(result), dest)?; } + "mach_timebase_info" => { + let result = this.mach_timebase_info(args[0])?; + this.write_scalar(Scalar::from_i32(result), dest)?; + }, + // Access to command-line arguments "_NSGetArgc" => { this.write_scalar(this.machine.argc.expect("machine must be initialized"), dest)?; diff --git a/src/shims/time.rs b/src/shims/time.rs index 0d7a4929e4e0..adcca21fb4c0 100644 --- a/src/shims/time.rs +++ b/src/shims/time.rs @@ -13,6 +13,7 @@ pub fn system_time_to_duration<'tcx>(time: &SystemTime) -> InterpResult<'tcx, Du .map_err(|_| err_unsup_format!("times before the Unix epoch are not supported").into()) } + impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriEvalContext<'mir, 'tcx> {} pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx> { fn clock_gettime( @@ -159,4 +160,25 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriEvalContextExt<'mir, 'tcx u64::try_from(duration.as_nanos()) .map_err(|_| err_unsup_format!("programs running longer than 2^64 nanoseconds are not supported").into()) } + + fn mach_timebase_info(&mut self, info_op: OpTy<'tcx, Tag>) -> InterpResult<'tcx, i32> { + let this = self.eval_context_mut(); + + this.assert_target_os("macos", "mach_timebase_info"); + this.check_no_isolation("mach_timebase_info")?; + + let info = this.deref_operand(info_op)?; + + // Since we return nanoseceonds instead of ticks from + // `mach_absolute_time`, we don't need to scale the absolute + // time. + let (numer, denom) = (1,1); + let imms = [ + immty_from_int_checked(numer, this.libc_ty_layout("uint32_t")?)?, + immty_from_int_checked(denom, this.libc_ty_layout("uint32_t")?)? + ]; + + this.write_packed_immediates(info, &imms)?; + Ok(0) + } } diff --git a/tests/run-pass/time.rs b/tests/run-pass/time.rs index aa02ac15388e..9ae64fbae42a 100644 --- a/tests/run-pass/time.rs +++ b/tests/run-pass/time.rs @@ -25,13 +25,10 @@ fn main() { let now2 = Instant::now(); assert!(now2 > now1); - #[cfg(not(target_os = "macos"))] // TODO: macOS does not support Instant subtraction - { - let diff = now2.duration_since(now1); - assert_eq!(now1 + diff, now2); - assert_eq!(now2 - diff, now1); - // Sanity-check the difference we got. - assert!(diff.as_micros() > 1); - assert!(diff.as_micros() < 1_000_000); - } + let diff = now2.duration_since(now1); + assert_eq!(now1 + diff, now2); + assert_eq!(now2 - diff, now1); + // Sanity-check the difference we got. + assert!(diff.as_micros() > 1); + assert!(diff.as_micros() < 1_000_000); }