1+ use std:: time:: SystemTime ;
2+
13use crate :: concurrency:: thread:: { MachineCallback , Time } ;
24use crate :: * ;
3- use rustc_target:: abi:: { Align , Size } ;
4- use std:: time:: SystemTime ;
55
66/// Implementation of the SYS_futex syscall.
77/// `args` is the arguments *after* the syscall number.
@@ -28,13 +28,14 @@ pub fn futex<'tcx>(
2828 // The first three arguments (after the syscall number itself) are the same to all futex operations:
2929 // (int *addr, int op, int val).
3030 // We checked above that these definitely exist.
31- let addr = this. read_immediate ( & args[ 0 ] ) ?;
31+ let addr = this. read_pointer ( & args[ 0 ] ) ?;
3232 let op = this. read_scalar ( & args[ 1 ] ) ?. to_i32 ( ) ?;
3333 let val = this. read_scalar ( & args[ 2 ] ) ?. to_i32 ( ) ?;
3434
3535 let thread = this. get_active_thread ( ) ;
36- let addr_scalar = addr. to_scalar ( ) ;
37- let addr_usize = addr_scalar. to_machine_usize ( this) ?;
36+ // This is a vararg function so we have to bring our own type for this pointer.
37+ let addr = MPlaceTy :: from_aligned_ptr ( addr, this. machine . layouts . i32 ) ;
38+ let addr_usize = addr. ptr . addr ( ) . bytes ( ) ;
3839
3940 let futex_private = this. eval_libc_i32 ( "FUTEX_PRIVATE_FLAG" ) ?;
4041 let futex_wait = this. eval_libc_i32 ( "FUTEX_WAIT" ) ?;
@@ -117,15 +118,6 @@ pub fn futex<'tcx>(
117118 }
118119 } )
119120 } ;
120- // Check the pointer for alignment and validity.
121- // The API requires `addr` to be a 4-byte aligned pointer, and will
122- // use the 4 bytes at the given address as an (atomic) i32.
123- this. check_ptr_access_align (
124- addr_scalar. to_pointer ( this) ?,
125- Size :: from_bytes ( 4 ) ,
126- Align :: from_bytes ( 4 ) . unwrap ( ) ,
127- CheckInAllocMsg :: MemoryAccessTest ,
128- ) ?;
129121 // There may be a concurrent thread changing the value of addr
130122 // and then invoking the FUTEX_WAKE syscall. It is critical that the
131123 // effects of this and the other thread are correctly observed,
@@ -172,14 +164,7 @@ pub fn futex<'tcx>(
172164 this. atomic_fence ( AtomicFenceOrd :: SeqCst ) ?;
173165 // Read an `i32` through the pointer, regardless of any wrapper types.
174166 // It's not uncommon for `addr` to be passed as another type than `*mut i32`, such as `*const AtomicI32`.
175- let futex_val = this
176- . read_scalar_at_offset_atomic (
177- & addr. into ( ) ,
178- 0 ,
179- this. machine . layouts . i32 ,
180- AtomicReadOrd :: Relaxed ,
181- ) ?
182- . to_i32 ( ) ?;
167+ let futex_val = this. read_scalar_atomic ( & addr, AtomicReadOrd :: Relaxed ) ?. to_i32 ( ) ?;
183168 if val == futex_val {
184169 // The value still matches, so we block the thread make it wait for FUTEX_WAKE.
185170 this. block_thread ( thread) ;
0 commit comments