@@ -366,65 +366,60 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
366
366
& mut self ,
367
367
clock_id : & OpTy < ' tcx > ,
368
368
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.
371
371
) -> InterpResult < ' tcx , Scalar > {
372
372
let this = self . eval_context_mut ( ) ;
373
373
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" ) ;
385
386
}
386
387
387
- let req = this. deref_pointer_as ( req_op, this. libc_ty_layout ( "timespec" ) ) ?;
388
388
let duration = match this. read_timespec ( & req) ? {
389
389
Some ( duration) => duration,
390
390
None => {
391
391
return this. set_last_error_and_return_i32 ( LibcError ( "EINVAL" ) ) ;
392
392
}
393
393
} ;
394
394
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
424
403
} else {
425
404
// 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 ) )
428
423
}
429
424
430
425
#[ allow( non_snake_case) ]
0 commit comments