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)?;
.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(
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)
+ }
}
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);
}