diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index ddafe416305e1..a17d121e60a2a 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -263,7 +263,7 @@ mod dl {
     use sys::os;
     use os::windows::prelude::*;
     use ptr;
-    use sys::c::compat::kernel32::SetThreadErrorMode;
+    use sys::c::SetThreadErrorMode;
 
     pub fn open(filename: Option<&OsStr>) -> Result<*mut u8, String> {
         // disable "dll load failed" error dialog.
diff --git a/src/libstd/sys/windows/c.rs b/src/libstd/sys/windows/c.rs
index 3c9b2ef1b986e..7f89ea979391e 100644
--- a/src/libstd/sys/windows/c.rs
+++ b/src/libstd/sys/windows/c.rs
@@ -13,6 +13,9 @@
 #![allow(bad_style, dead_code, overflowing_literals)]
 
 use libc;
+use libc::{c_uint, c_ulong};
+use libc::{DWORD, BOOL, BOOLEAN, ERROR_CALL_NOT_IMPLEMENTED, LPVOID, HANDLE};
+use libc::{LPCWSTR, LONG};
 
 pub use self::GET_FILEEX_INFO_LEVELS::*;
 pub use self::FILE_INFO_BY_HANDLE_CLASS::*;
@@ -240,7 +243,32 @@ pub struct SYMBOLIC_LINK_REPARSE_BUFFER {
     pub PathBuffer: libc::WCHAR,
 }
 
+pub type PCONDITION_VARIABLE = *mut CONDITION_VARIABLE;
+pub type PSRWLOCK = *mut SRWLOCK;
+pub type ULONG = c_ulong;
+pub type ULONG_PTR = c_ulong;
+
+#[repr(C)]
+pub struct CONDITION_VARIABLE { pub ptr: LPVOID }
+#[repr(C)]
+pub struct SRWLOCK { pub ptr: LPVOID }
+#[repr(C)]
+pub struct CRITICAL_SECTION {
+    CriticalSectionDebug: LPVOID,
+    LockCount: LONG,
+    RecursionCount: LONG,
+    OwningThread: HANDLE,
+    LockSemaphore: HANDLE,
+    SpinCount: ULONG_PTR
+}
+
+pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE {
+    ptr: 0 as *mut _,
+};
+pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { ptr: 0 as *mut _ };
+
 #[link(name = "ws2_32")]
+#[link(name = "userenv")]
 extern "system" {
     pub fn WSAStartup(wVersionRequested: libc::WORD,
                       lpWSAData: LPWSADATA) -> libc::c_int;
@@ -295,115 +323,13 @@ extern "system" {
     pub fn CancelIo(hFile: libc::HANDLE) -> libc::BOOL;
     pub fn CancelIoEx(hFile: libc::HANDLE,
                       lpOverlapped: libc::LPOVERLAPPED) -> libc::BOOL;
-}
-
-pub mod compat {
-    use prelude::v1::*;
 
-    use ffi::CString;
-    use libc::types::os::arch::extra::{LPCWSTR, HMODULE, LPCSTR, LPVOID};
-    use sync::atomic::{AtomicUsize, Ordering};
+    pub fn InitializeCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
+    pub fn EnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
+    pub fn TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOLEAN;
+    pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
+    pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
 
-    extern "system" {
-        fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
-        fn GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR) -> LPVOID;
-    }
-
-    fn store_func(ptr: &AtomicUsize, module: &str, symbol: &str,
-                  fallback: usize) -> usize {
-        let mut module: Vec<u16> = module.utf16_units().collect();
-        module.push(0);
-        let symbol = CString::new(symbol).unwrap();
-        let func = unsafe {
-            let handle = GetModuleHandleW(module.as_ptr());
-            GetProcAddress(handle, symbol.as_ptr()) as usize
-        };
-        let value = if func == 0 {fallback} else {func};
-        ptr.store(value, Ordering::SeqCst);
-        value
-    }
-
-    /// Macro for creating a compatibility fallback for a Windows function
-    ///
-    /// # Examples
-    /// ```
-    /// compat_fn!(adll32::SomeFunctionW(_arg: LPCWSTR) {
-    ///     // Fallback implementation
-    /// })
-    /// ```
-    ///
-    /// Note that arguments unused by the fallback implementation should not be
-    /// called `_` as they are used to be passed to the real function if
-    /// available.
-    macro_rules! compat_fn {
-        ($module:ident::$symbol:ident($($argname:ident: $argtype:ty),*)
-                                      -> $rettype:ty { $fallback:expr }) => (
-            #[inline(always)]
-            pub unsafe fn $symbol($($argname: $argtype),*) -> $rettype {
-                use sync::atomic::{AtomicUsize, Ordering};
-                use mem;
-
-                static PTR: AtomicUsize = AtomicUsize::new(0);
-
-                fn load() -> usize {
-                    ::sys::c::compat::store_func(&PTR,
-                                                 stringify!($module),
-                                                 stringify!($symbol),
-                                                 fallback as usize)
-                }
-
-                extern "system" fn fallback($($argname: $argtype),*)
-                                            -> $rettype { $fallback }
-
-                let addr = match PTR.load(Ordering::SeqCst) {
-                    0 => load(),
-                    n => n,
-                };
-                let f: extern "system" fn($($argtype),*) -> $rettype =
-                    mem::transmute(addr);
-                f($($argname),*)
-            }
-        )
-    }
-
-    /// Compatibility layer for functions in `kernel32.dll`
-    ///
-    /// Latest versions of Windows this is needed for:
-    ///
-    /// * `CreateSymbolicLinkW`: Windows XP, Windows Server 2003
-    /// * `GetFinalPathNameByHandleW`: Windows XP, Windows Server 2003
-    pub mod kernel32 {
-        use libc::c_uint;
-        use libc::types::os::arch::extra::{DWORD, LPCWSTR, BOOLEAN, HANDLE};
-        use libc::consts::os::extra::ERROR_CALL_NOT_IMPLEMENTED;
-        use sys::c::SetLastError;
-
-        compat_fn! {
-            kernel32::CreateSymbolicLinkW(_lpSymlinkFileName: LPCWSTR,
-                                          _lpTargetFileName: LPCWSTR,
-                                          _dwFlags: DWORD) -> BOOLEAN {
-                unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 }
-            }
-        }
-
-        compat_fn! {
-            kernel32::GetFinalPathNameByHandleW(_hFile: HANDLE,
-                                                _lpszFilePath: LPCWSTR,
-                                                _cchFilePath: DWORD,
-                                                _dwFlags: DWORD) -> DWORD {
-                unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 }
-            }
-        }
-
-        compat_fn! {
-            kernel32::SetThreadErrorMode(_dwNewMode: DWORD, _lpOldMode: *mut DWORD) -> c_uint {
-                unsafe { SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0 }
-            }
-        }
-    }
-}
-
-extern "system" {
     // FIXME - pInputControl should be PCONSOLE_READCONSOLE_CONTROL
     pub fn ReadConsoleW(hConsoleInput: libc::HANDLE,
                         lpBuffer: libc::LPVOID,
@@ -447,10 +373,6 @@ extern "system" {
                        lpCreationTime: *const libc::FILETIME,
                        lpLastAccessTime: *const libc::FILETIME,
                        lpLastWriteTime: *const libc::FILETIME) -> libc::BOOL;
-    pub fn SetFileInformationByHandle(hFile: libc::HANDLE,
-                    FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
-                    lpFileInformation: libc::LPVOID,
-                    dwBufferSize: libc::DWORD) -> libc::BOOL;
     pub fn GetTempPathW(nBufferLength: libc::DWORD,
                         lpBuffer: libc::LPCWSTR) -> libc::DWORD;
     pub fn OpenProcessToken(ProcessHandle: libc::HANDLE,
@@ -483,11 +405,70 @@ extern "system" {
     pub fn SwitchToThread() -> libc::BOOL;
     pub fn Sleep(dwMilliseconds: libc::DWORD);
     pub fn GetProcessId(handle: libc::HANDLE) -> libc::DWORD;
-}
-
-#[link(name = "userenv")]
-extern "system" {
     pub fn GetUserProfileDirectoryW(hToken: libc::HANDLE,
                                     lpProfileDir: libc::LPCWSTR,
                                     lpcchSize: *mut libc::DWORD) -> libc::BOOL;
 }
+
+// Functions that aren't available on Windows XP, but we still use them and just
+// provide some form of a fallback implementation.
+compat_fn! {
+    kernel32:
+
+    pub fn CreateSymbolicLinkW(_lpSymlinkFileName: LPCWSTR,
+                               _lpTargetFileName: LPCWSTR,
+                               _dwFlags: DWORD) -> BOOLEAN {
+        SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
+    }
+    pub fn GetFinalPathNameByHandleW(_hFile: HANDLE,
+                                     _lpszFilePath: LPCWSTR,
+                                     _cchFilePath: DWORD,
+                                     _dwFlags: DWORD) -> DWORD {
+        SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
+    }
+    pub fn SetThreadErrorMode(_dwNewMode: DWORD,
+                              _lpOldMode: *mut DWORD) -> c_uint {
+        SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
+    }
+    pub fn SetThreadStackGuarantee(_size: *mut c_ulong) -> BOOL {
+        SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
+    }
+    pub fn SetFileInformationByHandle(_hFile: HANDLE,
+                    _FileInformationClass: FILE_INFO_BY_HANDLE_CLASS,
+                    _lpFileInformation: LPVOID,
+                    _dwBufferSize: DWORD) -> BOOL {
+        SetLastError(ERROR_CALL_NOT_IMPLEMENTED as DWORD); 0
+    }
+    pub fn SleepConditionVariableSRW(ConditionVariable: PCONDITION_VARIABLE,
+                                     SRWLock: PSRWLOCK,
+                                     dwMilliseconds: DWORD,
+                                     Flags: ULONG) -> BOOL {
+        panic!("condition variables not available")
+    }
+    pub fn WakeConditionVariable(ConditionVariable: PCONDITION_VARIABLE)
+                                 -> () {
+        panic!("condition variables not available")
+    }
+    pub fn WakeAllConditionVariable(ConditionVariable: PCONDITION_VARIABLE)
+                                    -> () {
+        panic!("condition variables not available")
+    }
+    pub fn AcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> () {
+        panic!("rwlocks not available")
+    }
+    pub fn AcquireSRWLockShared(SRWLock: PSRWLOCK) -> () {
+        panic!("rwlocks not available")
+    }
+    pub fn ReleaseSRWLockExclusive(SRWLock: PSRWLOCK) -> () {
+        panic!("rwlocks not available")
+    }
+    pub fn ReleaseSRWLockShared(SRWLock: PSRWLOCK) -> () {
+        panic!("rwlocks not available")
+    }
+    pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN {
+        panic!("rwlocks not available")
+    }
+    pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN {
+        panic!("rwlocks not available")
+    }
+}
diff --git a/src/libstd/sys/windows/compat.rs b/src/libstd/sys/windows/compat.rs
new file mode 100644
index 0000000000000..3a03b91f24ed3
--- /dev/null
+++ b/src/libstd/sys/windows/compat.rs
@@ -0,0 +1,88 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A "compatibility layer" for spanning XP and Windows 7
+//!
+//! The standard library currently binds many functions that are not available
+//! on Windows XP, but we would also like to support building executables that
+//! run on XP. To do this we specify all non-XP APIs as having a fallback
+//! implementation to do something reasonable.
+//!
+//! This dynamic runtime detection of whether a function is available is
+//! implemented with `GetModuleHandle` and `GetProcAddress` paired with a
+//! static-per-function which caches the result of the first check. In this
+//! manner we pay a semi-large one-time cost up front for detecting whether a
+//! function is available but afterwards it's just a load and a jump.
+
+use prelude::v1::*;
+
+use ffi::CString;
+use libc::{LPVOID, LPCWSTR, HMODULE, LPCSTR};
+use sync::atomic::{AtomicUsize, Ordering};
+
+extern "system" {
+    fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE;
+    fn GetProcAddress(hModule: HMODULE, lpProcName: LPCSTR) -> LPVOID;
+}
+
+pub fn lookup(module: &str, symbol: &str) -> Option<usize> {
+    let mut module: Vec<u16> = module.utf16_units().collect();
+    module.push(0);
+    let symbol = CString::new(symbol).unwrap();
+    unsafe {
+        let handle = GetModuleHandleW(module.as_ptr());
+        match GetProcAddress(handle, symbol.as_ptr()) as usize {
+            0 => None,
+            n => Some(n),
+        }
+    }
+}
+
+pub fn store_func(ptr: &AtomicUsize, module: &str, symbol: &str,
+                  fallback: usize) -> usize {
+    let value = lookup(module, symbol).unwrap_or(fallback);
+    ptr.store(value, Ordering::SeqCst);
+    value
+}
+
+macro_rules! compat_fn {
+    ($module:ident: $(
+        pub fn $symbol:ident($($argname:ident: $argtype:ty),*)
+                                  -> $rettype:ty {
+            $($body:expr);*
+        }
+    )*) => ($(
+        #[allow(unused_variables)]
+        pub unsafe fn $symbol($($argname: $argtype),*) -> $rettype {
+            use sync::atomic::{AtomicUsize, Ordering};
+            use mem;
+            type F = unsafe extern "system" fn($($argtype),*) -> $rettype;
+
+            static PTR: AtomicUsize = AtomicUsize::new(0);
+
+            fn load() -> usize {
+                ::sys::compat::store_func(&PTR,
+                                          stringify!($module),
+                                          stringify!($symbol),
+                                          fallback as usize)
+            }
+            unsafe extern "system" fn fallback($($argname: $argtype),*)
+                                               -> $rettype {
+                $($body);*
+            }
+
+            let addr = match PTR.load(Ordering::SeqCst) {
+                0 => load(),
+                n => n,
+            };
+            mem::transmute::<usize, F>(addr)($($argname),*)
+        }
+    )*)
+}
diff --git a/src/libstd/sys/windows/condvar.rs b/src/libstd/sys/windows/condvar.rs
index baa7d1ceea331..04d62200e9bcc 100644
--- a/src/libstd/sys/windows/condvar.rs
+++ b/src/libstd/sys/windows/condvar.rs
@@ -12,35 +12,35 @@ use prelude::v1::*;
 
 use cell::UnsafeCell;
 use libc::{self, DWORD};
-use sys::os;
+use sys::c;
 use sys::mutex::{self, Mutex};
-use sys::sync as ffi;
+use sys::os;
 use time::Duration;
 
-pub struct Condvar { inner: UnsafeCell<ffi::CONDITION_VARIABLE> }
+pub struct Condvar { inner: UnsafeCell<c::CONDITION_VARIABLE> }
 
 unsafe impl Send for Condvar {}
 unsafe impl Sync for Condvar {}
 
 impl Condvar {
     pub const fn new() -> Condvar {
-        Condvar { inner: UnsafeCell::new(ffi::CONDITION_VARIABLE_INIT) }
+        Condvar { inner: UnsafeCell::new(c::CONDITION_VARIABLE_INIT) }
     }
 
     #[inline]
     pub unsafe fn wait(&self, mutex: &Mutex) {
-        let r = ffi::SleepConditionVariableSRW(self.inner.get(),
-                                               mutex::raw(mutex),
-                                               libc::INFINITE,
-                                               0);
+        let r = c::SleepConditionVariableSRW(self.inner.get(),
+                                             mutex::raw(mutex),
+                                             libc::INFINITE,
+                                             0);
         debug_assert!(r != 0);
     }
 
     pub unsafe fn wait_timeout(&self, mutex: &Mutex, dur: Duration) -> bool {
-        let r = ffi::SleepConditionVariableSRW(self.inner.get(),
-                                               mutex::raw(mutex),
-                                               super::dur2timeout(dur),
-                                               0);
+        let r = c::SleepConditionVariableSRW(self.inner.get(),
+                                             mutex::raw(mutex),
+                                             super::dur2timeout(dur),
+                                             0);
         if r == 0 {
             const ERROR_TIMEOUT: DWORD = 0x5B4;
             debug_assert_eq!(os::errno() as usize, ERROR_TIMEOUT as usize);
@@ -52,12 +52,12 @@ impl Condvar {
 
     #[inline]
     pub unsafe fn notify_one(&self) {
-        ffi::WakeConditionVariable(self.inner.get())
+        c::WakeConditionVariable(self.inner.get())
     }
 
     #[inline]
     pub unsafe fn notify_all(&self) {
-        ffi::WakeAllConditionVariable(self.inner.get())
+        c::WakeAllConditionVariable(self.inner.get())
     }
 
     pub unsafe fn destroy(&self) {
diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs
index 437b2cc649117..36fabe72aa0c1 100644
--- a/src/libstd/sys/windows/fs.rs
+++ b/src/libstd/sys/windows/fs.rs
@@ -497,12 +497,11 @@ pub fn symlink(src: &Path, dst: &Path) -> io::Result<()> {
 }
 
 pub fn symlink_inner(src: &Path, dst: &Path, dir: bool) -> io::Result<()> {
-    use sys::c::compat::kernel32::CreateSymbolicLinkW;
     let src = to_utf16(src);
     let dst = to_utf16(dst);
     let flags = if dir { c::SYMBOLIC_LINK_FLAG_DIRECTORY } else { 0 };
     try!(cvt(unsafe {
-        CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), flags) as libc::BOOL
+        c::CreateSymbolicLinkW(dst.as_ptr(), src.as_ptr(), flags) as libc::BOOL
     }));
     Ok(())
 }
@@ -565,14 +564,13 @@ pub fn utimes(p: &Path, atime: u64, mtime: u64) -> io::Result<()> {
 }
 
 pub fn canonicalize(p: &Path) -> io::Result<PathBuf> {
-    use sys::c::compat::kernel32::GetFinalPathNameByHandleW;
 
     let mut opts = OpenOptions::new();
     opts.read(true);
     let f = try!(File::open(p, &opts));
     super::fill_utf16_buf(|buf, sz| unsafe {
-        GetFinalPathNameByHandleW(f.handle.raw(), buf, sz,
-                                  libc::VOLUME_NAME_DOS)
+        c::GetFinalPathNameByHandleW(f.handle.raw(), buf, sz,
+                                     libc::VOLUME_NAME_DOS)
     }, |buf| {
         PathBuf::from(OsString::from_wide(buf))
     })
diff --git a/src/libstd/sys/windows/mod.rs b/src/libstd/sys/windows/mod.rs
index 18c8add17a6d6..b6d080109df05 100644
--- a/src/libstd/sys/windows/mod.rs
+++ b/src/libstd/sys/windows/mod.rs
@@ -22,6 +22,8 @@ use os::windows::ffi::{OsStrExt, OsStringExt};
 use path::PathBuf;
 use time::Duration;
 
+#[macro_use] pub mod compat;
+
 pub mod backtrace;
 pub mod c;
 pub mod condvar;
@@ -36,7 +38,6 @@ pub mod pipe;
 pub mod process;
 pub mod rwlock;
 pub mod stack_overflow;
-pub mod sync;
 pub mod thread;
 pub mod thread_local;
 pub mod time;
diff --git a/src/libstd/sys/windows/mutex.rs b/src/libstd/sys/windows/mutex.rs
index 29e370698ad74..277c3d14c0ec5 100644
--- a/src/libstd/sys/windows/mutex.rs
+++ b/src/libstd/sys/windows/mutex.rs
@@ -8,57 +8,154 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+//! System Mutexes
+//!
+//! The Windows implementation of mutexes is a little odd and it may not be
+//! immediately obvious what's going on. The primary oddness is that SRWLock is
+//! used instead of CriticalSection, and this is done because:
+//!
+//! 1. SRWLock is several times faster than CriticalSection according to
+//!    benchmarks performed on both Windows 8 and Windows 7.
+//!
+//! 2. CriticalSection allows recursive locking while SRWLock deadlocks. The
+//!    Unix implementation deadlocks so consistency is preferred. See #19962 for
+//!    more details.
+//!
+//! 3. While CriticalSection is fair and SRWLock is not, the current Rust policy
+//!    is there there are no guarantees of fairness.
+//!
+//! The downside of this approach, however, is that SRWLock is not available on
+//! Windows XP, so we continue to have a fallback implementation where
+//! CriticalSection is used and we keep track of who's holding the mutex to
+//! detect recursive locks.
+
 use prelude::v1::*;
 
 use cell::UnsafeCell;
-use sys::sync as ffi;
 use mem;
+use sync::atomic::{AtomicUsize, Ordering};
+use sys::c;
+use sys::compat;
 
-pub struct Mutex { inner: UnsafeCell<ffi::SRWLOCK> }
+pub struct Mutex {
+    lock: AtomicUsize,
+    held: UnsafeCell<bool>,
+}
 
 unsafe impl Send for Mutex {}
 unsafe impl Sync for Mutex {}
 
-#[inline]
-pub unsafe fn raw(m: &Mutex) -> ffi::PSRWLOCK {
-    m.inner.get()
+#[derive(Clone, Copy)]
+enum Kind {
+    SRWLock = 1,
+    CriticalSection = 2,
 }
 
-// So you might be asking why we're using SRWLock instead of CriticalSection?
-//
-// 1. SRWLock is several times faster than CriticalSection according to
-//    benchmarks performed on both Windows 8 and Windows 7.
-//
-// 2. CriticalSection allows recursive locking while SRWLock deadlocks. The Unix
-//    implementation deadlocks so consistency is preferred. See #19962 for more
-//    details.
-//
-// 3. While CriticalSection is fair and SRWLock is not, the current Rust policy
-//    is there there are no guarantees of fairness.
+#[inline]
+pub unsafe fn raw(m: &Mutex) -> c::PSRWLOCK {
+    debug_assert!(mem::size_of::<c::SRWLOCK>() <= mem::size_of_val(&m.lock));
+    &m.lock as *const _ as *mut _
+}
 
 impl Mutex {
     pub const fn new() -> Mutex {
-        Mutex { inner: UnsafeCell::new(ffi::SRWLOCK_INIT) }
+        Mutex {
+            lock: AtomicUsize::new(0),
+            held: UnsafeCell::new(false),
+        }
     }
-    #[inline]
     pub unsafe fn lock(&self) {
-        ffi::AcquireSRWLockExclusive(self.inner.get())
+        match kind() {
+            Kind::SRWLock => c::AcquireSRWLockExclusive(raw(self)),
+            Kind::CriticalSection => {
+                let re = self.remutex();
+                (*re).lock();
+                if !self.flag_locked() {
+                    (*re).unlock();
+                    panic!("cannot recursively lock a mutex");
+                }
+            }
+        }
     }
-    #[inline]
     pub unsafe fn try_lock(&self) -> bool {
-        ffi::TryAcquireSRWLockExclusive(self.inner.get()) != 0
+        match kind() {
+            Kind::SRWLock => c::TryAcquireSRWLockExclusive(raw(self)) != 0,
+            Kind::CriticalSection => {
+                let re = self.remutex();
+                if !(*re).try_lock() {
+                    false
+                } else if self.flag_locked() {
+                    true
+                } else {
+                    (*re).unlock();
+                    false
+                }
+            }
+        }
     }
-    #[inline]
     pub unsafe fn unlock(&self) {
-        ffi::ReleaseSRWLockExclusive(self.inner.get())
+        *self.held.get() = false;
+        match kind() {
+            Kind::SRWLock => c::ReleaseSRWLockExclusive(raw(self)),
+            Kind::CriticalSection => (*self.remutex()).unlock(),
+        }
     }
-    #[inline]
     pub unsafe fn destroy(&self) {
-        // ...
+        match kind() {
+            Kind::SRWLock => {}
+            Kind::CriticalSection => {
+                match self.lock.load(Ordering::SeqCst) {
+                    0 => {}
+                    n => { Box::from_raw(n as *mut ReentrantMutex).destroy(); }
+                }
+            }
+        }
+    }
+
+    unsafe fn remutex(&self) -> *mut ReentrantMutex {
+        match self.lock.load(Ordering::SeqCst) {
+            0 => {}
+            n => return n as *mut _,
+        }
+        let mut re = Box::new(ReentrantMutex::uninitialized());
+        re.init();
+        let re = Box::into_raw(re);
+        match self.lock.compare_and_swap(0, re as usize, Ordering::SeqCst) {
+            0 => re,
+            n => { Box::from_raw(re).destroy(); n as *mut _ }
+        }
+    }
+
+    unsafe fn flag_locked(&self) -> bool {
+        if *self.held.get() {
+            false
+        } else {
+            *self.held.get() = true;
+            true
+        }
+
     }
 }
 
-pub struct ReentrantMutex { inner: UnsafeCell<ffi::CRITICAL_SECTION> }
+fn kind() -> Kind {
+    static KIND: AtomicUsize = AtomicUsize::new(0);
+
+    let val = KIND.load(Ordering::SeqCst);
+    if val == Kind::SRWLock as usize {
+        return Kind::SRWLock
+    } else if val == Kind::CriticalSection as usize {
+        return Kind::CriticalSection
+    }
+
+    let ret = match compat::lookup("kernel32", "AcquireSRWLockExclusive") {
+        None => Kind::CriticalSection,
+        Some(..) => Kind::SRWLock,
+    };
+    KIND.store(ret as usize, Ordering::SeqCst);
+    return ret;
+}
+
+pub struct ReentrantMutex { inner: UnsafeCell<c::CRITICAL_SECTION> }
 
 unsafe impl Send for ReentrantMutex {}
 unsafe impl Sync for ReentrantMutex {}
@@ -69,23 +166,23 @@ impl ReentrantMutex {
     }
 
     pub unsafe fn init(&mut self) {
-        ffi::InitializeCriticalSection(self.inner.get());
+        c::InitializeCriticalSection(self.inner.get());
     }
 
     pub unsafe fn lock(&self) {
-        ffi::EnterCriticalSection(self.inner.get());
+        c::EnterCriticalSection(self.inner.get());
     }
 
     #[inline]
     pub unsafe fn try_lock(&self) -> bool {
-        ffi::TryEnterCriticalSection(self.inner.get()) != 0
+        c::TryEnterCriticalSection(self.inner.get()) != 0
     }
 
     pub unsafe fn unlock(&self) {
-        ffi::LeaveCriticalSection(self.inner.get());
+        c::LeaveCriticalSection(self.inner.get());
     }
 
     pub unsafe fn destroy(&self) {
-        ffi::DeleteCriticalSection(self.inner.get());
+        c::DeleteCriticalSection(self.inner.get());
     }
 }
diff --git a/src/libstd/sys/windows/rwlock.rs b/src/libstd/sys/windows/rwlock.rs
index e727638e3e9b5..25865286db051 100644
--- a/src/libstd/sys/windows/rwlock.rs
+++ b/src/libstd/sys/windows/rwlock.rs
@@ -11,40 +11,40 @@
 use prelude::v1::*;
 
 use cell::UnsafeCell;
-use sys::sync as ffi;
+use sys::c;
 
-pub struct RWLock { inner: UnsafeCell<ffi::SRWLOCK> }
+pub struct RWLock { inner: UnsafeCell<c::SRWLOCK> }
 
 unsafe impl Send for RWLock {}
 unsafe impl Sync for RWLock {}
 
 impl RWLock {
     pub const fn new() -> RWLock {
-        RWLock { inner: UnsafeCell::new(ffi::SRWLOCK_INIT) }
+        RWLock { inner: UnsafeCell::new(c::SRWLOCK_INIT) }
     }
     #[inline]
     pub unsafe fn read(&self) {
-        ffi::AcquireSRWLockShared(self.inner.get())
+        c::AcquireSRWLockShared(self.inner.get())
     }
     #[inline]
     pub unsafe fn try_read(&self) -> bool {
-        ffi::TryAcquireSRWLockShared(self.inner.get()) != 0
+        c::TryAcquireSRWLockShared(self.inner.get()) != 0
     }
     #[inline]
     pub unsafe fn write(&self) {
-        ffi::AcquireSRWLockExclusive(self.inner.get())
+        c::AcquireSRWLockExclusive(self.inner.get())
     }
     #[inline]
     pub unsafe fn try_write(&self) -> bool {
-        ffi::TryAcquireSRWLockExclusive(self.inner.get()) != 0
+        c::TryAcquireSRWLockExclusive(self.inner.get()) != 0
     }
     #[inline]
     pub unsafe fn read_unlock(&self) {
-        ffi::ReleaseSRWLockShared(self.inner.get())
+        c::ReleaseSRWLockShared(self.inner.get())
     }
     #[inline]
     pub unsafe fn write_unlock(&self) {
-        ffi::ReleaseSRWLockExclusive(self.inner.get())
+        c::ReleaseSRWLockExclusive(self.inner.get())
     }
 
     #[inline]
diff --git a/src/libstd/sys/windows/stack_overflow.rs b/src/libstd/sys/windows/stack_overflow.rs
index 79b7de4f341ac..cf827848db5c9 100644
--- a/src/libstd/sys/windows/stack_overflow.rs
+++ b/src/libstd/sys/windows/stack_overflow.rs
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use rt::util::report_overflow;
 use core::prelude::*;
-use ptr;
-use mem;
+
+use libc::types::os::arch::extra::{LPVOID, DWORD, LONG};
 use libc;
-use libc::types::os::arch::extra::{LPVOID, DWORD, LONG, BOOL};
+use mem;
+use ptr;
+use rt::util::report_overflow;
+use sys::c;
 use sys_common::stack;
 
 pub struct Handler {
@@ -69,8 +71,12 @@ pub unsafe fn cleanup() {
 }
 
 pub unsafe fn make_handler() -> Handler {
-    if SetThreadStackGuarantee(&mut 0x5000) == 0 {
-        panic!("failed to reserve stack space for exception handling");
+    // This API isn't available on XP, so don't panic in that case and just pray
+    // it works out ok.
+    if c::SetThreadStackGuarantee(&mut 0x5000) == 0 {
+        if libc::GetLastError() as u32 != libc::ERROR_CALL_NOT_IMPLEMENTED as u32 {
+            panic!("failed to reserve stack space for exception handling");
+        }
     }
 
     Handler { _data: 0 as *mut libc::c_void }
@@ -103,5 +109,4 @@ extern "system" {
     fn AddVectoredExceptionHandler(FirstHandler: ULONG,
                                    VectoredHandler: PVECTORED_EXCEPTION_HANDLER)
                                   -> LPVOID;
-    fn SetThreadStackGuarantee(StackSizeInBytes: *mut ULONG) -> BOOL;
 }
diff --git a/src/libstd/sys/windows/sync.rs b/src/libstd/sys/windows/sync.rs
deleted file mode 100644
index 5410259540eac..0000000000000
--- a/src/libstd/sys/windows/sync.rs
+++ /dev/null
@@ -1,60 +0,0 @@
-// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-use libc::{BOOL, DWORD, LPVOID, LONG, HANDLE, c_ulong};
-use libc::types::os::arch::extra::BOOLEAN;
-
-pub type PCONDITION_VARIABLE = *mut CONDITION_VARIABLE;
-pub type PSRWLOCK = *mut SRWLOCK;
-pub type ULONG = c_ulong;
-pub type ULONG_PTR = c_ulong;
-
-#[repr(C)]
-pub struct CONDITION_VARIABLE { pub ptr: LPVOID }
-#[repr(C)]
-pub struct SRWLOCK { pub ptr: LPVOID }
-#[repr(C)]
-pub struct CRITICAL_SECTION {
-    CriticalSectionDebug: LPVOID,
-    LockCount: LONG,
-    RecursionCount: LONG,
-    OwningThread: HANDLE,
-    LockSemaphore: HANDLE,
-    SpinCount: ULONG_PTR
-}
-
-pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE {
-    ptr: 0 as *mut _,
-};
-pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { ptr: 0 as *mut _ };
-
-extern "system" {
-    // condition variables
-    pub fn SleepConditionVariableSRW(ConditionVariable: PCONDITION_VARIABLE,
-                                     SRWLock: PSRWLOCK,
-                                     dwMilliseconds: DWORD,
-                                     Flags: ULONG) -> BOOL;
-    pub fn WakeConditionVariable(ConditionVariable: PCONDITION_VARIABLE);
-    pub fn WakeAllConditionVariable(ConditionVariable: PCONDITION_VARIABLE);
-
-    // slim rwlocks
-    pub fn AcquireSRWLockExclusive(SRWLock: PSRWLOCK);
-    pub fn AcquireSRWLockShared(SRWLock: PSRWLOCK);
-    pub fn ReleaseSRWLockExclusive(SRWLock: PSRWLOCK);
-    pub fn ReleaseSRWLockShared(SRWLock: PSRWLOCK);
-    pub fn TryAcquireSRWLockExclusive(SRWLock: PSRWLOCK) -> BOOLEAN;
-    pub fn TryAcquireSRWLockShared(SRWLock: PSRWLOCK) -> BOOLEAN;
-
-    pub fn InitializeCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
-    pub fn EnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
-    pub fn TryEnterCriticalSection(CriticalSection: *mut CRITICAL_SECTION) -> BOOLEAN;
-    pub fn LeaveCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
-    pub fn DeleteCriticalSection(CriticalSection: *mut CRITICAL_SECTION);
-}