diff options
| author | bors <bors@rust-lang.org> | 2024-03-06 12:19:40 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2024-03-06 12:19:40 +0000 |
| commit | 3314d5ce4c209e840c2e4b2c4442f6e031ae0989 (patch) | |
| tree | 76e2b5df951aadb1db86b55c6efcb1f63906320e /src | |
| parent | 09bc67b9158392361780e779d32997f14cc75c39 (diff) | |
| parent | cf83d83c77eb9c5a08debc818156815ae5bf759f (diff) | |
| download | rust-3314d5ce4c209e840c2e4b2c4442f6e031ae0989.tar.gz rust-3314d5ce4c209e840c2e4b2c4442f6e031ae0989.zip | |
Auto merge of #121956 - ChrisDenton:srwlock, r=joboet
Windows: Implement condvar, mutex and rwlock using futex Well, the Windows equivalent: [`WaitOnAddress`,](https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitonaddress) [`WakeByAddressSingle`](https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-wakebyaddresssingle) and [`WakeByAddressAll`](https://learn.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-wakebyaddressall). Note that Windows flavoured futexes can be different sizes (1, 2, 4 or 8 bytes). I took advantage of that in the `Mutex` implementation. I also edited the Mutex implementation a bit more than necessary. I was having trouble keeping in my head what 0, 1 and 2 meant so I replaced them with consts. I *think* we're maybe spinning a bit much. `WaitOnAddress` seems to be looping quite a bit too. But for now I've keep the implementations the same. I do wonder if it'd be worth reducing or removing our spinning on Windows. This also adds a new shim to miri, because of course it does. Fixes #121949
Diffstat (limited to 'src')
| -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, |
