Skip to content

Commit a66439c

Browse files
committed
use enum instead of bool for rwlock mode
1 parent 01d3bae commit a66439c

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(())
@@ -385,14 +386,19 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
385386
};
386387

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

390397
let active_thread = this.get_active_thread();
391398

392-
let was_locked = if shared {
393-
this.rwlock_reader_unlock(lock_id, active_thread)
394-
} else {
395-
this.rwlock_writer_unlock(lock_id, active_thread)
399+
let was_locked = match mode {
400+
RwLockMode::Shared => this.rwlock_reader_unlock(lock_id, active_thread),
401+
RwLockMode::Exclusive => this.rwlock_writer_unlock(lock_id, active_thread),
396402
};
397403

398404
if !was_locked {
@@ -402,27 +408,27 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
402408
}
403409

404410
this.block_thread(active_thread);
405-
this.condvar_wait(condvar_id, active_thread, CondvarLock::RwLock { id: lock_id, shared });
411+
this.condvar_wait(condvar_id, active_thread, CondvarLock::RwLock { id: lock_id, mode });
406412

407413
if let Some(timeout_time) = timeout_time {
408414
struct Callback<'tcx> {
409415
thread: ThreadId,
410416
condvar_id: CondvarId,
411417
lock_id: RwLockId,
412-
shared: bool,
418+
mode: RwLockMode,
413419
dest: PlaceTy<'tcx, Provenance>,
414420
}
415421

416422
impl<'tcx> VisitTags for Callback<'tcx> {
417423
fn visit_tags(&self, visit: &mut dyn FnMut(SbTag)) {
418-
let Callback { thread: _, condvar_id: _, lock_id: _, shared: _, dest } = self;
424+
let Callback { thread: _, condvar_id: _, lock_id: _, mode: _, dest } = self;
419425
dest.visit_tags(visit);
420426
}
421427
}
422428

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

427433
this.condvar_remove_waiter(self.condvar_id, self.thread);
428434

@@ -440,7 +446,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
440446
thread: active_thread,
441447
condvar_id,
442448
lock_id,
443-
shared,
449+
mode,
444450
dest: dest.clone(),
445451
}),
446452
);
@@ -454,8 +460,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
454460
let condvar_id = this.condvar_get_or_create_id(condvar_op, CONDVAR_ID_OFFSET)?;
455461

456462
if let Some((thread, lock)) = this.condvar_signal(condvar_id) {
457-
if let CondvarLock::RwLock { id, shared } = lock {
458-
this.reacquire_cond_lock(thread, id, shared)?;
463+
if let CondvarLock::RwLock { id, mode } = lock {
464+
this.reacquire_cond_lock(thread, id, mode)?;
459465
this.unregister_timeout_callback_if_exists(thread);
460466
} else {
461467
panic!("mutexes should not exist on windows");
@@ -473,8 +479,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
473479
let condvar_id = this.condvar_get_or_create_id(condvar_op, CONDVAR_ID_OFFSET)?;
474480

475481
while let Some((thread, lock)) = this.condvar_signal(condvar_id) {
476-
if let CondvarLock::RwLock { id, shared } = lock {
477-
this.reacquire_cond_lock(thread, id, shared)?;
482+
if let CondvarLock::RwLock { id, mode } = lock {
483+
this.reacquire_cond_lock(thread, id, mode)?;
478484
this.unregister_timeout_callback_if_exists(thread);
479485
} else {
480486
panic!("mutexes should not exist on windows");

0 commit comments

Comments
 (0)