@@ -366,65 +366,60 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
366366 & mut self ,
367367 clock_id : & OpTy < ' tcx > ,
368368 flags : & OpTy < ' tcx > ,
369- req_op : & OpTy < ' tcx > ,
370- _rem : & OpTy < ' tcx > , // Signal handlers are not supported, so rem will never be written to.
369+ req : & OpTy < ' tcx > ,
370+ rem : & OpTy < ' tcx > , // Signal handlers are not supported, so rem will never be written to.
371371 ) -> InterpResult < ' tcx , Scalar > {
372372 let this = self . eval_context_mut ( ) ;
373373
374- let clock_id: libc:: clockid_t = this. read_scalar ( clock_id) ?. to_i32 ( ) ?;
375- match clock_id {
376- libc:: CLOCK_MONOTONIC => ( ) ,
377- libc:: CLOCK_REALTIME
378- | libc:: CLOCK_TAI
379- | libc:: CLOCK_BOOTTIME
380- | libc:: CLOCK_PROCESS_CPUTIME_ID => {
381- // The standard lib through sleep_until only needs CLOCK_MONOTONIC
382- panic ! ( "MIRI only supports CLOCK_MONOTONIC for clock_nanosleep" )
383- }
384- _other => return this. set_last_error_and_return_i32 ( LibcError ( "EINVAL" ) ) ,
374+ let clockid_t_size = this. libc_ty_layout ( "clockid_t" ) . size ;
375+ let clock_id = this. read_scalar ( clock_id_op) ?. to_int ( clockid_t_size) ?;
376+ let req = this. deref_pointer_as ( req_op, this. libc_ty_layout ( "timespec" ) ) ?;
377+ // TODO must be a better way to do this, also fix the
378+ // if compare of the flags later
379+ let int_size = this. libc_ty_layout ( "int" ) . size ;
380+ let flags = this. read_scalar ( flags) ?. to_int ( int_size) ;
381+ let rem = this. read_pointer ( ) ?;
382+
383+ // The standard lib through sleep_until only needs CLOCK_MONOTONIC
384+ if clock_id != this. eval_libc ( "CLOCK_MONOTONIC" ) . to_int ( clockid_t_size) ? {
385+ throw_unsup_format ! ( "clock_nanosleep: only CLOCK_MONOTONIC is supported" ) ;
385386 }
386387
387- let req = this. deref_pointer_as ( req_op, this. libc_ty_layout ( "timespec" ) ) ?;
388388 let duration = match this. read_timespec ( & req) ? {
389389 Some ( duration) => duration,
390390 None => {
391391 return this. set_last_error_and_return_i32 ( LibcError ( "EINVAL" ) ) ;
392392 }
393393 } ;
394394
395- let flags: libc:: c_int = this. read_scalar ( flags) ?. to_i32 ( ) ?;
396- if flags == 0 {
397- this. block_thread (
398- BlockReason :: Sleep ,
399- Some ( ( TimeoutClock :: Monotonic , TimeoutAnchor :: Relative , duration) ) ,
400- callback ! (
401- @capture<' tcx> { }
402- |_this, unblock: UnblockKind | {
403- assert_eq!( unblock, UnblockKind :: TimedOut ) ;
404- interp_ok( ( ) )
405- }
406- ) ,
407- ) ;
408- interp_ok ( Scalar :: from_i32 ( 0 ) )
409- } else if flags == libc:: TIMER_ABSTIME {
410- this. block_thread (
411- BlockReason :: Sleep ,
412- Some ( ( TimeoutClock :: Monotonic , TimeoutAnchor :: Absolute , duration) ) ,
413- // PR Author review note: no idea what this does, I copied it
414- // form nanosleep, please check carefully if it is correct
415- callback ! (
416- @capture<' tcx> { }
417- |_this, unblock: UnblockKind | {
418- assert_eq!( unblock, UnblockKind :: TimedOut ) ;
419- interp_ok( ( ) )
420- }
421- ) ,
422- ) ;
423- interp_ok ( Scalar :: from_i32 ( 0 ) )
395+ let timeout_anchor = if flags == 0 {
396+ // No flags set, the timespec should be interperted as a duration
397+ // to sleep for
398+ TimeoutAnchor :: Relative
399+ } else if flag == this. eval_libc ( "TIMER_ABSTIME" ) . to_int ( int_size) {
400+ // Only flag TIMER_ABSTIME set, the timespec should be interperted as
401+ // an absolute time.
402+ TimeoutAnchor :: Absolute
424403 } else {
425404 // The standard lib through sleep_until only needs TIMER_ABSTIME
426- panic ! ( "MIRI only supports no flags (0) or flag TIMER_ABSTIME for clock_nanosleep" )
427- }
405+ throw_unsup_format ! (
406+ "`clock_nanosleep` unsupported flags {flags}, only no flags or\
407+ TIMER_ABSTIME is supported"
408+ ) ;
409+ } ;
410+
411+ this. block_thread (
412+ BlockReason :: Sleep ,
413+ Some ( ( TimeoutClock :: Monotonic , timeout_anchor, duration) ) ,
414+ callback ! (
415+ @capture<' tcx> { }
416+ |_this, unblock: UnblockKind | {
417+ assert_eq!( unblock, UnblockKind :: TimedOut ) ;
418+ interp_ok( ( ) )
419+ }
420+ ) ,
421+ ) ;
422+ interp_ok ( Scalar :: from_i32 ( 0 ) )
428423 }
429424
430425 #[ allow( non_snake_case) ]
0 commit comments