Skip to content

Commit 302aae5

Browse files
committed
Use raw pointers
1 parent 090b834 commit 302aae5

File tree

1 file changed

+39
-30
lines changed

1 file changed

+39
-30
lines changed

src/librustc/ty/maps/job.rs

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ pub struct QueryJob<'tcx> {
6262
pub diagnostics: Lock<Vec<Diagnostic>>,
6363

6464
#[cfg(parallel_queries)]
65-
latch: QueryLatch,
65+
latch: QueryLatch<'tcx>,
6666
}
6767

6868
impl<'tcx> QueryJob<'tcx> {
@@ -146,41 +146,45 @@ impl<'tcx> QueryJob<'tcx> {
146146
///
147147
/// This does nothing for single threaded rustc,
148148
/// as there are no concurrent jobs which could be waiting on us
149-
pub fn signal_complete(&self, tcx: TyCtxt<'_, 'tcx, '_>) {
149+
pub fn signal_complete(&self) {
150150
#[cfg(parallel_queries)]
151-
self.latch.set(tcx);
151+
self.latch.set();
152152
}
153153
}
154154

155155
#[cfg(parallel_queries)]
156-
struct QueryWaiter<'a, 'tcx: 'a> {
157-
query: &'a Option<Lrc<QueryJob<'tcx>>>,
156+
struct QueryWaiter<'tcx> {
157+
query: *const Option<Lrc<QueryJob<'tcx>>>,
158158
condvar: Condvar,
159159
span: Span,
160160
cycle: Option<CycleError<'tcx>>,
161161
}
162162

163163
#[cfg(parallel_queries)]
164-
impl<'a, 'tcx> QueryWaiter<'a, 'tcx> {
165-
fn notify(&self, tcx: TyCtxt<'_, '_, '_>, registry: &rayon_core::Registry) {
164+
impl<'tcx> QueryWaiter<'tcx> {
165+
fn notify(&self, registry: &rayon_core::Registry) {
166166
rayon_core::mark_unblocked(registry);
167167
self.condvar.notify_one();
168168
}
169169
}
170170

171171
#[cfg(parallel_queries)]
172-
struct QueryLatchInfo {
172+
struct QueryLatchInfo<'tcx> {
173173
complete: bool,
174-
waiters: Vec<&'static mut QueryWaiter<'static, 'static>>,
174+
waiters: Vec<*mut QueryWaiter<'tcx>>,
175175
}
176176

177+
// Required because of raw pointers
177178
#[cfg(parallel_queries)]
178-
struct QueryLatch {
179-
info: Mutex<QueryLatchInfo>,
179+
unsafe impl<'tcx> Send for QueryLatchInfo<'tcx> {}
180+
181+
#[cfg(parallel_queries)]
182+
struct QueryLatch<'tcx> {
183+
info: Mutex<QueryLatchInfo<'tcx>>,
180184
}
181185

182186
#[cfg(parallel_queries)]
183-
impl QueryLatch {
187+
impl<'tcx> QueryLatch<'tcx> {
184188
fn new() -> Self {
185189
QueryLatch {
186190
info: Mutex::new(QueryLatchInfo {
@@ -190,44 +194,45 @@ impl QueryLatch {
190194
}
191195
}
192196

193-
fn await(&self, waiter: &mut QueryWaiter<'_, '_>) {
197+
fn await(&self, waiter: &mut QueryWaiter<'tcx>) {
194198
let mut info = self.info.lock();
195199
if !info.complete {
196-
let waiter = &*waiter;
197-
unsafe {
198-
#[allow(mutable_transmutes)]
199-
info.waiters.push(mem::transmute(waiter));
200-
}
200+
info.waiters.push(waiter);
201+
let condvar = &waiter.condvar;
201202
// If this detects a deadlock and the deadlock handler want to resume this thread
202203
// we have to be in the `wait` call. This is ensured by the deadlock handler
203204
// getting the self.info lock.
204205
rayon_core::mark_blocked();
205-
waiter.condvar.wait(&mut info);
206+
condvar.wait(&mut info);
206207
}
207208
}
208209

209-
fn set(&self, tcx: TyCtxt<'_, '_, '_>) {
210+
fn set(&self) {
210211
let mut info = self.info.lock();
211212
debug_assert!(!info.complete);
212213
info.complete = true;
213214
let registry = rayon_core::Registry::current();
214215
for waiter in info.waiters.drain(..) {
215-
waiter.notify(tcx, &registry);
216+
unsafe {
217+
(*waiter).notify(&registry);
218+
}
216219
}
217220
}
218221

219222
fn resume_waiter(
220223
&self,
221224
waiter: usize,
222-
error: CycleError
223-
) -> &'static mut QueryWaiter<'static, 'static> {
225+
error: CycleError<'tcx>
226+
) -> *mut QueryWaiter<'tcx> {
224227
let mut info = self.info.lock();
225228
debug_assert!(!info.complete);
226229
// Remove the waiter from the list of waiters
227230
let waiter = info.waiters.remove(waiter);
228231

229232
// Set the cycle error it will be picked it up when resumed
230-
waiter.cycle = unsafe { Some(mem::transmute(error)) };
233+
unsafe {
234+
(*waiter).cycle = Some(error);
235+
}
231236

232237
waiter
233238
}
@@ -250,10 +255,12 @@ where
250255
return Some(cycle);
251256
}
252257
}
253-
for (i, waiter) in query.latch.info.lock().waiters.iter().enumerate() {
254-
if let Some(ref waiter_query) = waiter.query {
255-
if visit(waiter.span, &**waiter_query as Ref).is_some() {
256-
return Some(Some((query_ref, i)));
258+
for (i, &waiter) in query.latch.info.lock().waiters.iter().enumerate() {
259+
unsafe {
260+
if let Some(ref waiter_query) = *(*waiter).query {
261+
if visit((*waiter).span, &**waiter_query as Ref).is_some() {
262+
return Some(Some((query_ref, i)));
263+
}
257264
}
258265
}
259266
}
@@ -322,7 +329,7 @@ fn query_entry<'tcx>(r: Ref<'tcx>) -> QueryInfo<'tcx> {
322329
#[cfg(parallel_queries)]
323330
fn remove_cycle<'tcx>(
324331
jobs: &mut Vec<Ref<'tcx>>,
325-
wakelist: &mut Vec<&'static mut QueryWaiter<'static, 'static>>,
332+
wakelist: &mut Vec<*mut QueryWaiter<'tcx>>,
326333
tcx: TyCtxt<'_, 'tcx, '_>
327334
) {
328335
let mut visited = HashSet::new();
@@ -453,7 +460,9 @@ fn deadlock(tcx: TyCtxt<'_, '_, '_>, registry: &rayon_core::Registry) {
453460

454461
// FIXME: Ensure this won't cause a deadlock before we return
455462
for waiter in wakelist.into_iter() {
456-
waiter.notify(tcx, registry);
463+
unsafe {
464+
(*waiter).notify(registry);
465+
}
457466
}
458467

459468
on_panic.disable();

0 commit comments

Comments
 (0)