about summary refs log tree commit diff
path: root/src/libstd
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-07-12 15:15:56 -0700
committerGitHub <noreply@github.com>2016-07-12 15:15:56 -0700
commit26fd0117f9a5128d39a30ae36efc731042bd1fec (patch)
treedefbc041a06bfb6350663170856c62a6694b7d48 /src/libstd
parent3085ec78487712ed77a506d9cba8d69cd3a44684 (diff)
parenta7220d9046e292869dded2c478544850c220c7de (diff)
downloadrust-26fd0117f9a5128d39a30ae36efc731042bd1fec.tar.gz
rust-26fd0117f9a5128d39a30ae36efc731042bd1fec.zip
Auto merge of #34705 - alexcrichton:clean-deprecated, r=brson
std: Clean out deprecated APIs

This primarily removes a lot of `sync::Static*` APIs and rejiggers the
associated implementations. While doing this it was discovered that the
`is_poisoned` method can actually result in a data race for the Mutex/RwLock
primitives, so the inner `Cell<bool>` was changed to an `AtomicBool` to prevent
the associated data race. Otherwise the usage/gurantees should be the same
they were before.
Diffstat (limited to 'src/libstd')
-rw-r--r--src/libstd/sync/condvar.rs368
-rw-r--r--src/libstd/sync/mod.rs14
-rw-r--r--src/libstd/sync/mutex.rs219
-rw-r--r--src/libstd/sync/rwlock.rs249
-rw-r--r--src/libstd/sys/common/poison.rs24
-rw-r--r--src/libstd/sys/windows/backtrace.rs92
6 files changed, 234 insertions, 732 deletions
diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs
index bf4b119a0b6..3c52ebc72f2 100644
--- a/src/libstd/sync/condvar.rs
+++ b/src/libstd/sync/condvar.rs
@@ -15,7 +15,7 @@ use sync::{mutex, MutexGuard, PoisonError};
 use sys_common::condvar as sys;
 use sys_common::mutex as sys_mutex;
 use sys_common::poison::{self, LockResult};
-use time::{Instant, Duration};
+use time::Duration;
 
 /// A type indicating whether a timed wait on a condition variable returned
 /// due to a time out or not.
@@ -72,59 +72,19 @@ impl WaitTimeoutResult {
 /// }
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-pub struct Condvar { inner: Box<StaticCondvar> }
-
-/// Statically allocated condition variables.
-///
-/// This structure is identical to `Condvar` except that it is suitable for use
-/// in static initializers for other structures.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(static_condvar)]
-///
-/// use std::sync::{StaticCondvar, CONDVAR_INIT};
-///
-/// static CVAR: StaticCondvar = CONDVAR_INIT;
-/// ```
-#[unstable(feature = "static_condvar",
-           reason = "may be merged with Condvar in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `Condvar::new` in a static should \
-                             suffice")]
-pub struct StaticCondvar {
-    inner: sys::Condvar,
+pub struct Condvar {
+    inner: Box<sys::Condvar>,
     mutex: AtomicUsize,
 }
 
-/// Constant initializer for a statically allocated condition variable.
-#[unstable(feature = "static_condvar",
-           reason = "may be merged with Condvar in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `Condvar::new` in a static should \
-                             suffice")]
-#[allow(deprecated)]
-pub const CONDVAR_INIT: StaticCondvar = StaticCondvar::new();
-
-#[allow(deprecated)]
 impl Condvar {
     /// Creates a new condition variable which is ready to be waited on and
     /// notified.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new() -> Condvar {
         Condvar {
-            inner: box StaticCondvar {
-                inner: sys::Condvar::new(),
-                mutex: AtomicUsize::new(0),
-            }
+            inner: box sys::Condvar::new(),
+            mutex: AtomicUsize::new(0),
         }
     }
 
@@ -157,9 +117,16 @@ impl Condvar {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn wait<'a, T>(&self, guard: MutexGuard<'a, T>)
                        -> LockResult<MutexGuard<'a, T>> {
-        unsafe {
-            let me: &'static Condvar = &*(self as *const _);
-            me.inner.wait(guard)
+        let poisoned = unsafe {
+            let lock = mutex::guard_lock(&guard);
+            self.verify(lock);
+            self.inner.wait(lock);
+            mutex::guard_poison(&guard).get()
+        };
+        if poisoned {
+            Err(PoisonError::new(guard))
+        } else {
+            Ok(guard)
         }
     }
 
