Skip to content

Commit bfbf1d3

Browse files
committed
windows: remove support for slim rwlock
Since rust-lang#121956 we don't need it any more, and we are generally short on Windows staff so reducing the amount of code we have to test and maintain sounds like a good idea. The InitOnce stuff is still used by `thread_local_key::StaticKey`.
1 parent 9a308d4 commit bfbf1d3

File tree

4 files changed

+0
-602
lines changed

4 files changed

+0
-602
lines changed

src/tools/miri/src/shims/windows/foreign_items.rs

-45
Original file line numberDiff line numberDiff line change
@@ -297,32 +297,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
297297
}
298298

299299
// Synchronization primitives
300-
"AcquireSRWLockExclusive" => {
301-
let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
302-
this.AcquireSRWLockExclusive(ptr)?;
303-
}
304-
"ReleaseSRWLockExclusive" => {
305-
let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
306-
this.ReleaseSRWLockExclusive(ptr)?;
307-
}
308-
"TryAcquireSRWLockExclusive" => {
309-
let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
310-
let ret = this.TryAcquireSRWLockExclusive(ptr)?;
311-
this.write_scalar(ret, dest)?;
312-
}
313-
"AcquireSRWLockShared" => {
314-
let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
315-
this.AcquireSRWLockShared(ptr)?;
316-
}
317-
"ReleaseSRWLockShared" => {
318-
let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
319-
this.ReleaseSRWLockShared(ptr)?;
320-
}
321-
"TryAcquireSRWLockShared" => {
322-
let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
323-
let ret = this.TryAcquireSRWLockShared(ptr)?;
324-
this.write_scalar(ret, dest)?;
325-
}
326300
"InitOnceBeginInitialize" => {
327301
let [ptr, flags, pending, context] =
328302
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
@@ -335,25 +309,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
335309
let result = this.InitOnceComplete(ptr, flags, context)?;
336310
this.write_scalar(result, dest)?;
337311
}
338-
"SleepConditionVariableSRW" => {
339-
let [condvar, lock, timeout, flags] =
340-
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
341-
342-
let result = this.SleepConditionVariableSRW(condvar, lock, timeout, flags, dest)?;
343-
this.write_scalar(result, dest)?;
344-
}
345-
"WakeConditionVariable" => {
346-
let [condvar] =
347-
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
348-
349-
this.WakeConditionVariable(condvar)?;
350-
}
351-
"WakeAllConditionVariable" => {
352-
let [condvar] =
353-
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
354-
355-
this.WakeAllConditionVariable(condvar)?;
356-
}
357312
"WaitOnAddress" => {
358313
let [ptr_op, compare_op, size_op, timeout_op] =
359314
this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;

src/tools/miri/src/shims/windows/sync.rs

-271
Original file line numberDiff line numberDiff line change
@@ -3,170 +3,26 @@ use std::time::Duration;
33
use rustc_target::abi::Size;
44

55
use crate::concurrency::init_once::InitOnceStatus;
6-
use crate::concurrency::sync::{CondvarLock, RwLockMode};
76
use crate::concurrency::thread::MachineCallback;
87
use crate::*;
98

109
impl<'mir, 'tcx> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
1110
trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
12-
/// Try to reacquire the lock associated with the condition variable after we
13-
/// were signaled.
14-
fn reacquire_cond_lock(
15-
&mut self,
16-
thread: ThreadId,
17-
lock: RwLockId,
18-
mode: RwLockMode,
19-
) -> InterpResult<'tcx> {
20-
let this = self.eval_context_mut();
21-
this.unblock_thread(thread);
22-
23-
match mode {
24-
RwLockMode::Read =>
25-
if this.rwlock_is_write_locked(lock) {
26-
this.rwlock_enqueue_and_block_reader(lock, thread);
27-
} else {
28-
this.rwlock_reader_lock(lock, thread);
29-
},
30-
RwLockMode::Write =>
31-
if this.rwlock_is_locked(lock) {
32-
this.rwlock_enqueue_and_block_writer(lock, thread);
33-
} else {
34-
this.rwlock_writer_lock(lock, thread);
35-
},
36-
}
37-
38-
Ok(())
39-
}
40-
4111
// Windows sync primitives are pointer sized.
4212
// We only use the first 4 bytes for the id.
4313

44-
fn srwlock_get_id(
45-
&mut self,
46-
rwlock_op: &OpTy<'tcx, Provenance>,
47-
) -> InterpResult<'tcx, RwLockId> {
48-
let this = self.eval_context_mut();
49-
this.rwlock_get_or_create_id(rwlock_op, this.windows_ty_layout("SRWLOCK"), 0)
50-
}
51-
5214
fn init_once_get_id(
5315
&mut self,
5416
init_once_op: &OpTy<'tcx, Provenance>,
5517
) -> InterpResult<'tcx, InitOnceId> {
5618
let this = self.eval_context_mut();
5719
this.init_once_get_or_create_id(init_once_op, this.windows_ty_layout("INIT_ONCE"), 0)
5820
}
59-
60-
fn condvar_get_id(
61-
&mut self,
62-
condvar_op: &OpTy<'tcx, Provenance>,
63-
) -> InterpResult<'tcx, CondvarId> {
64-
let this = self.eval_context_mut();
65-
this.condvar_get_or_create_id(condvar_op, this.windows_ty_layout("CONDITION_VARIABLE"), 0)
66-
}
6721
}
6822

