1
+ use std:: time:: SystemTime ;
2
+
1
3
use crate :: concurrency:: thread:: { MachineCallback , Time } ;
2
4
use crate :: * ;
3
- use rustc_target:: abi:: { Align , Size } ;
4
- use std:: time:: SystemTime ;
5
5
6
6
/// Implementation of the SYS_futex syscall.
7
7
/// `args` is the arguments *after* the syscall number.
@@ -28,13 +28,14 @@ pub fn futex<'tcx>(
28
28
// The first three arguments (after the syscall number itself) are the same to all futex operations:
29
29
// (int *addr, int op, int val).
30
30
// We checked above that these definitely exist.
31
- let addr = this. read_immediate ( & args[ 0 ] ) ?;
31
+ let addr = this. read_pointer ( & args[ 0 ] ) ?;
32
32
let op = this. read_scalar ( & args[ 1 ] ) ?. to_i32 ( ) ?;
33
33
let val = this. read_scalar ( & args[ 2 ] ) ?. to_i32 ( ) ?;
34
34
35
35
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 ( ) ;
38
39
39
40
let futex_private = this. eval_libc_i32 ( "FUTEX_PRIVATE_FLAG" ) ?;
40
41
let futex_wait = this. eval_libc_i32 ( "FUTEX_WAIT" ) ?;
@@ -117,15 +118,6 @@ pub fn futex<'tcx>(
117
118
}
118
119
} )
119
120
} ;
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
- ) ?;
129
121
// There may be a concurrent thread changing the value of addr
130
122
// and then invoking the FUTEX_WAKE syscall. It is critical that the
131
123
// effects of this and the other thread are correctly observed,
@@ -172,14 +164,7 @@ pub fn futex<'tcx>(
172
164
this. atomic_fence ( AtomicFenceOrd :: SeqCst ) ?;
173
165
// Read an `i32` through the pointer, regardless of any wrapper types.
174
166
// 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 ( ) ?;
183
168
if val == futex_val {
184
169
// The value still matches, so we block the thread make it wait for FUTEX_WAKE.
185
170
this. block_thread ( thread) ;
0 commit comments