@@ -206,9 +173,16 @@ impl Condvar {
     pub fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>,
                                dur: Duration)
                                -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)> {
-        unsafe {
-            let me: &'static Condvar = &*(self as *const _);
-            me.inner.wait_timeout(guard, dur)
+        let (poisoned, result) = unsafe {
+            let lock = mutex::guard_lock(&guard);
+            self.verify(lock);
+            let success = self.inner.wait_timeout(lock, dur);
+            (mutex::guard_poison(&guard).get(), WaitTimeoutResult(!success))
+        };
+        if poisoned {
+            Err(PoisonError::new((guard, result)))
+        } else {
+            Ok((guard, result))
         }
     }
 
@@ -220,7 +194,9 @@ impl Condvar {
     ///
     /// To wake up all threads, see `notify_all()`.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn notify_one(&self) { unsafe { self.inner.inner.notify_one() } }
+    pub fn notify_one(&self) {
+        unsafe { self.inner.notify_one() }
+    }
 
     /// Wakes up all blocked threads on this condvar.
     ///
@@ -230,169 +206,8 @@ impl Condvar {
     ///
     /// To wake up only one thread, see `notify_one()`.
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn notify_all(&self) { unsafe { self.inner.inner.notify_all() } }
-}
-
-#[stable(feature = "condvar_default", since = "1.9.0")]
-impl Default for Condvar {
-    fn default() -> Condvar {
-        Condvar::new()
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-impl Drop for Condvar {
-    fn drop(&mut self) {
-        unsafe { self.inner.inner.destroy() }
-    }
-}
-
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `Condvar::new` in a static should \
-                             suffice")]
-#[unstable(feature = "static_condvar",
-           reason = "may be merged with Condvar in the future",
-           issue = "27717")]
-#[allow(deprecated)]
-impl StaticCondvar {
-    /// Creates a new condition variable
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub const fn new() -> StaticCondvar {
-        StaticCondvar {
-            inner: sys::Condvar::new(),
-            mutex: AtomicUsize::new(0),
-        }
-    }
-
-    /// Blocks the current thread until this condition variable receives a
-    /// notification.
-    ///
-    /// See `Condvar::wait`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn wait<'a, T>(&'static self, guard: MutexGuard<'a, T>)
-                       -> LockResult<MutexGuard<'a, T>> {
-        let poisoned = unsafe {
-            let lock = mutex::guard_lock(&guard);
-            self.verify(lock);
-            self.inner.wait(lock);
-            mutex::guard_poison(&guard).get()
-        };
-        if poisoned {
-            Err(PoisonError::new(guard))
-        } else {
-            Ok(guard)
-        }
-    }
-
-    /// Waits on this condition variable for a notification, timing out after a
-    /// specified duration.
-    ///
-    /// See `Condvar::wait_timeout`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn wait_timeout<'a, T>(&'static self,
-                               guard: MutexGuard<'a, T>,
-                               timeout: Duration)
-                               -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)> {
-        let (poisoned, result) = unsafe {
-            let lock = mutex::guard_lock(&guard);
-            self.verify(lock);
-            let success = self.inner.wait_timeout(lock, timeout);
-            (mutex::guard_poison(&guard).get(), WaitTimeoutResult(!success))
-        };
-        if poisoned {
-            Err(PoisonError::new((guard, result)))
-        } else {
-            Ok((guard, result))
-        }
-    }
-
-    /// Waits on this condition variable for a notification, timing out after a
-    /// specified duration.
-    ///
-    /// The implementation will repeatedly wait while the duration has not
-    /// passed and the function returns `false`.
-    ///
-    /// See `Condvar::wait_timeout_with`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn wait_timeout_with<'a, T, F>(&'static self,
-                                       guard: MutexGuard<'a, T>,
-                                       dur: Duration,
-                                       mut f: F)
-                                       -> LockResult<(MutexGuard<'a, T>, WaitTimeoutResult)>
-            where F: FnMut(LockResult<&mut T>) -> bool {
-        // This could be made more efficient by pushing the implementation into
-        // sys::condvar
-        let start = Instant::now();
-        let mut guard_result: LockResult<MutexGuard<'a, T>> = Ok(guard);
-        while !f(guard_result
-                    .as_mut()
-                    .map(|g| &mut **g)
-                    .map_err(|e| PoisonError::new(&mut **e.get_mut()))) {
-            let consumed = start.elapsed();
-            let guard = guard_result.unwrap_or_else(|e| e.into_inner());
-            let (new_guard_result, timed_out) = if consumed > dur {
-                (Ok(guard), WaitTimeoutResult(true))
-            } else {
-                match self.wait_timeout(guard, dur - consumed) {
-                    Ok((new_guard, timed_out)) => (Ok(new_guard), timed_out),
-                    Err(err) => {
-                        let (new_guard, no_timeout) = err.into_inner();
-                        (Err(PoisonError::new(new_guard)), no_timeout)
-                    }
-                }
-            };
-            guard_result = new_guard_result;
-            if timed_out.timed_out() {
-                let result = f(guard_result
-                                    .as_mut()
-                                    .map(|g| &mut **g)
-                                    .map_err(|e| PoisonError::new(&mut **e.get_mut())));
-                let result = WaitTimeoutResult(!result);
-                return poison::map_result(guard_result, |g| (g, result));
-            }
-        }
-
-        poison::map_result(guard_result, |g| (g, WaitTimeoutResult(false)))
-    }
-
-    /// Wakes up one blocked thread on this condvar.
-    ///
-    /// See `Condvar::notify_one`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn notify_one(&'static self) { unsafe { self.inner.notify_one() } }
-
-    /// Wakes up all blocked threads on this condvar.
-    ///
-    /// See `Condvar::notify_all`.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub fn notify_all(&'static self) { unsafe { self.inner.notify_all() } }
-
-    /// Deallocates all resources associated with this static condvar.
-    ///
-    /// This method is unsafe to call as there is no guarantee that there are no
-    /// active users of the condvar, and this also doesn't prevent any future
-    /// users of the condvar. This method is required to be called to not leak
-    /// memory on all platforms.
-    #[unstable(feature = "static_condvar",
-               reason = "may be merged with Condvar in the future",
-               issue = "27717")]
-    pub unsafe fn destroy(&'static self) {
-        self.inner.destroy()
+    pub fn notify_all(&self) {
+        unsafe { self.inner.notify_all() }
     }
 
     fn verify(&self, mutex: &sys_mutex::Mutex) {
@@ -414,15 +229,26 @@ impl StaticCondvar {
     }
 }
 
+#[stable(feature = "condvar_default", since = "1.9.0")]
+impl Default for Condvar {
+    fn default() -> Condvar {
+        Condvar::new()
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Drop for Condvar {
+    fn drop(&mut self) {
+        unsafe { self.inner.destroy() }
+    }
+}
+
 #[cfg(test)]
-#[allow(deprecated)]
 mod tests {
     use prelude::v1::*;
 
-    use super::StaticCondvar;
     use sync::mpsc::channel;
-    use sync::{StaticMutex, Condvar, Mutex, Arc};
-    use sync::atomic::{AtomicUsize, Ordering};
+    use sync::{Condvar, Mutex, Arc};
     use thread;
     use time::Duration;
     use u32;
@@ -435,26 +261,19 @@ mod tests {
     }
 
     #[test]
-    fn static_smoke() {
-        static C: StaticCondvar = StaticCondvar::new();
-        C.notify_one();
-        C.notify_all();
-        unsafe { C.destroy(); }
-    }
-
-    #[test]
     fn notify_one() {
-        static C: StaticCondvar = StaticCondvar::new();
-        static M: StaticMutex = StaticMutex::new();
+        let m = Arc::new(Mutex::new(()));
+        let m2 = m.clone();
+        let c = Arc::new(Condvar::new());
+        let c2 = c.clone();
 
-        let g = M.lock().unwrap();
+        let g = m.lock().unwrap();
         let _t = thread::spawn(move|| {
-            let _g = M.lock().unwrap();
-            C.notify_one();
+            let _g = m2.lock().unwrap();
+            c2.notify_one();
         });
-        let g = C.wait(g).unwrap();
+        let g = c.wait(g).unwrap();
         drop(g);
-        unsafe { C.destroy(); M.destroy(); }
     }
 
     #[test]
@@ -495,84 +314,41 @@ mod tests {
 
     #[test]
     fn wait_timeout_ms() {
-        static C: StaticCondvar = StaticCondvar::new();
-        static M: StaticMutex = StaticMutex::new();
+        let m = Arc::new(Mutex::new(()));
+        let m2 = m.clone();
+        let c = Arc::new(Condvar::new());
+        let c2 = c.clone();
 
-        let g = M.lock().unwrap();
-        let (g, _no_timeout) = C.wait_timeout(g, Duration::from_millis(1)).unwrap();
+        let g = m.lock().unwrap();
+        let (g, _no_timeout) = c.wait_timeout(g, Duration::from_millis(1)).unwrap();
         // spurious wakeups mean this isn't necessarily true
         // assert!(!no_timeout);
         let _t = thread::spawn(move || {
-            let _g = M.lock().unwrap();
-            C.notify_one();
+            let _g = m2.lock().unwrap();
+            c2.notify_one();
         });
-        let (g, timeout_res) = C.wait_timeout(g, Duration::from_millis(u32::MAX as u64)).unwrap();
+        let (g, timeout_res) = c.wait_timeout(g, Duration::from_millis(u32::MAX as u64)).unwrap();
         assert!(!timeout_res.timed_out());
         drop(g);
-        unsafe { C.destroy(); M.destroy(); }
-    }
-
-    #[test]
-    fn wait_timeout_with() {
-        static C: StaticCondvar = StaticCondvar::new();
-        static M: StaticMutex = StaticMutex::new();
-        static S: AtomicUsize = AtomicUsize::new(0);
-
-        let g = M.lock().unwrap();
-        let (g, timed_out) = C.wait_timeout_with(g, Duration::new(0, 1000), |_| {
-            false
-        }).unwrap();
-        assert!(timed_out.timed_out());
-
-        let (tx, rx) = channel();
-        let _t = thread::spawn(move || {
-            rx.recv().unwrap();
-            let g = M.lock().unwrap();
-            S.store(1, Ordering::SeqCst);
-            C.notify_one();
-            drop(g);
-
-            rx.recv().unwrap();
-            let g = M.lock().unwrap();
-            S.store(2, Ordering::SeqCst);
-            C.notify_one();
-            drop(g);
-
-            rx.recv().unwrap();
-            let _g = M.lock().unwrap();
-            S.store(3, Ordering::SeqCst);
-            C.notify_one();
-        });
-
-        let mut state = 0;
-        let day = 24 * 60 * 60;
-        let (_g, timed_out) = C.wait_timeout_with(g, Duration::new(day, 0), |_| {
-            assert_eq!(state, S.load(Ordering::SeqCst));
-            tx.send(()).unwrap();
-            state += 1;
-            match state {
-                1|2 => false,
-                _ => true,
-            }
-        }).unwrap();
-        assert!(!timed_out.timed_out());
     }
 
     #[test]
     #[should_panic]
     fn two_mutexes() {
-        static M1: StaticMutex = StaticMutex::new();
-        static M2: StaticMutex = StaticMutex::new();
-        static C: StaticCondvar = StaticCondvar::new();
+        let m = Arc::new(Mutex::new(()));
+        let m2 = m.clone();
+        let c = Arc::new(Condvar::new());
+        let c2 = c.clone();
 
-        let mut g = M1.lock().unwrap();
+        let mut g = m.lock().unwrap();
         let _t = thread::spawn(move|| {
-            let _g = M1.lock().unwrap();
-            C.notify_one();
+            let _g = m2.lock().unwrap();
+            c2.notify_one();
         });
-        g = C.wait(g).unwrap();
+        g = c.wait(g).unwrap();
         drop(g);
 
-        let _ = C.wait(M2.lock().unwrap()).unwrap();
+        let m = Mutex::new(());
+        let _ = c.wait(m.lock().unwrap()).unwrap();
     }
 }
diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs
index 56eb7340c89..289b47b3484 100644
--- a/src/libstd/sync/mod.rs
+++ b/src/libstd/sync/mod.rs
@@ -25,23 +25,15 @@ pub use core::sync::atomic;
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::barrier::{Barrier, BarrierWaitResult};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-pub use self::condvar::{Condvar, StaticCondvar, WaitTimeoutResult, CONDVAR_INIT};
+pub use self::condvar::{Condvar, WaitTimeoutResult};
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-pub use self::mutex::MUTEX_INIT;
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-pub use self::mutex::{Mutex, MutexGuard, StaticMutex};
+pub use self::mutex::{Mutex, MutexGuard};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::once::{Once, OnceState, ONCE_INIT};
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use sys_common::poison::{PoisonError, TryLockError, TryLockResult, LockResult};
 #[stable(feature = "rust1", since = "1.0.0")]
-pub use self::rwlock::{RwLockReadGuard, RwLockWriteGuard};
-#[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
-pub use self::rwlock::{RwLock, StaticRwLock, RW_LOCK_INIT};
+pub use self::rwlock::{RwLock, RwLockReadGuard, RwLockWriteGuard};
 
 pub mod mpsc;
 
diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs
index c75a5c09146..6bc458397f1 100644
--- a/src/libstd/sync/mutex.rs
+++ b/src/libstd/sync/mutex.rs
@@ -113,14 +113,14 @@ use sys_common::poison::{self, TryLockError, TryLockResult, LockResult};
 /// *guard += 1;
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 pub struct Mutex<T: ?Sized> {
-    // Note that this static mutex is in a *box*, not inlined into the struct
-    // itself. Once a native mutex has been used once, its address can never
-    // change (it can't be moved). This mutex type can be safely moved at any
-    // time, so to ensure that the native mutex is used correctly we box the
-    // inner lock to give it a constant address.
-    inner: Box<StaticMutex>,
+    // Note that this mutex is in a *box*, not inlined into the struct itself.
+    // Once a native mutex has been used once, its address can never change (it
+    // can't be moved). This mutex type can be safely moved at any time, so to
+    // ensure that the native mutex is used correctly we box the inner lock to
+    // give it a constant address.
+    inner: Box<sys::Mutex>,
+    poison: poison::Flag,
     data: UnsafeCell<T>,
 }
 
@@ -131,42 +131,6 @@ unsafe impl<T: ?Sized + Send> Send for Mutex<T> { }
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<T: ?Sized + Send> Sync for Mutex<T> { }
 
-/// The static mutex type is provided to allow for static allocation of mutexes.
-///
-/// Note that this is a separate type because using a Mutex correctly means that
-/// it needs to have a destructor run. In Rust, statics are not allowed to have
-/// destructors. As a result, a `StaticMutex` has one extra method when compared
-/// to a `Mutex`, a `destroy` method. This method is unsafe to call, and
-/// documentation can be found directly on the method.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(static_mutex)]
-///
-/// use std::sync::{StaticMutex, MUTEX_INIT};
-///
-/// static LOCK: StaticMutex = MUTEX_INIT;
-///
-/// {
-///     let _g = LOCK.lock().unwrap();
-///     // do some productive work
-/// }
-/// // lock is unlocked here.
-/// ```
-#[unstable(feature = "static_mutex",
-           reason = "may be merged with Mutex in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `Mutex::new` in a static should \
-                             suffice")]
-pub struct StaticMutex {
-    lock: sys::Mutex,
-    poison: poison::Flag,
-}
-
 /// An RAII implementation of a "scoped lock" of a mutex. When this structure is
 /// dropped (falls out of scope), the lock will be unlocked.
 ///
@@ -174,48 +138,32 @@ pub struct StaticMutex {
 /// `Deref` and `DerefMut` implementations
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 pub struct MutexGuard<'a, T: ?Sized + 'a> {
     // funny underscores due to how Deref/DerefMut currently work (they
     // disregard field privacy).
-    __lock: &'a StaticMutex,
-    __data: &'a mut T,
+    __lock: &'a Mutex<T>,
     __poison: poison::Guard,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: ?Sized> !marker::Send for MutexGuard<'a, T> {}
 
-/// Static initialization of a mutex. This constant can be used to initialize
-/// other mutex constants.
-#[unstable(feature = "static_mutex",
-           reason = "may be merged with Mutex in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `Mutex::new` in a static should \
-                             suffice")]
-#[allow(deprecated)]
-pub const MUTEX_INIT: StaticMutex = StaticMutex::new();
-
-#[allow(deprecated)]
 impl<T> Mutex<T> {
     /// Creates a new mutex in an unlocked state ready for use.
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(t: T) -> Mutex<T> {
         let mut m = Mutex {
-            inner: box StaticMutex::new(),
+            inner: box sys::Mutex::new(),
+            poison: poison::Flag::new(),
             data: UnsafeCell::new(t),
         };
         unsafe {
-            m.inner.lock.init();
+            m.inner.init();
         }
         m
     }
 }
 
-#[allow(deprecated)]
 impl<T: ?Sized> Mutex<T> {
     /// Acquires a mutex, blocking the current thread until it is able to do so.
     ///
@@ -240,8 +188,8 @@ impl<T: ?Sized> Mutex<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn lock(&self) -> LockResult<MutexGuard<T>> {
         unsafe {
-            self.inner.lock.lock();
-            MutexGuard::new(&*self.inner, &self.data)
+            self.inner.lock();
+            MutexGuard::new(self)
         }
     }
 
@@ -261,8 +209,8 @@ impl<T: ?Sized> Mutex<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_lock(&self) -> TryLockResult<MutexGuard<T>> {
         unsafe {
-            if self.inner.lock.try_lock() {
-                Ok(MutexGuard::new(&*self.inner, &self.data)?)
+            if self.inner.try_lock() {
+                Ok(MutexGuard::new(self)?)
             } else {
                 Err(TryLockError::WouldBlock)
             }
@@ -277,7 +225,7 @@ impl<T: ?Sized> Mutex<T> {
     #[inline]
     #[stable(feature = "sync_poison", since = "1.2.0")]
     pub fn is_poisoned(&self) -> bool {
-        self.inner.poison.get()
+        self.poison.get()
     }
 
     /// Consumes this mutex, returning the underlying data.
@@ -289,21 +237,22 @@ impl<T: ?Sized> Mutex<T> {
     #[stable(feature = "mutex_into_inner", since = "1.6.0")]
     pub fn into_inner(self) -> LockResult<T> where T: Sized {
         // We know statically that there are no outstanding references to
-        // `self` so there's no need to lock the inner StaticMutex.
+        // `self` so there's no need to lock the inner lock.
         //
         // To get the inner value, we'd like to call `data.into_inner()`,
         // but because `Mutex` impl-s `Drop`, we can't move out of it, so
         // we'll have to destructure it manually instead.
         unsafe {
-            // Like `let Mutex { inner, data } = self`.
-            let (inner, data) = {
-                let Mutex { ref inner, ref data } = self;
-                (ptr::read(inner), ptr::read(data))
+            // Like `let Mutex { inner, poison, data } = self`.
+            let (inner, poison, data) = {
+                let Mutex { ref inner, ref poison, ref data } = self;
+                (ptr::read(inner), ptr::read(poison), ptr::read(data))
             };
             mem::forget(self);
-            inner.lock.destroy();  // Keep in sync with the `Drop` impl.
+            inner.destroy();  // Keep in sync with the `Drop` impl.
+            drop(inner);
 
-            poison::map_result(inner.poison.borrow(), |_| data.into_inner())
+            poison::map_result(poison.borrow(), |_| data.into_inner())
         }
     }
 
@@ -319,14 +268,13 @@ impl<T: ?Sized> Mutex<T> {
     #[stable(feature = "mutex_get_mut", since = "1.6.0")]
     pub fn get_mut(&mut self) -> LockResult<&mut T> {
         // We know statically that there are no other references to `self`, so
-        // there's no need to lock the inner StaticMutex.
+        // there's no need to lock the inner lock.
         let data = unsafe { &mut *self.data.get() };
-        poison::map_result(self.inner.poison.borrow(), |_| data )
+        poison::map_result(self.poison.borrow(), |_| data )
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 impl<T: ?Sized> Drop for Mutex<T> {
     #[unsafe_destructor_blind_to_params]
     fn drop(&mut self) {
@@ -335,7 +283,7 @@ impl<T: ?Sized> Drop for Mutex<T> {
         // dropped, that's not our job)
         //
         // IMPORTANT: This code must be kept in sync with `Mutex::into_inner`.
-        unsafe { self.inner.lock.destroy() }
+        unsafe { self.inner.destroy() }
     }
 }
 
@@ -359,72 +307,11 @@ impl<T: ?Sized + fmt::Debug> fmt::Debug for Mutex<T> {
     }
 }
 
-struct Dummy(UnsafeCell<()>);
-unsafe impl Sync for Dummy {}
-static DUMMY: Dummy = Dummy(UnsafeCell::new(()));
-
-#[unstable(feature = "static_mutex",
-           reason = "may be merged with Mutex in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `Mutex::new` in a static should \
-                             suffice")]
-#[allow(deprecated)]
-impl StaticMutex {
-    /// Creates a new mutex in an unlocked state ready for use.
-    pub const fn new() -> StaticMutex {
-        StaticMutex {
-            lock: sys::Mutex::new(),
-            poison: poison::Flag::new(),
-        }
-    }
-
-    /// Acquires this lock, see `Mutex::lock`
-    #[inline]
-    pub fn lock(&'static self) -> LockResult<MutexGuard<()>> {
-        unsafe {
-            self.lock.lock();
-            MutexGuard::new(self, &DUMMY.0)
-        }
-    }
-
-    /// Attempts to grab this lock, see `Mutex::try_lock`
-    #[inline]
-    pub fn try_lock(&'static self) -> TryLockResult<MutexGuard<()>> {
-        unsafe {
-            if self.lock.try_lock() {
-                Ok(MutexGuard::new(self, &DUMMY.0)?)
-            } else {
-                Err(TryLockError::WouldBlock)
-            }
-        }
-    }
-
-    /// Deallocates resources associated with this static mutex.
-    ///
-    /// This method is unsafe because it provides no guarantees that there are
-    /// no active users of this mutex, and safety is not guaranteed if there are
-    /// active users of this mutex.
-    ///
-    /// This method is required to ensure that there are no memory leaks on
-    /// *all* platforms. It may be the case that some platforms do not leak
-    /// memory if this method is not called, but this is not guaranteed to be
-    /// true on all platforms.
-    pub unsafe fn destroy(&'static self) {
-        self.lock.destroy()
-    }
-}
-
-#[allow(deprecated)]
 impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
-    unsafe fn new(lock: &'mutex StaticMutex, data: &'mutex UnsafeCell<T>)
-           -> LockResult<MutexGuard<'mutex, T>> {
+    unsafe fn new(lock: &'mutex Mutex<T>) -> LockResult<MutexGuard<'mutex, T>> {
         poison::map_result(lock.poison.borrow(), |guard| {
             MutexGuard {
                 __lock: lock,
-                __data: &mut *data.get(),
                 __poison: guard,
             }
         })
@@ -435,43 +322,43 @@ impl<'mutex, T: ?Sized> MutexGuard<'mutex, T> {
 impl<'mutex, T: ?Sized> Deref for MutexGuard<'mutex, T> {
     type Target = T;
 
-    fn deref(&self) -> &T {self.__data }
+    fn deref(&self) -> &T {
+        unsafe { &*self.__lock.data.get() }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'mutex, T: ?Sized> DerefMut for MutexGuard<'mutex, T> {
-    fn deref_mut(&mut self) -> &mut T { self.__data }
+    fn deref_mut(&mut self) -> &mut T {
+        unsafe { &mut *self.__lock.data.get() }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 impl<'a, T: ?Sized> Drop for MutexGuard<'a, T> {
     #[inline]
     fn drop(&mut self) {
         unsafe {
             self.__lock.poison.done(&self.__poison);
-            self.__lock.lock.unlock();
+            self.__lock.inner.unlock();
         }
     }
 }
 
-#[allow(deprecated)]
 pub fn guard_lock<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a sys::Mutex {
-    &guard.__lock.lock
+    &guard.__lock.inner
 }
 
-#[allow(deprecated)]
 pub fn guard_poison<'a, T: ?Sized>(guard: &MutexGuard<'a, T>) -> &'a poison::Flag {
     &guard.__lock.poison
 }
 
 #[cfg(test)]
-#[allow(deprecated)]
 mod tests {
     use prelude::v1::*;
 
     use sync::mpsc::channel;
-    use sync::{Arc, Mutex, StaticMutex, Condvar};
+    use sync::{Arc, Mutex, Condvar};
     use sync::atomic::{AtomicUsize, Ordering};
     use thread;
 
@@ -491,47 +378,33 @@ mod tests {
     }
 
     #[test]
-    fn smoke_static() {
-        static M: StaticMutex = StaticMutex::new();
-        unsafe {
-            drop(M.lock().unwrap());
-            drop(M.lock().unwrap());
-            M.destroy();
-        }
-    }
-
-    #[test]
     fn lots_and_lots() {
-        static M: StaticMutex = StaticMutex::new();
-        static mut CNT: u32 = 0;
         const J: u32 = 1000;
         const K: u32 = 3;
 
-        fn inc() {
+        let m = Arc::new(Mutex::new(0));
+
+        fn inc(m: &Mutex<u32>) {
             for _ in 0..J {
-                unsafe {
-                    let _g = M.lock().unwrap();
-                    CNT += 1;
-                }
+                *m.lock().unwrap() += 1;
             }
         }
 
         let (tx, rx) = channel();
         for _ in 0..K {
             let tx2 = tx.clone();
-            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
+            let m2 = m.clone();
+            thread::spawn(move|| { inc(&m2); tx2.send(()).unwrap(); });
             let tx2 = tx.clone();
-            thread::spawn(move|| { inc(); tx2.send(()).unwrap(); });
+            let m2 = m.clone();
+            thread::spawn(move|| { inc(&m2); tx2.send(()).unwrap(); });
         }
 
         drop(tx);
         for _ in 0..2 * K {
             rx.recv().unwrap();
         }
-        assert_eq!(unsafe {CNT}, J * K * 2);
-        unsafe {
-            M.destroy();
-        }
+        assert_eq!(*m.lock().unwrap(), J * K * 2);
     }
 
     #[test]
diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs
index 03d3483902d..65b5686de86 100644
--- a/src/libstd/sync/rwlock.rs
+++ b/src/libstd/sync/rwlock.rs
@@ -66,9 +66,9 @@ use sys_common::rwlock as sys;
 /// } // write lock is dropped here
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 pub struct RwLock<T: ?Sized> {
-    inner: Box<StaticRwLock>,
+    inner: Box<sys::RWLock>,
+    poison: poison::Flag,
     data: UnsafeCell<T>,
 }
 
@@ -77,64 +77,12 @@ unsafe impl<T: ?Sized + Send + Sync> Send for RwLock<T> {}
 #[stable(feature = "rust1", since = "1.0.0")]
 unsafe impl<T: ?Sized + Send + Sync> Sync for RwLock<T> {}
 
-/// Structure representing a statically allocated RwLock.
-///
-/// This structure is intended to be used inside of a `static` and will provide
-/// automatic global access as well as lazy initialization. The internal
-/// resources of this RwLock, however, must be manually deallocated.
-///
-/// # Examples
-///
-/// ```
-/// #![feature(static_rwlock)]
-///
-/// use std::sync::{StaticRwLock, RW_LOCK_INIT};
-///
-/// static LOCK: StaticRwLock = RW_LOCK_INIT;
-///
-/// {
-///     let _g = LOCK.read().unwrap();
-///     // ... shared read access
-/// }
-/// {
-///     let _g = LOCK.write().unwrap();
-///     // ... exclusive write access
-/// }
-/// unsafe { LOCK.destroy() } // free all resources
-/// ```
-#[unstable(feature = "static_rwlock",
-           reason = "may be merged with RwLock in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `RwLock::new` in a static should \
-                             suffice")]
-pub struct StaticRwLock {
-    lock: sys::RWLock,
-    poison: poison::Flag,
-}
-
-/// Constant initialization for a statically-initialized rwlock.
-#[unstable(feature = "static_rwlock",
-           reason = "may be merged with RwLock in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `RwLock::new` in a static should \
-                             suffice")]
-#[allow(deprecated)]
-pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock::new();
-
 /// RAII structure used to release the shared read access of a lock when
 /// dropped.
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 pub struct RwLockReadGuard<'a, T: ?Sized + 'a> {
-    __lock: &'a StaticRwLock,
-    __data: &'a T,
+    __lock: &'a RwLock<T>,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -144,17 +92,14 @@ impl<'a, T: ?Sized> !marker::Send for RwLockReadGuard<'a, T> {}
 /// dropped.
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 pub struct RwLockWriteGuard<'a, T: ?Sized + 'a> {
-    __lock: &'a StaticRwLock,
-    __data: &'a mut T,
+    __lock: &'a RwLock<T>,
     __poison: poison::Guard,
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: ?Sized> !marker::Send for RwLockWriteGuard<'a, T> {}
 
-#[allow(deprecated)]
 impl<T> RwLock<T> {
     /// Creates a new instance of an `RwLock<T>` which is unlocked.
     ///
@@ -167,11 +112,14 @@ impl<T> RwLock<T> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new(t: T) -> RwLock<T> {
-        RwLock { inner: box StaticRwLock::new(), data: UnsafeCell::new(t) }
+        RwLock {
+            inner: box sys::RWLock::new(),
+            poison: poison::Flag::new(),
+            data: UnsafeCell::new(t),
+        }
     }
 }
 
-#[allow(deprecated)]
 impl<T: ?Sized> RwLock<T> {
     /// Locks this rwlock with shared read access, blocking the current thread
     /// until it can be acquired.
@@ -194,8 +142,8 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn read(&self) -> LockResult<RwLockReadGuard<T>> {
         unsafe {
-            self.inner.lock.read();
-            RwLockReadGuard::new(&*self.inner, &self.data)
+            self.inner.read();
+            RwLockReadGuard::new(self)
         }
     }
 
@@ -220,8 +168,8 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<T>> {
         unsafe {
-            if self.inner.lock.try_read() {
-                Ok(RwLockReadGuard::new(&*self.inner, &self.data)?)
+            if self.inner.try_read() {
+                Ok(RwLockReadGuard::new(self)?)
             } else {
                 Err(TryLockError::WouldBlock)
             }
@@ -246,8 +194,8 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn write(&self) -> LockResult<RwLockWriteGuard<T>> {
         unsafe {
-            self.inner.lock.write();
-            RwLockWriteGuard::new(&*self.inner, &self.data)
+            self.inner.write();
+            RwLockWriteGuard::new(self)
         }
     }
 
@@ -272,8 +220,8 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<T>> {
         unsafe {
-            if self.inner.lock.try_write() {
-                Ok(RwLockWriteGuard::new(&*self.inner, &self.data)?)
+            if self.inner.try_write() {
+                Ok(RwLockWriteGuard::new(self)?)
             } else {
                 Err(TryLockError::WouldBlock)
             }
@@ -288,7 +236,7 @@ impl<T: ?Sized> RwLock<T> {
     #[inline]
     #[stable(feature = "sync_poison", since = "1.2.0")]
     pub fn is_poisoned(&self) -> bool {
-        self.inner.poison.get()
+        self.poison.get()
     }
 
     /// Consumes this `RwLock`, returning the underlying data.
@@ -302,21 +250,22 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rwlock_into_inner", since = "1.6.0")]
     pub fn into_inner(self) -> LockResult<T> where T: Sized {
         // We know statically that there are no outstanding references to
-        // `self` so there's no need to lock the inner StaticRwLock.
+        // `self` so there's no need to lock the inner lock.
         //
         // To get the inner value, we'd like to call `data.into_inner()`,
         // but because `RwLock` impl-s `Drop`, we can't move out of it, so
         // we'll have to destructure it manually instead.
         unsafe {
-            // Like `let RwLock { inner, data } = self`.
-            let (inner, data) = {
-                let RwLock { ref inner, ref data } = self;
-                (ptr::read(inner), ptr::read(data))
+            // Like `let RwLock { inner, poison, data } = self`.
+            let (inner, poison, data) = {
+                let RwLock { ref inner, ref poison, ref data } = self;
+                (ptr::read(inner), ptr::read(poison), ptr::read(data))
             };
             mem::forget(self);
-            inner.lock.destroy();  // Keep in sync with the `Drop` impl.
+            inner.destroy();  // Keep in sync with the `Drop` impl.
+            drop(inner);
 
-            poison::map_result(inner.poison.borrow(), |_| data.into_inner())
+            poison::map_result(poison.borrow(), |_| data.into_inner())
         }
     }
 
@@ -334,19 +283,18 @@ impl<T: ?Sized> RwLock<T> {
     #[stable(feature = "rwlock_get_mut", since = "1.6.0")]
     pub fn get_mut(&mut self) -> LockResult<&mut T> {
         // We know statically that there are no other references to `self`, so
-        // there's no need to lock the inner StaticRwLock.
+        // there's no need to lock the inner lock.
         let data = unsafe { &mut *self.data.get() };
-        poison::map_result(self.inner.poison.borrow(), |_| data )
+        poison::map_result(self.poison.borrow(), |_| data)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-#[allow(deprecated)]
 impl<T: ?Sized> Drop for RwLock<T> {
     #[unsafe_destructor_blind_to_params]
     fn drop(&mut self) {
         // IMPORTANT: This code needs to be kept in sync with `RwLock::into_inner`.
-        unsafe { self.inner.lock.destroy() }
+        unsafe { self.inner.destroy() }
     }
 }
 
@@ -370,114 +318,23 @@ impl<T: Default> Default for RwLock<T> {
     }
 }
 
-struct Dummy(UnsafeCell<()>);
-unsafe impl Sync for Dummy {}
-static DUMMY: Dummy = Dummy(UnsafeCell::new(()));
-
-#[unstable(feature = "static_rwlock",
-           reason = "may be merged with RwLock in the future",
-           issue = "27717")]
-#[rustc_deprecated(since = "1.10.0",
-                   reason = "the lazy-static crate suffices for static sync \
-                             primitives and eventually this type shouldn't \
-                             be necessary as `RwLock::new` in a static should \
-                             suffice")]
-#[allow(deprecated)]
-impl StaticRwLock {
-    /// Creates a new rwlock.
-    pub const fn new() -> StaticRwLock {
-        StaticRwLock {
-            lock: sys::RWLock::new(),
-            poison: poison::Flag::new(),
-        }
-    }
-
-    /// Locks this rwlock with shared read access, blocking the current thread
-    /// until it can be acquired.
-    ///
-    /// See `RwLock::read`.
-    #[inline]
-    pub fn read(&'static self) -> LockResult<RwLockReadGuard<'static, ()>> {
-        unsafe {
-            self.lock.read();
-            RwLockReadGuard::new(self, &DUMMY.0)
-        }
-    }
-
-    /// Attempts to acquire this lock with shared read access.
-    ///
-    /// See `RwLock::try_read`.
-    #[inline]
-    pub fn try_read(&'static self)
-                    -> TryLockResult<RwLockReadGuard<'static, ()>> {
-        unsafe {
-            if self.lock.try_read(){
-                Ok(RwLockReadGuard::new(self, &DUMMY.0)?)
-            } else {
-                Err(TryLockError::WouldBlock)
-            }
-        }
-    }
-
-    /// Locks this rwlock with exclusive write access, blocking the current
-    /// thread until it can be acquired.
-    ///
-    /// See `RwLock::write`.
-    #[inline]
-    pub fn write(&'static self) -> LockResult<RwLockWriteGuard<'static, ()>> {
-        unsafe {
-            self.lock.write();
-            RwLockWriteGuard::new(self, &DUMMY.0)
-        }
-    }
-
-    /// Attempts to lock this rwlock with exclusive write access.
-    ///
-    /// See `RwLock::try_write`.
-    #[inline]
-    pub fn try_write(&'static self)
-                     -> TryLockResult<RwLockWriteGuard<'static, ()>> {
-        unsafe {
-            if self.lock.try_write() {
-                Ok(RwLockWriteGuard::new(self, &DUMMY.0)?)
-            } else {
-                Err(TryLockError::WouldBlock)
-            }
-        }
-    }
-
-    /// Deallocates all resources associated with this static lock.
-    ///
-    /// This method is unsafe to call as there is no guarantee that there are no
-    /// active users of the lock, and this also doesn't prevent any future users
-    /// of this lock. This method is required to be called to not leak memory on
-    /// all platforms.
-    pub unsafe fn destroy(&'static self) {
-        self.lock.destroy()
-    }
-}
-
-#[allow(deprecated)]
 impl<'rwlock, T: ?Sized> RwLockReadGuard<'rwlock, T> {
-    unsafe fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
-           -> LockResult<RwLockReadGuard<'rwlock, T>> {
+    unsafe fn new(lock: &'rwlock RwLock<T>)
+                  -> LockResult<RwLockReadGuard<'rwlock, T>> {
         poison::map_result(lock.poison.borrow(), |_| {
             RwLockReadGuard {
                 __lock: lock,
-                __data: &*data.get(),
             }
         })
     }
 }
 
-#[allow(deprecated)]
 impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
-    unsafe fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell<T>)
-           -> LockResult<RwLockWriteGuard<'rwlock, T>> {
+    unsafe fn new(lock: &'rwlock RwLock<T>)
+                  -> LockResult<RwLockWriteGuard<'rwlock, T>> {
         poison::map_result(lock.poison.borrow(), |guard| {
             RwLockWriteGuard {
                 __lock: lock,
-                __data: &mut *data.get(),
                 __poison: guard,
             }
         })
@@ -488,42 +345,43 @@ impl<'rwlock, T: ?Sized> RwLockWriteGuard<'rwlock, T> {
 impl<'rwlock, T: ?Sized> Deref for RwLockReadGuard<'rwlock, T> {
     type Target = T;
 
-    fn deref(&self) -> &T { self.__data }
+    fn deref(&self) -> &T {
+        unsafe { &*self.__lock.data.get() }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'rwlock, T: ?Sized> Deref for RwLockWriteGuard<'rwlock, T> {
     type Target = T;
 
-    fn deref(&self) -> &T { self.__data }
+    fn deref(&self) -> &T {
+        unsafe { &*self.__lock.data.get() }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'rwlock, T: ?Sized> DerefMut for RwLockWriteGuard<'rwlock, T> {
     fn deref_mut(&mut self) -> &mut T {
-        self.__data
+        unsafe { &mut *self.__lock.data.get() }
     }
 }
 
-#[allow(deprecated)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: ?Sized> Drop for RwLockReadGuard<'a, T> {
     fn drop(&mut self) {
-        unsafe { self.__lock.lock.read_unlock(); }
+        unsafe { self.__lock.inner.read_unlock(); }
     }
 }
 
-#[allow(deprecated)]
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: ?Sized> Drop for RwLockWriteGuard<'a, T> {
     fn drop(&mut self) {
         self.__lock.poison.done(&self.__poison);
-        unsafe { self.__lock.lock.write_unlock(); }
+        unsafe { self.__lock.inner.write_unlock(); }
     }
 }
 
 #[cfg(test)]
-#[allow(deprecated)]
 mod tests {
     #![allow(deprecated)] // rand
 
@@ -532,7 +390,7 @@ mod tests {
     use rand::{self, Rng};
     use sync::mpsc::channel;
     use thread;
-    use sync::{Arc, RwLock, StaticRwLock, TryLockError};
+    use sync::{Arc, RwLock, TryLockError};
     use sync::atomic::{AtomicUsize, Ordering};
 
     #[derive(Eq, PartialEq, Debug)]
@@ -548,31 +406,23 @@ mod tests {
     }
 
     #[test]
-    fn static_smoke() {
-        static R: StaticRwLock = StaticRwLock::new();
-        drop(R.read().unwrap());
-        drop(R.write().unwrap());
-        drop((R.read().unwrap(), R.read().unwrap()));
-        drop(R.write().unwrap());
-        unsafe { R.destroy(); }
-    }
-
-    #[test]
     fn frob() {
-        static R: StaticRwLock = StaticRwLock::new();
         const N: usize = 10;
         const M: usize = 1000;
 
+        let r = Arc::new(RwLock::new(()));
+
         let (tx, rx) = channel::<()>();
         for _ in 0..N {
             let tx = tx.clone();
-            thread::spawn(move|| {
+            let r = r.clone();
+            thread::spawn(move || {
                 let mut rng = rand::thread_rng();
                 for _ in 0..M {
                     if rng.gen_weighted_bool(N) {
-                        drop(R.write().unwrap());
+                        drop(r.write().unwrap());
                     } else {
-                        drop(R.read().unwrap());
+                        drop(r.read().unwrap());
                     }
                 }
                 drop(tx);
@@ -580,7 +430,6 @@ mod tests {
         }
         drop(tx);
         let _ = rx.recv();
-        unsafe { R.destroy(); }
     }
 
     #[test]
diff --git a/src/libstd/sys/common/poison.rs b/src/libstd/sys/common/poison.rs
index 83780a31cce..55212bf35d6 100644
--- a/src/libstd/sys/common/poison.rs
+++ b/src/libstd/sys/common/poison.rs
@@ -8,22 +8,28 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use cell::Cell;
 use error::{Error};
 use fmt;
 use marker::Reflect;
+use sync::atomic::{AtomicBool, Ordering};
 use thread;
 
-pub struct Flag { failed: Cell<bool> }
+pub struct Flag { failed: AtomicBool }
 
-// This flag is only ever accessed with a lock previously held. Note that this
-// a totally private structure.
-unsafe impl Send for Flag {}
-unsafe impl Sync for Flag {}
+// Note that the Ordering uses to access the `failed` field of `Flag` below is
+// always `Relaxed`, and that's because this isn't actually protecting any data,
+// it's just a flag whether we've panicked or not.
+//
+// The actual location that this matters is when a mutex is **locked** which is
+// where we have external synchronization ensuring that we see memory
+// reads/writes to this flag.
+//
+// As a result, if it matters, we should see the correct value for `failed` in
+// all cases.
 
 impl Flag {
     pub const fn new() -> Flag {
-        Flag { failed: Cell::new(false) }
+        Flag { failed: AtomicBool::new(false) }
     }
 
     #[inline]
@@ -39,13 +45,13 @@ impl Flag {
     #[inline]
     pub fn done(&self, guard: &Guard) {
         if !guard.panicking && thread::panicking() {
-            self.failed.set(true);
+            self.failed.store(true, Ordering::Relaxed);
         }
     }
 
     #[inline]
     pub fn get(&self) -> bool {
-        self.failed.get()
+        self.failed.load(Ordering::Relaxed)
     }
 }
 
diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs
index 0e10a8d8e8d..82a44c1c110 100644
--- a/src/libstd/sys/windows/backtrace.rs
+++ b/src/libstd/sys/windows/backtrace.rs
@@ -30,9 +30,9 @@ use io;
 use libc::c_void;
 use mem;
 use ptr;
-use sync::StaticMutex;
 use sys::c;
 use sys::dynamic_lib::DynamicLibrary;
+use sys::mutex::Mutex;
 
 macro_rules! sym {
     ($lib:expr, $e:expr, $t:ident) => (
@@ -101,53 +101,59 @@ impl Drop for Cleanup {
 pub fn write(w: &mut Write) -> io::Result<()> {
     // According to windows documentation, all dbghelp functions are
     // single-threaded.
-    static LOCK: StaticMutex = StaticMutex::new();
-    let _g = LOCK.lock();
+    static LOCK: Mutex = Mutex::new();
+    unsafe {
+        LOCK.lock();
+        let res = _write(w);
+        LOCK.unlock();
+        return res
+    }
+}
 
+unsafe fn _write(w: &mut Write) -> io::Result<()> {
     let dbghelp = match DynamicLibrary::open("dbghelp.dll") {
         Ok(lib) => lib,
         Err(..) => return Ok(()),
     };
-    unsafe {
-        // Fetch the symbols necessary from dbghelp.dll
-        let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn);
-        let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn);
-        let StackWalk64 = sym!(dbghelp, "StackWalk64", StackWalk64Fn);
-
-        // Allocate necessary structures for doing the stack walk
-        let process = c::GetCurrentProcess();
-        let thread = c::GetCurrentThread();
-        let mut context: c::CONTEXT = mem::zeroed();
-        c::RtlCaptureContext(&mut context);
-        let mut frame: c::STACKFRAME64 = mem::zeroed();
-        let image = init_frame(&mut frame, &context);
-
-        // Initialize this process's symbols
-        let ret = SymInitialize(process, ptr::null_mut(), c::TRUE);
-        if ret != c::TRUE { return Ok(()) }
-        let _c = Cleanup { handle: process, SymCleanup: SymCleanup };
-
-        // And now that we're done with all the setup, do the stack walking!
-        // Start from -1 to avoid printing this stack frame, which will
-        // always be exactly the same.
-        let mut i = -1;
-        write!(w, "stack backtrace:\n")?;
-        while StackWalk64(image, process, thread, &mut frame, &mut context,
-                          ptr::null_mut(),
-                          ptr::null_mut(),
-                          ptr::null_mut(),
-                          ptr::null_mut()) == c::TRUE {
-            let addr = frame.AddrPC.Offset;
-            if addr == frame.AddrReturn.Offset || addr == 0 ||
-               frame.AddrReturn.Offset == 0 { break }
-
-            i += 1;
-
-            if i >= 0 {
-                printing::print(w, i, addr - 1, process, &dbghelp)?;
-            }
-        }
 
-        Ok(())
+    // Fetch the symbols necessary from dbghelp.dll
+    let SymInitialize = sym!(dbghelp, "SymInitialize", SymInitializeFn);
+    let SymCleanup = sym!(dbghelp, "SymCleanup", SymCleanupFn);
+    let StackWalk64 = sym!(dbghelp, "StackWalk64", StackWalk64Fn);
+
+    // Allocate necessary structures for doing the stack walk
+    let process = c::GetCurrentProcess();
+    let thread = c::GetCurrentThread();
+    let mut context: c::CONTEXT = mem::zeroed();
+    c::RtlCaptureContext(&mut context);
+    let mut frame: c::STACKFRAME64 = mem::zeroed();
+    let image = init_frame(&mut frame, &context);
+
+    // Initialize this process's symbols
+    let ret = SymInitialize(process, ptr::null_mut(), c::TRUE);
+    if ret != c::TRUE { return Ok(()) }
+    let _c = Cleanup { handle: process, SymCleanup: SymCleanup };
+
+    // And now that we're done with all the setup, do the stack walking!
+    // Start from -1 to avoid printing this stack frame, which will
+    // always be exactly the same.
+    let mut i = -1;
+    write!(w, "stack backtrace:\n")?;
+    while StackWalk64(image, process, thread, &mut frame, &mut context,
+                      ptr::null_mut(),
+                      ptr::null_mut(),
+                      ptr::null_mut(),
+                      ptr::null_mut()) == c::TRUE {
+        let addr = frame.AddrPC.Offset;
+        if addr == frame.AddrReturn.Offset || addr == 0 ||
+           frame.AddrReturn.Offset == 0 { break }
+
+        i += 1;
+
+        if i >= 0 {
+            printing::print(w, i, addr - 1, process, &dbghelp)?;
+        }
     }
+
+    Ok(())
 }