diff options
| author | bors <bors@rust-lang.org> | 2016-02-21 00:56:08 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2016-02-21 00:56:08 +0000 |
| commit | a2fb48e9f76aabd543e4f6352ac32109e09fab22 (patch) | |
| tree | eab0306c3ac87aa48fa4d8c2bbab528b377014c8 | |
| parent | c894ff6b1249fc59ce583054011cf5966c6fcc97 (diff) | |
| parent | 3b67e467b26d54111da36c7af62fbfdbf611ebe3 (diff) | |
| download | rust-a2fb48e9f76aabd543e4f6352ac32109e09fab22.tar.gz rust-a2fb48e9f76aabd543e4f6352ac32109e09fab22.zip | |
Auto merge of #31761 - Amanieu:volatile, r=alexcrichton
Tracking issue: #31756 RFC: rust-lang/rfcs#1467 I've made these unstable for now. Should they be stabilized straight away since we've had plenty of experience with people using the unstable intrinsics?
| -rw-r--r-- | src/libcore/ptr.rs | 48 | ||||
| -rw-r--r-- | src/test/run-make/volatile-intrinsics/main.rs | 8 |
2 files changed, 55 insertions, 1 deletions
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 3cbb2f17be7..f871857dab6 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -161,6 +161,54 @@ pub unsafe fn write<T>(dst: *mut T, src: T) { intrinsics::move_val_init(&mut *dst, src) } +/// Performs a volatile read of the value from `src` without moving it. This +/// leaves the memory in `src` unchanged. +/// +/// Volatile operations are intended to act on I/O memory, and are guaranteed +/// to not be elided or reordered by the compiler across other volatile +/// operations. See the LLVM documentation on [[volatile]]. +/// +/// [volatile]: http://llvm.org/docs/LangRef.html#volatile-memory-accesses +/// +/// # Safety +/// +/// Beyond accepting a raw pointer, this is unsafe because it semantically +/// moves the value out of `src` without preventing further usage of `src`. +/// If `T` is not `Copy`, then care must be taken to ensure that the value at +/// `src` is not used before the data is overwritten again (e.g. with `write`, +/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use +/// because it will attempt to drop the value previously at `*src`. +#[inline] +#[unstable(feature = "volatile", reason = "recently added", issue = "31756")] +pub unsafe fn read_volatile<T>(src: *const T) -> T { + intrinsics::volatile_load(src) +} + +/// Performs a volatile write of a memory location with the given value without +/// reading or dropping the old value. +/// +/// Volatile operations are intended to act on I/O memory, and are guaranteed +/// to not be elided or reordered by the compiler across other volatile +/// operations. See the LLVM documentation on [[volatile]]. +/// +/// [volatile]: http://llvm.org/docs/LangRef.html#volatile-memory-accesses +/// +/// # Safety +/// +/// This operation is marked unsafe because it accepts a raw pointer. +/// +/// It does not drop the contents of `dst`. This is safe, but it could leak +/// allocations or resources, so care must be taken not to overwrite an object +/// that should be dropped. +/// +/// This is appropriate for initializing uninitialized memory, or overwriting +/// memory that has previously been `read` from. +#[inline] +#[unstable(feature = "volatile", reason = "recently added", issue = "31756")] +pub unsafe fn write_volatile<T>(dst: *mut T, src: T) { + intrinsics::volatile_store(dst, src); +} + #[lang = "const_ptr"] impl<T: ?Sized> *const T { /// Returns true if the pointer is null. diff --git a/src/test/run-make/volatile-intrinsics/main.rs b/src/test/run-make/volatile-intrinsics/main.rs index 6c6afdc1303..4d0d7672101 100644 --- a/src/test/run-make/volatile-intrinsics/main.rs +++ b/src/test/run-make/volatile-intrinsics/main.rs @@ -8,9 +8,10 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![feature(core_intrinsics)] +#![feature(core_intrinsics, volatile)] use std::intrinsics::{volatile_load, volatile_store}; +use std::ptr::{read_volatile, write_volatile}; pub fn main() { unsafe { @@ -18,4 +19,9 @@ pub fn main() { volatile_store(&mut i, 2); assert_eq!(volatile_load(&i), 2); } + unsafe { + let mut i : isize = 1; + write_volatile(&mut i, 2); + assert_eq!(read_volatile(&i), 2); + } } |
