diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs index 31491106d97ee..dd22894ea95b2 100644 --- a/src/liballoc/lib.rs +++ b/src/liballoc/lib.rs @@ -74,6 +74,7 @@ #![feature(allocator)] #![feature(box_syntax)] +#![feature(cfg_target_has_atomic)] #![feature(coerce_unsized)] #![feature(const_fn)] #![feature(core_intrinsics)] @@ -117,6 +118,7 @@ mod boxed { } #[cfg(test)] mod boxed_test; +#[cfg(target_has_atomic = "ptr")] pub mod arc; pub mod rc; pub mod raw_vec; diff --git a/src/liballoc/oom.rs b/src/liballoc/oom.rs index d355d59185eb4..3640156fec2ae 100644 --- a/src/liballoc/oom.rs +++ b/src/liballoc/oom.rs @@ -8,12 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use core::sync::atomic::{AtomicPtr, Ordering}; -use core::mem; +#[cfg(target_has_atomic = "ptr")] +pub use self::imp::set_oom_handler; use core::intrinsics; -static OOM_HANDLER: AtomicPtr<()> = AtomicPtr::new(default_oom_handler as *mut ()); - fn default_oom_handler() -> ! { // The default handler can't do much more since we can't assume the presence // of libc or any way of printing an error message. @@ -26,17 +24,38 @@ fn default_oom_handler() -> ! { #[unstable(feature = "oom", reason = "not a scrutinized interface", issue = "27700")] pub fn oom() -> ! { - let value = OOM_HANDLER.load(Ordering::SeqCst); - let handler: fn() -> ! = unsafe { mem::transmute(value) }; - handler(); + self::imp::oom() } -/// Set a custom handler for out-of-memory conditions -/// -/// To avoid recursive OOM failures, it is critical that the OOM handler does -/// not allocate any memory itself. -#[unstable(feature = "oom", reason = "not a scrutinized interface", - issue = "27700")] -pub fn set_oom_handler(handler: fn() -> !) { - OOM_HANDLER.store(handler as *mut (), Ordering::SeqCst); +#[cfg(target_has_atomic = "ptr")] +mod imp { + use core::mem; + use core::sync::atomic::{AtomicPtr, Ordering}; + + static OOM_HANDLER: AtomicPtr<()> = AtomicPtr::new(super::default_oom_handler as *mut ()); + + #[inline(always)] + pub fn oom() -> ! { + let value = OOM_HANDLER.load(Ordering::SeqCst); + let handler: fn() -> ! = unsafe { mem::transmute(value) }; + handler(); + } + + /// Set a custom handler for out-of-memory conditions + /// + /// To avoid recursive OOM failures, it is critical that the OOM handler does + /// not allocate any memory itself. + #[unstable(feature = "oom", reason = "not a scrutinized interface", + issue = "27700")] + pub fn set_oom_handler(handler: fn() -> !) { + OOM_HANDLER.store(handler as *mut (), Ordering::SeqCst); + } +} + +#[cfg(not(target_has_atomic = "ptr"))] +mod imp { + #[inline(always)] + pub fn oom() -> ! { + super::default_oom_handler() + } }