Skip to content

Commit fa1b720

Browse files
committed
refactor into private functions
1 parent 224dff4 commit fa1b720

File tree

2 files changed

+51
-26
lines changed

2 files changed

+51
-26
lines changed

src/tools/miri/src/concurrency/init_once.rs

Lines changed: 50 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::num::NonZeroU32;
33

44
use rustc_index::vec::Idx;
55

6-
use super::sync::EvalContextExtPriv;
6+
use super::sync::EvalContextExtPriv as _;
77
use super::thread::MachineCallback;
88
use super::vector_clock::VClock;
99
use crate::*;
@@ -52,6 +52,43 @@ impl<'mir, 'tcx> VisitTags for InitOnce<'mir, 'tcx> {
5252
}
5353
}
5454

55+
impl<'mir, 'tcx: 'mir> EvalContextExtPriv<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
56+
trait EvalContextExtPriv<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
57+
/// Synchronize with the previous initialization attempt of an InitOnce.
58+
#[inline]
59+
fn init_once_observe_attempt(&mut self, id: InitOnceId) {
60+
let this = self.eval_context_mut();
61+
let current_thread = this.get_active_thread();
62+
63+
if let Some(data_race) = &this.machine.data_race {
64+
data_race.validate_lock_acquire(
65+
&this.machine.threads.sync.init_onces[id].data_race,
66+
current_thread,
67+
);
68+
}
69+
}
70+
71+
#[inline]
72+
fn init_once_wake_waiter(
73+
&mut self,
74+
id: InitOnceId,
75+
waiter: InitOnceWaiter<'mir, 'tcx>,
76+
) -> InterpResult<'tcx> {
77+
let this = self.eval_context_mut();
78+
let current_thread = this.get_active_thread();
79+
80+
this.unblock_thread(waiter.thread);
81+
82+
// Call callback, with the woken-up thread as `current`.
83+
this.set_active_thread(waiter.thread);
84+
this.init_once_observe_attempt(id);
85+
waiter.callback.call(this)?;
86+
this.set_active_thread(current_thread);
87+
88+
Ok(())
89+
}
90+
}
91+
5592
impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
5693
pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
5794
fn init_once_get_or_create_id(
@@ -141,13 +178,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
141178
// Wake up everyone.
142179
// need to take the queue to avoid having `this` be borrowed multiple times
143180
for waiter in std::mem::take(&mut init_once.waiters) {
144-
this.unblock_thread(waiter.thread);
145-
146-
// Call callback, with the woken-up thread as `current`.
147-
this.set_active_thread(waiter.thread);
148-
this.init_once_acquire(id);
149-
waiter.callback.call(this)?;
150-
this.set_active_thread(current_thread);
181+
this.init_once_wake_waiter(id, waiter)?;
151182
}
152183

153184
Ok(())
@@ -171,13 +202,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
171202

172203
// Wake up one waiting thread, so they can go ahead and try to init this.
173204
if let Some(waiter) = init_once.waiters.pop_front() {
174-
this.unblock_thread(waiter.thread);
175-
176-
// Call callback, with the woken-up thread as `current`.
177-
this.set_active_thread(waiter.thread);
178-
this.init_once_acquire(id);
179-
waiter.callback.call(this)?;
180-
this.set_active_thread(current_thread);
205+
this.init_once_wake_waiter(id, waiter)?;
181206
} else {
182207
// Nobody there to take this, so go back to 'uninit'
183208
init_once.status = InitOnceStatus::Uninitialized;
@@ -186,18 +211,18 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
186211
Ok(())
187212
}
188213

189-
/// Synchronize with the previous completion or failure of an InitOnce.
190-
/// This is required to prevent data races.
214+
/// Synchronize with the previous completion of an InitOnce.
215+
/// Must only be called after checking that it is complete.
191216
#[inline]
192-
fn init_once_acquire(&mut self, id: InitOnceId) {
217+
fn init_once_observe_completed(&mut self, id: InitOnceId) {
193218
let this = self.eval_context_mut();
194-
let current_thread = this.get_active_thread();
195219

196-
if let Some(data_race) = &this.machine.data_race {
197-
data_race.validate_lock_acquire(
198-
&this.machine.threads.sync.init_onces[id].data_race,
199-
current_thread,
200-
);
201-
}
220+
assert_eq!(
221+
this.init_once_status(id),
222+
InitOnceStatus::Complete,
223+
"observing the completion of incomplete init once"
224+
);
225+
226+
this.init_once_observe_attempt(id);
202227
}
203228
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
178178
)
179179
}
180180
InitOnceStatus::Complete => {
181-
this.init_once_acquire(id);
181+
this.init_once_observe_completed(id);
182182
this.write_scalar(this.eval_windows("c", "FALSE")?, &pending_place)?;
183183
}
184184
}

0 commit comments

Comments
 (0)