Skip to content

Commit c9b37ba

Browse files
committed
use enum instead of bool for rwlock mode
1 parent e59ecbb commit c9b37ba

File tree

2 files changed

+41
-29
lines changed

2 files changed

+41
-29
lines changed

src/concurrency/sync.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,10 +116,16 @@ struct RwLock {
116116

117117
declare_id!(CondvarId);
118118

119+
#[derive(Debug, Copy, Clone)]
120+
pub enum RwLockMode {
121+
Shared,
122+
Exclusive,
123+
}
124+
119125
#[derive(Debug)]
120126
pub enum CondvarLock {
121127
Mutex(MutexId),
122-
RwLock { id: RwLockId, shared: bool },
128+
RwLock { id: RwLockId, mode: RwLockMode },
123129
}
124130

125131
/// A thread waiting on a conditional variable.

src/shims/windows/sync.rs

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::time::Duration;
33
use rustc_target::abi::Size;
44

55
use crate::concurrency::init_once::InitOnceStatus;
6-
use crate::concurrency::sync::CondvarLock;
6+
use crate::concurrency::sync::{CondvarLock, RwLockMode};
77
use crate::concurrency::thread::MachineCallback;
88
use crate::*;
99

@@ -19,23 +19,24 @@ trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
1919
&mut self,
2020
thread: ThreadId,
2121
lock: RwLockId,
22-
shared: bool,
22+
mode: RwLockMode,
2323
) -> InterpResult<'tcx> {
2424
let this = self.eval_context_mut();
2525
this.unblock_thread(thread);
2626

27-
if shared {
28-
if this.rwlock_is_write_locked(lock) {
29-
this.rwlock_enqueue_and_block_reader(lock, thread);
30-
} else {
31-
this.rwlock_reader_lock(lock, thread);
32-
}
33-
} else {
34-
if this.rwlock_is_locked(lock) {
35-
this.rwlock_enqueue_and_block_writer(lock, thread);
36-
} else {
37-
this.rwlock_writer_lock(lock, thread);
38-
}
27+
match mode {
28+
RwLockMode::Shared =>
29+
if this.rwlock_is_write_locked(lock) {
30+
this.rwlock_enqueue_and_block_reader(lock, thread);
31+
} else {
32+
this.rwlock_reader_lock(lock, thread);
33+
},
34+
RwLockMode::Exclusive =>
35+
if this.rwlock_is_locked(lock) {
36+
this.rwlock_enqueue_and_block_writer(lock, thread);
37+
} else {
38+
this.rwlock_writer_lock(lock, thread);
39+
},
3940
}
4041

4142
Ok(())
@@ -387,14 +388,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
387388
};
388389

389390
let shared_mode = 0x1; // CONDITION_VARIABLE_LOCKMODE_SHARED is not in std
390-
let shared = flags == shared_mode;
391+
let mode = if flags == 0 {
392+
RwLockMode::Exclusive
393+
} else if flags == shared_mode {
394+
RwLockMode::Shared
395+
} else {
396+
throw_unsup_format!("unsupported `Flags` {flags} in `SleepConditionVariableSRW`");
397+
};
391398

392399
let active_thread = this.get_active_thread();
393400

394-
let was_locked = if shared {
395-
this.rwlock_reader_unlock(lock_id, active_thread)
396-
} else {
397-
this.rwlock_writer_unlock(lock_id, active_thread)
401+
let was_locked = match mode {
402+
RwLockMode::Shared => this.rwlock_reader_unlock(lock_id, active_thread),
403+
RwLockMode::Exclusive => this.rwlock_writer_unlock(lock_id, active_thread),
398404
};
399405

400406
if !was_locked {
@@ -404,27 +410,27 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
404410
}
405411

406412
this.block_thread(active_thread);
407-
this.condvar_wait(condvar_id, active_thread, CondvarLock::RwLock { id: lock_id, shared });
413+
this.condvar_wait(condvar_id, active_thread, CondvarLock::RwLock { id: lock_id, mode });
408414

409415
if let Some(timeout_time) = timeout_time {
410416
struct Callback<'tcx> {
411417
thread: ThreadId,
412418
condvar_id: CondvarId,
413419
lock_id: RwLockId,
414-
shared: bool,
420+
mode: RwLockMode,
415421
dest: PlaceTy<'tcx, Provenance>,
416422
}
417423

418424
impl<'tcx> VisitTags for Callback<'tcx> {
419425
fn visit_tags(&self, visit: &mut dyn FnMut(SbTag)) {
420-
let Callback { thread: _, condvar_id: _, lock_id: _, shared: _, dest } = self;
426+
let Callback { thread: _, condvar_id: _, lock_id: _, mode: _, dest } = self;
421427
dest.visit_tags(visit);
422428
}
423429
}
424430

425431
impl<'mir, 'tcx: 'mir> MachineCallback<'mir, 'tcx> for Callback<'tcx> {
426432
fn call(&self, this: &mut MiriInterpCx<'mir, 'tcx>) -> InterpResult<'tcx> {
427-
this.reacquire_cond_lock(self.thread, self.lock_id, self.shared)?;
433+
this.reacquire_cond_lock(self.thread, self.lock_id, self.mode)?;
428434

429435
this.condvar_remove_waiter(self.condvar_id, self.thread);
430436

@@ -442,7 +448,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
442448
thread: active_thread,
443449
condvar_id,
444450
lock_id,
445-
shared,
451+
mode,
446452
dest: dest.clone(),
447453
}),
448454
);
@@ -456,8 +462,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
456462
let condvar_id = this.condvar_get_or_create_id(condvar_op, CONDVAR_ID_OFFSET)?;
457463

458464
if let Some((thread, lock)) = this.condvar_signal(condvar_id) {
459-
if let CondvarLock::RwLock { id, shared } = lock {
460-
this.reacquire_cond_lock(thread, id, shared)?;
465+
if let CondvarLock::RwLock { id, mode } = lock {
466+
this.reacquire_cond_lock(thread, id, mode)?;
461467
this.unregister_timeout_callback_if_exists(thread);
462468
} else {
463469
panic!("mutexes should not exist on windows");
@@ -475,8 +481,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
475481
let condvar_id = this.condvar_get_or_create_id(condvar_op, CONDVAR_ID_OFFSET)?;
476482

477483
while let Some((thread, lock)) = this.condvar_signal(condvar_id) {
478-
if let CondvarLock::RwLock { id, shared } = lock {
479-
this.reacquire_cond_lock(thread, id, shared)?;
484+
if let CondvarLock::RwLock { id, mode } = lock {
485+
this.reacquire_cond_lock(thread, id, mode)?;
480486
this.unregister_timeout_callback_if_exists(thread);
481487
} else {
482488
panic!("mutexes should not exist on windows");

0 commit comments

Comments
 (0)