6923
impl<'mir, 'tcx> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
7024
#[allow(non_snake_case)]
7125
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
72-
fn AcquireSRWLockExclusive(&mut self, lock_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
73-
let this = self.eval_context_mut();
74-
let id = this.srwlock_get_id(lock_op)?;
75-
let active_thread = this.get_active_thread();
76-
77-
if this.rwlock_is_locked(id) {
78-
// Note: this will deadlock if the lock is already locked by this
79-
// thread in any way.
80-
//
81-
// FIXME: Detect and report the deadlock proactively. (We currently
82-
// report the deadlock only when no thread can continue execution,
83-
// but we could detect that this lock is already locked and report
84-
// an error.)
85-
this.rwlock_enqueue_and_block_writer(id, active_thread);
86-
} else {
87-
this.rwlock_writer_lock(id, active_thread);
88-
}
89-
90-
Ok(())
91-
}
92-
93-
fn TryAcquireSRWLockExclusive(
94-
&mut self,
95-
lock_op: &OpTy<'tcx, Provenance>,
96-
) -> InterpResult<'tcx, Scalar<Provenance>> {
97-
let this = self.eval_context_mut();
98-
let id = this.srwlock_get_id(lock_op)?;
99-
let active_thread = this.get_active_thread();
100-
101-
if this.rwlock_is_locked(id) {
102-
// Lock is already held.
103-
Ok(Scalar::from_u8(0))
104-
} else {
105-
this.rwlock_writer_lock(id, active_thread);
106-
Ok(Scalar::from_u8(1))
107-
}
108-
}
109-
110-
fn ReleaseSRWLockExclusive(&mut self, lock_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
111-
let this = self.eval_context_mut();
112-
let id = this.srwlock_get_id(lock_op)?;
113-
let active_thread = this.get_active_thread();
114-
115-
if !this.rwlock_writer_unlock(id, active_thread) {
116-
// The docs do not say anything about this case, but it seems better to not allow it.
117-
throw_ub_format!(
118-
"calling ReleaseSRWLockExclusive on an SRWLock that is not exclusively locked by the current thread"
119-
);
120-
}
121-
122-
Ok(())
123-
}
124-
125-
fn AcquireSRWLockShared(&mut self, lock_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
126-
let this = self.eval_context_mut();
127-
let id = this.srwlock_get_id(lock_op)?;
128-
let active_thread = this.get_active_thread();
129-
130-
if this.rwlock_is_write_locked(id) {
131-
this.rwlock_enqueue_and_block_reader(id, active_thread);
132-
} else {
133-
this.rwlock_reader_lock(id, active_thread);
134-
}
135-
136-
Ok(())
137-
}
138-
139-
fn TryAcquireSRWLockShared(
140-
&mut self,
141-
lock_op: &OpTy<'tcx, Provenance>,
142-
) -> InterpResult<'tcx, Scalar<Provenance>> {
143-
let this = self.eval_context_mut();
144-
let id = this.srwlock_get_id(lock_op)?;
145-
let active_thread = this.get_active_thread();
146-
147-
if this.rwlock_is_write_locked(id) {
148-
Ok(Scalar::from_u8(0))
149-
} else {
150-
this.rwlock_reader_lock(id, active_thread);
151-
Ok(Scalar::from_u8(1))
152-
}
153-
}
154-
155-
fn ReleaseSRWLockShared(&mut self, lock_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
156-
let this = self.eval_context_mut();
157-
let id = this.srwlock_get_id(lock_op)?;
158-
let active_thread = this.get_active_thread();
159-
160-
if !this.rwlock_reader_unlock(id, active_thread) {
161-
// The docs do not say anything about this case, but it seems better to not allow it.
162-
throw_ub_format!(
163-
"calling ReleaseSRWLockShared on an SRWLock that is not locked by the current thread"
164-
);
165-
}
166-
167-
Ok(())
168-
}
169-
17026
fn InitOnceBeginInitialize(
17127
&mut self,
17228
init_once_op: &OpTy<'tcx, Provenance>,
@@ -399,131 +255,4 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
399255

400256
Ok(())
401257
}
402-
403-
fn SleepConditionVariableSRW(
404-
&mut self,
405-
condvar_op: &OpTy<'tcx, Provenance>,
406-
lock_op: &OpTy<'tcx, Provenance>,
407-
timeout_op: &OpTy<'tcx, Provenance>,
408-
flags_op: &OpTy<'tcx, Provenance>,
409-
dest: &MPlaceTy<'tcx, Provenance>,
410-
) -> InterpResult<'tcx, Scalar<Provenance>> {
411-
let this = self.eval_context_mut();
412-
413-
let condvar_id = this.condvar_get_id(condvar_op)?;
414-
let lock_id = this.srwlock_get_id(lock_op)?;
415-
let timeout_ms = this.read_scalar(timeout_op)?.to_u32()?;
416-
let flags = this.read_scalar(flags_op)?.to_u32()?;
417-
418-
let timeout_time = if timeout_ms == this.eval_windows_u32("c", "INFINITE") {
419-
None
420-
} else {
421-
let duration = Duration::from_millis(timeout_ms.into());
422-
Some(this.machine.clock.now().checked_add(duration).unwrap())
423-
};
424-
425-
let shared_mode = 0x1; // CONDITION_VARIABLE_LOCKMODE_SHARED is not in std
426-
let mode = if flags == 0 {
427-
RwLockMode::Write
428-
} else if flags == shared_mode {
429-
RwLockMode::Read
430-
} else {
431-
throw_unsup_format!("unsupported `Flags` {flags} in `SleepConditionVariableSRW`");
432-
};
433-
434-
let active_thread = this.get_active_thread();
435-
436-
let was_locked = match mode {
437-
RwLockMode::Read => this.rwlock_reader_unlock(lock_id, active_thread),
438-
RwLockMode::Write => this.rwlock_writer_unlock(lock_id, active_thread),
439-
};
440-
441-
if !was_locked {
442-
throw_ub_format!(
443-
"calling SleepConditionVariableSRW with an SRWLock that is not locked by the current thread"
444-
);
445-
}
446-
447-
this.block_thread(active_thread);
448-
this.condvar_wait(condvar_id, active_thread, CondvarLock::RwLock { id: lock_id, mode });
449-
450-
if let Some(timeout_time) = timeout_time {
451-
struct Callback<'tcx> {
452-
thread: ThreadId,
453-
condvar_id: CondvarId,
454-
lock_id: RwLockId,
455-
mode: RwLockMode,
456-
dest: MPlaceTy<'tcx, Provenance>,
457-
}
458-
459-
impl<'tcx> VisitProvenance for Callback<'tcx> {
460-
fn visit_provenance(&self, visit: &mut VisitWith<'_>) {
461-
let Callback { thread: _, condvar_id: _, lock_id: _, mode: _, dest } = self;
462-
dest.visit_provenance(visit);
463-
}
464-
}
465-
466-
impl<'mir, 'tcx: 'mir> MachineCallback<'mir, 'tcx> for Callback<'tcx> {
467-
fn call(&self, this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
468-
this.reacquire_cond_lock(self.thread, self.lock_id, self.mode)?;
469-
470-
this.condvar_remove_waiter(self.condvar_id, self.thread);
471-
472-
let error_timeout = this.eval_windows("c", "ERROR_TIMEOUT");
473-
this.set_last_error(error_timeout)?;
474-
this.write_scalar(this.eval_windows("c", "FALSE"), &self.dest)?;
475-
Ok(())
476-
}
477-
}
478-
479-
this.register_timeout_callback(
480-
active_thread,
481-
Time::Monotonic(timeout_time),
482-
Box::new(Callback {
483-
thread: active_thread,
484-
condvar_id,
485-
lock_id,
486-
mode,
487-
dest: dest.clone(),
488-
}),
489-
);
490-
}
491-
492-
Ok(this.eval_windows("c", "TRUE"))
493-
}
494-
495-
fn WakeConditionVariable(&mut self, condvar_op: &OpTy<'tcx, Provenance>) -> InterpResult<'tcx> {
496-
let this = self.eval_context_mut();
497-
let condvar_id = this.condvar_get_id(condvar_op)?;
498-
499-
if let Some((thread, lock)) = this.condvar_signal(condvar_id) {
500-
if let CondvarLock::RwLock { id, mode } = lock {
501-
this.reacquire_cond_lock(thread, id, mode)?;
502-
this.unregister_timeout_callback_if_exists(thread);
503-
} else {
504-
panic!("mutexes should not exist on windows");
505-
}
506-
}
507-
508-
Ok(())
509-
}
510-
511-
fn WakeAllConditionVariable(
512-
&mut self,
513-
condvar_op: &OpTy<'tcx, Provenance>,
514-
) -> InterpResult<'tcx> {
515-
let this = self.eval_context_mut();
516-
let condvar_id = this.condvar_get_id(condvar_op)?;
517-
518-
while let Some((thread, lock)) = this.condvar_signal(condvar_id) {
519-
if let CondvarLock::RwLock { id, mode } = lock {
520-
this.reacquire_cond_lock(thread, id, mode)?;
521-
this.unregister_timeout_callback_if_exists(thread);
522-
} else {
523-
panic!("mutexes should not exist on windows");
524-
}
525-
}
526-
527-
Ok(())
528-
}
529258
}

0 commit comments

Comments
 (0)