about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-05-27 09:01:57 +0200
committerJohn Kåre Alsaker <john.kare.alsaker@gmail.com>2018-06-06 15:25:18 +0200
commit302aae58648aed753ecb9752ff01534b42a97f69 (patch)
tree41ba8e0821ab6a5ec1825523ffbc86299164bd82 /src
parent090b8341bcd1eb7de3d0cbaa71eb2d77924fc4bc (diff)
downloadrust-302aae58648aed753ecb9752ff01534b42a97f69.tar.gz
rust-302aae58648aed753ecb9752ff01534b42a97f69.zip
Use raw pointers
Diffstat (limited to 'src')
-rw-r--r--src/librustc/ty/maps/job.rs69
1 files changed, 39 insertions, 30 deletions
diff --git a/src/librustc/ty/maps/job.rs b/src/librustc/ty/maps/job.rs
index 6b7170f2c47..adc06a9e457 100644
--- a/src/librustc/ty/maps/job.rs
+++ b/src/librustc/ty/maps/job.rs
@@ -62,7 +62,7 @@ pub struct QueryJob<'tcx> {
     pub diagnostics: Lock<Vec<Diagnostic>>,
 
     #[cfg(parallel_queries)]
-    latch: QueryLatch,
+    latch: QueryLatch<'tcx>,
 }
 
 impl<'tcx> QueryJob<'tcx> {
@@ -146,41 +146,45 @@ impl<'tcx> QueryJob<'tcx> {
     ///
     /// This does nothing for single threaded rustc,
     /// as there are no concurrent jobs which could be waiting on us
-    pub fn signal_complete(&self, tcx: TyCtxt<'_, 'tcx, '_>) {
+    pub fn signal_complete(&self) {
         #[cfg(parallel_queries)]
-        self.latch.set(tcx);
+        self.latch.set();
     }
 }
 
 #[cfg(parallel_queries)]
-struct QueryWaiter<'a, 'tcx: 'a> {
-    query: &'a Option<Lrc<QueryJob<'tcx>>>,
+struct QueryWaiter<'tcx> {
+    query: *const Option<Lrc<QueryJob<'tcx>>>,
     condvar: Condvar,
     span: Span,
     cycle: Option<CycleError<'tcx>>,
 }
 
 #[cfg(parallel_queries)]
-impl<'a, 'tcx> QueryWaiter<'a, 'tcx> {
-    fn notify(&self, tcx: TyCtxt<'_, '_, '_>, registry: &rayon_core::Registry) {
+impl<'tcx> QueryWaiter<'tcx> {
+    fn notify(&self, registry: &rayon_core::Registry) {
         rayon_core::mark_unblocked(registry);
         self.condvar.notify_one();
     }
 }
 
 #[cfg(parallel_queries)]
-struct QueryLatchInfo {
+struct QueryLatchInfo<'tcx> {
     complete: bool,
-    waiters: Vec<&'static mut QueryWaiter<'static, 'static>>,
+    waiters: Vec<*mut QueryWaiter<'tcx>>,
 }
 
+// Required because of raw pointers
 #[cfg(parallel_queries)]
-struct QueryLatch {
-    info: Mutex<QueryLatchInfo>,
+unsafe impl<'tcx> Send for QueryLatchInfo<'tcx> {}
+
+#[cfg(parallel_queries)]
+struct QueryLatch<'tcx> {
+    info: Mutex<QueryLatchInfo<'tcx>>,
 }
 
 #[cfg(parallel_queries)]
-impl QueryLatch {
+impl<'tcx> QueryLatch<'tcx> {
     fn new() -> Self {
         QueryLatch {
             info: Mutex::new(QueryLatchInfo {
@@ -190,44 +194,45 @@ impl QueryLatch {
         }
     }
 
-    fn await(&self, waiter: &mut QueryWaiter<'_, '_>) {
+    fn await(&self, waiter: &mut QueryWaiter<'tcx>) {
         let mut info = self.info.lock();
         if !info.complete {
-            let waiter = &*waiter;
-            unsafe {
-                #[allow(mutable_transmutes)]
-                info.waiters.push(mem::transmute(waiter));
-            }
+            info.waiters.push(waiter);
+            let condvar = &waiter.condvar;
             // If this detects a deadlock and the deadlock handler want to resume this thread
             // we have to be in the `wait` call. This is ensured by the deadlock handler
             // getting the self.info lock.
             rayon_core::mark_blocked();
-            waiter.condvar.wait(&mut info);
+            condvar.wait(&mut info);
         }
     }
 
-    fn set(&self, tcx: TyCtxt<'_, '_, '_>) {
+    fn set(&self) {
         let mut info = self.info.lock();
         debug_assert!(!info.complete);
         info.complete = true;
         let registry = rayon_core::Registry::current();
         for waiter in info.waiters.drain(..) {
-            waiter.notify(tcx, &registry);
+            unsafe {
+                (*waiter).notify(&registry);
+            }
         }
     }
 
     fn resume_waiter(
         &self,
         waiter: usize,
-        error: CycleError
-    ) -> &'static mut QueryWaiter<'static, 'static> {
+        error: CycleError<'tcx>
+    ) -> *mut QueryWaiter<'tcx> {
         let mut info = self.info.lock();
         debug_assert!(!info.complete);
         // Remove the waiter from the list of waiters
         let waiter = info.waiters.remove(waiter);
 
         // Set the cycle error it will be picked it up when resumed
-        waiter.cycle = unsafe { Some(mem::transmute(error)) };
+        unsafe {
+            (*waiter).cycle = Some(error);
+        }
 
         waiter
     }
@@ -250,10 +255,12 @@ where
             return Some(cycle);
         }
     }
-    for (i, waiter) in query.latch.info.lock().waiters.iter().enumerate() {
-        if let Some(ref waiter_query) = waiter.query {
-            if visit(waiter.span, &**waiter_query as Ref).is_some() {
-                return Some(Some((query_ref, i)));
+    for (i, &waiter) in query.latch.info.lock().waiters.iter().enumerate() {
+        unsafe {
+            if let Some(ref waiter_query) = *(*waiter).query {
+                if visit((*waiter).span, &**waiter_query as Ref).is_some() {
+                    return Some(Some((query_ref, i)));
+                }
             }
         }
     }
@@ -322,7 +329,7 @@ fn query_entry<'tcx>(r: Ref<'tcx>) -> QueryInfo<'tcx> {
 #[cfg(parallel_queries)]
 fn remove_cycle<'tcx>(
     jobs: &mut Vec<Ref<'tcx>>,
-    wakelist: &mut Vec<&'static mut QueryWaiter<'static, 'static>>,
+    wakelist: &mut Vec<*mut QueryWaiter<'tcx>>,
     tcx: TyCtxt<'_, 'tcx, '_>
 ) {
     let mut visited = HashSet::new();
@@ -453,7 +460,9 @@ fn deadlock(tcx: TyCtxt<'_, '_, '_>, registry: &rayon_core::Registry) {
 
     // FIXME: Ensure this won't cause a deadlock before we return
     for waiter in wakelist.into_iter() {
-        waiter.notify(tcx, registry);
+        unsafe {
+            (*waiter).notify(registry);
+        }
     }
 
     on_panic.disable();