Skip to content

Commit 834de52

Browse files
committed
add and update futex comments
1 parent 2cd4af1 commit 834de52

File tree

4 files changed

+20
-9
lines changed

4 files changed

+20
-9
lines changed

src/concurrency/sync.rs

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -734,11 +734,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
734734
interp_ok(true)
735735
}
736736

737-
/// Wait for the futex to be signaled, or a timeout.
738-
/// * On a signal, `retval_succ` is called with the number of waiters on the
739-
/// futex and its result is written to `dest`.
740-
/// * On a timeout, `retval_timeout` is written to `dest` and `errno_timeout`
741-
/// is set as the last error.
737+
/// Wait for the futex to be signaled, or a timeout. Once the thread is
738+
/// unblocked, `callback` is called with the unblock reason.
742739
fn futex_wait(
743740
&mut self,
744741
futex_ref: FutexRef,

src/shims/unix/macos/foreign_items.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
222222
this.write_scalar(res, dest)?;
223223
}
224224

225+
// Futex primitives
225226
"os_sync_wait_on_address" => {
226227
let [addr_op, value_op, size_op, flags_op] =
227228
this.check_shim(abi, Conv::C, link_name, args)?;
@@ -261,12 +262,16 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
261262
"os_sync_wake_by_address_any" => {
262263
let [addr_op, size_op, flags_op] =
263264
this.check_shim(abi, Conv::C, link_name, args)?;
264-
this.os_sync_wake_by_address(addr_op, size_op, flags_op, false, dest)?;
265+
this.os_sync_wake_by_address(
266+
addr_op, size_op, flags_op, /* all */ false, dest,
267+
)?;
265268
}
266269
"os_sync_wake_by_address_all" => {
267270
let [addr_op, size_op, flags_op] =
268271
this.check_shim(abi, Conv::C, link_name, args)?;
269-
this.os_sync_wake_by_address(addr_op, size_op, flags_op, true, dest)?;
272+
this.os_sync_wake_by_address(
273+
addr_op, size_op, flags_op, /* all */ true, dest,
274+
)?;
270275
}
271276

272277
"os_unfair_lock_lock" => {

src/shims/unix/macos/sync.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,9 @@ pub enum MacOsFutexTimeout<'a, 'tcx> {
3838
/// This structure keeps track of both the futex queue and these values.
3939
struct MacOsFutex {
4040
futex: FutexRef,
41+
/// The size in bytes of the atomic primitive underlying this futex.
4142
size: Cell<u64>,
43+
/// Whether the futex is shared across process boundaries.
4244
shared: Cell<bool>,
4345
}
4446

@@ -153,7 +155,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
153155
};
154156

155157
// Detect mismatches between the flags and sizes used on this address
156-
// by storing the parameters of the first waiter in a batch of waiters.
158+
// by comparing with the parameters stored with the first waiter.
157159
if futex.futex.waiters() == 0 {
158160
futex.size.set(size);
159161
futex.shared.set(is_shared);
@@ -233,6 +235,11 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
233235
shared: Cell::new(is_shared),
234236
}
235237
}) else {
238+
// No AllocId, or no live allocation at that AllocId. Return an
239+
// error code. (That seems nicer than silently doing something
240+
// non-intuitive.) This means that if an address gets reused by a
241+
// new allocation, we'll use an independent futex queue for this...
242+
// that seems acceptable.
236243
this.set_last_error_and_return(LibcError("ENOENT"), dest)?;
237244
return interp_ok(());
238245
};

tests/pass-dep/concurrency/apple-futex.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use std::{io, ptr, thread};
66
fn wake_nobody() {
77
let futex = 0;
88

9-
// Wake 1 waiter. Expect zero waiters woken up, as nobody is waiting.
9+
// Wake 1 waiter. Expect ENOENT woken up, as nobody is waiting.
1010
unsafe {
1111
assert_eq!(
1212
libc::os_sync_wake_by_address_any(
@@ -181,6 +181,7 @@ fn param_mismatch() {
181181
),
182182
-1,
183183
);
184+
// This call fails because it uses the shared flag whereas the first waiter didn't.
184185
assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
185186
}
186187
});
@@ -195,6 +196,7 @@ fn param_mismatch() {
195196
),
196197
-1,
197198
);
199+
// This call fails because it uses the shared flag whereas the waiter didn't.
198200
assert_eq!(io::Error::last_os_error().raw_os_error().unwrap(), libc::EINVAL);
199201
}
200202
});

0 commit comments

Comments
 (0)