diff options
| author | bors <bors@rust-lang.org> | 2018-10-12 15:00:24 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-10-12 15:00:24 +0000 |
| commit | 945372d26818f93d6f5cded7b751749e280b67bf (patch) | |
| tree | 434e524cba2dee5a76b2aca15ef28c1f3229ff8e /src/liballoc_system | |
| parent | e9e27e6a6258b3adf00a5dd35d2676656224880d (diff) | |
| parent | d64c77a671390a7ce9072e550ffa57837892a4fe (diff) | |
| download | rust-945372d26818f93d6f5cded7b751749e280b67bf.tar.gz rust-945372d26818f93d6f5cded7b751749e280b67bf.zip | |
Auto merge of #55012 - kennytm:rollup, r=kennytm
Rollup of 16 pull requests
Successful merges:
- #54755 (Documents reference equality by address (#54197))
- #54811 (During rustc bootstrap, make default for `optimize` independent of `debug`)
- #54825 (NLL says "borrowed content" instead of more precise "dereference of raw pointer")
- #54860 (Add doc comments about safest way to initialize a vector of zeros)
- #54869 (Fix mobile docs)
- #54891 (Fix tracking issue for Once::is_completed)
- #54913 (doc fix: it's auto traits that make for automatic implementations)
- #54920 (Fix handling of #[must_use] on unit and uninhabited types)
- #54932 (A handful of random string-related improvements)
- #54936 (impl Eq+Hash for TyLayout)
- #54950 (std: Synchronize global allocator on wasm32)
- #54956 ("(using ..." doesn't have the matching ")")
- #54958 (add a macro for static (compile-time) assertions)
- #54967 (Remove incorrect span for second label inner macro invocation)
- #54983 (Fix slice's benchmarks)
- #54989 (Fix spelling in the documentation to htmldocck.py)
Failed merges:
r? @ghost
Diffstat (limited to 'src/liballoc_system')
| -rw-r--r-- | src/liballoc_system/lib.rs | 53 |
1 files changed, 52 insertions, 1 deletions
diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs index 3ef03ec6d58..15283036bb4 100644 --- a/src/liballoc_system/lib.rs +++ b/src/liballoc_system/lib.rs @@ -20,6 +20,10 @@ #![feature(nll)] #![feature(staged_api)] #![feature(rustc_attrs)] +#![cfg_attr( + all(target_arch = "wasm32", not(target_os = "emscripten")), + feature(integer_atomics, stdsimd) +)] #![cfg_attr(any(unix, target_os = "cloudabi", target_os = "redox"), feature(libc))] #![rustc_alloc_kind = "lib"] @@ -331,29 +335,76 @@ mod platform { use core::alloc::{GlobalAlloc, Layout}; use System; - // No need for synchronization here as wasm is currently single-threaded static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::DLMALLOC_INIT; #[stable(feature = "alloc_system_type", since = "1.28.0")] unsafe impl GlobalAlloc for System { #[inline] unsafe fn alloc(&self, layout: Layout) -> *mut u8 { + let _lock = lock::lock(); DLMALLOC.malloc(layout.size(), layout.align()) } #[inline] unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { + let _lock = lock::lock(); DLMALLOC.calloc(layout.size(), layout.align()) } #[inline] unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { + let _lock = lock::lock(); DLMALLOC.free(ptr, layout.size(), layout.align()) } #[inline] unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { + let _lock = lock::lock(); DLMALLOC.realloc(ptr, layout.size(), layout.align(), new_size) } } + + #[cfg(target_feature = "atomics")] + mod lock { + use core::arch::wasm32; + use core::sync::atomic::{AtomicI32, Ordering::SeqCst}; + + static LOCKED: AtomicI32 = AtomicI32::new(0); + + pub struct DropLock; + + pub fn lock() -> DropLock { + loop { + if LOCKED.swap(1, SeqCst) == 0 { + return DropLock + } + unsafe { + let r = wasm32::atomic::wait_i32( + &LOCKED as *const AtomicI32 as *mut i32, + 1, // expected value + -1, // timeout + ); + debug_assert!(r == 0 || r == 1); + } + } + } + + impl Drop for DropLock { + fn drop(&mut self) { + let r = LOCKED.swap(0, SeqCst); + debug_assert_eq!(r, 1); + unsafe { + wasm32::atomic::wake( + &LOCKED as *const AtomicI32 as *mut i32, + 1, // only one thread + ); + } + } + } + } + + #[cfg(not(target_feature = "atomics"))] + mod lock { + pub fn lock() {} // no atomics, no threads, that's easy! + } } |
