@@ -362,6 +362,71 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
362
362
interp_ok ( Scalar :: from_i32 ( 0 ) )
363
363
}
364
364
365
+ fn clock_nanosleep (
366
+ & mut self ,
367
+ clock_id : & OpTy < ' tcx > ,
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.
371
+ ) -> InterpResult < ' tcx , Scalar > {
372
+ let this = self . eval_context_mut ( ) ;
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" ) ) ,
385
+ }
386
+
387
+ let req = this. deref_pointer_as ( req_op, this. libc_ty_layout ( "timespec" ) ) ?;
388
+ let duration = match this. read_timespec ( & req) ? {
389
+ Some ( duration) => duration,
390
+ None => {
391
+ return this. set_last_error_and_return_i32 ( LibcError ( "EINVAL" ) ) ;
392
+ }
393
+ } ;
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 ) )
424
+ } else {
425
+ // 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
+ }
428
+ }
429
+
365
430
#[ allow( non_snake_case) ]
366
431
fn Sleep ( & mut self , timeout : & OpTy < ' tcx > ) -> InterpResult < ' tcx > {
367
432
let this = self . eval_context_mut ( ) ;
0 commit comments