about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorAmanieu d'Antras <amanieu@gmail.com>2016-02-18 20:01:11 +0000
committerAmanieu d'Antras <amanieu@gmail.com>2016-02-18 20:18:36 +0000
commit7ae4ee80d16b51e617af89aa9a7ca4cce9ae5441 (patch)
treed6166a0b909c88222f370071a1eaa5c49f7bfc43 /src/libcore
parent8e2a577804b32b6d203abe61e0cdf3a88837d228 (diff)
downloadrust-7ae4ee80d16b51e617af89aa9a7ca4cce9ae5441.tar.gz
rust-7ae4ee80d16b51e617af89aa9a7ca4cce9ae5441.zip
Implement read_volatile and write_volatile
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/ptr.rs48
1 files changed, 48 insertions, 0 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.