diff options
| author | Chris Denton <chris@chrisdenton.dev> | 2024-03-03 22:06:00 +0000 |
|---|---|---|
| committer | Chris Denton <chris@chrisdenton.dev> | 2024-03-05 00:19:42 +0000 |
| commit | f700641bd9eb7ec3b36b4d44eafae35ba970eea4 (patch) | |
| tree | 2bcda35248fd9a6b15cd821e97e666549e44c36f /src/tools | |
| parent | 89b78304e82dc5114e3b2faa0fbec747a28a2b37 (diff) | |
| download | rust-f700641bd9eb7ec3b36b4d44eafae35ba970eea4.tar.gz rust-f700641bd9eb7ec3b36b4d44eafae35ba970eea4.zip | |
Windows: Implement mutex using futex
Well, the Windows equivalent: `WaitOnAddress`, `WakeByAddressSingle` and `WakeByAddressAll`.
Diffstat (limited to 'src/tools')
| -rw-r--r-- | src/tools/miri/src/shims/windows/foreign_items.rs | 6 | ||||
| -rw-r--r-- | src/tools/miri/src/shims/windows/sync.rs | 15 |
2 files changed, 21 insertions, 0 deletions
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs index 734737a86dd..f56ea06dbe3 100644 --- a/src/tools/miri/src/shims/windows/foreign_items.rs +++ b/src/tools/miri/src/shims/windows/foreign_items.rs @@ -366,6 +366,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { this.WakeByAddressSingle(ptr_op)?; } + "WakeByAddressAll" => { + let [ptr_op] = + this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?; + + this.WakeByAddressAll(ptr_op)?; + } // Dynamic symbol loading "GetProcAddress" => { diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs index 2b9801fea68..1ce385aaaba 100644 --- a/src/tools/miri/src/shims/windows/sync.rs +++ b/src/tools/miri/src/shims/windows/sync.rs @@ -384,6 +384,21 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> { Ok(()) } + fn WakeByAddressAll(&mut self, ptr_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> { + let this = self.eval_context_mut(); + + let ptr = this.read_pointer(ptr_op)?; + + // See the Linux futex implementation for why this fence exists. + this.atomic_fence(AtomicFenceOrd::SeqCst)?; + + while let Some(thread) = this.futex_wake(ptr.addr().bytes(), u32::MAX) { + this.unblock_thread(thread); + this.unregister_timeout_callback_if_exists(thread); + } + + Ok(()) + } fn SleepConditionVariableSRW( &mut self, |
