diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-11-30 16:56:47 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-11-30 16:56:47 +0100 |
| commit | 123406cac7168fa2e169b404b852d1d265f34c99 (patch) | |
| tree | 75fad4fe46779d6222deca4884499ba8cd7cb4ee /src/libstd/sys | |
| parent | 3af14f994d7d5f0cef7d1f15bcfe6cab40685244 (diff) | |
| parent | d34090a10a6517f3e3ea8528936175953ce8bc3d (diff) | |
| download | rust-123406cac7168fa2e169b404b852d1d265f34c99.tar.gz rust-123406cac7168fa2e169b404b852d1d265f34c99.zip | |
Rollup merge of #66705 - pitdicker:atomic_mut_ptr, r=KodrAus
Atomic as_mut_ptr
I encountered the following pattern a few times: In Rust we use some atomic type like `AtomicI32`, and an FFI interface exposes this as `*mut i32` (or some similar `libc` type).
It was not obvious to me if a just transmuting a pointer to the atomic was acceptable, or if this should use a cast that goes through an `UnsafeCell`. See https://github.com/rust-lang/rust/issues/66136#issuecomment-557802477
Transmuting the pointer directly:
```rust
let atomic = AtomicI32::new(1);
let ptr = &atomic as *const AtomicI32 as *mut i32;
unsafe {
ffi(ptr);
}
```
A dance with `UnsafeCell`:
```rust
let atomic = AtomicI32::new(1);
unsafe {
let ptr = (&*(&atomic as *const AtomicI32 as *const UnsafeCell<i32>)).get();
ffi(ptr);
}
```
Maybe in the end both ways could be valid. But why not expose a direct method to get a pointer from the standard library?
An `as_mut_ptr` method on atomics can be safe, because only the use of the resulting pointer is where things can get unsafe. I documented its use for FFI, and "Doing non-atomic reads and writes on the resulting integer can be a data race."
The standard library could make use this method in a few places in the WASM module.
cc @RalfJung as you answered my original question.
Diffstat (limited to 'src/libstd/sys')
| -rw-r--r-- | src/libstd/sys/wasm/alloc.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sys/wasm/condvar_atomics.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sys/wasm/mutex_atomics.rs | 4 |
3 files changed, 5 insertions, 5 deletions
diff --git a/src/libstd/sys/wasm/alloc.rs b/src/libstd/sys/wasm/alloc.rs index c1af6ec1262..05e55334ac0 100644 --- a/src/libstd/sys/wasm/alloc.rs +++ b/src/libstd/sys/wasm/alloc.rs @@ -67,7 +67,7 @@ mod lock { // // unsafe { // let r = core::arch::wasm32::i32_atomic_wait( - // &LOCKED as *const AtomicI32 as *mut i32, + // LOCKED.as_mut_ptr(), // 1, // expected value // -1, // timeout // ); @@ -143,7 +143,7 @@ mod lock { // // unsafe { // core::arch::wasm32::atomic_notify( - // &LOCKED as *const AtomicI32 as *mut i32, + // LOCKED.as_mut_ptr(), // 1, // only one thread // ); // } diff --git a/src/libstd/sys/wasm/condvar_atomics.rs b/src/libstd/sys/wasm/condvar_atomics.rs index 580d2121844..f452bbd3487 100644 --- a/src/libstd/sys/wasm/condvar_atomics.rs +++ b/src/libstd/sys/wasm/condvar_atomics.rs @@ -89,6 +89,6 @@ impl Condvar { #[inline] fn ptr(&self) -> *mut i32 { assert_eq!(mem::size_of::<usize>(), mem::size_of::<i32>()); - &self.cnt as *const AtomicUsize as *mut i32 + self.cnt.as_mut_ptr() as *mut i32 } } diff --git a/src/libstd/sys/wasm/mutex_atomics.rs b/src/libstd/sys/wasm/mutex_atomics.rs index 0e4f3d80aa9..cddd584dd22 100644 --- a/src/libstd/sys/wasm/mutex_atomics.rs +++ b/src/libstd/sys/wasm/mutex_atomics.rs @@ -56,7 +56,7 @@ impl Mutex { #[inline] fn ptr(&self) -> *mut i32 { assert_eq!(mem::size_of::<usize>(), mem::size_of::<i32>()); - &self.locked as *const AtomicUsize as *mut isize as *mut i32 + self.locked.as_mut_ptr() as *mut i32 } } @@ -145,6 +145,6 @@ impl ReentrantMutex { #[inline] fn ptr(&self) -> *mut i32 { - &self.owner as *const AtomicU32 as *mut i32 + self.owner.as_mut_ptr() as *mut i32 } } |
