From e1e0df8a49d8c172261be1d71e33632200629cce Mon Sep 17 00:00:00 2001 From: Nathan Date: Mon, 22 Jul 2019 17:17:37 -0400 Subject: [PATCH 1/4] Remove uses of mem::uninitialized in std::sys::cloudabi Usages still appear in cloudabi tests and in the reentrant mutex implementation --- src/libstd/lib.rs | 1 + src/libstd/sys/cloudabi/condvar.rs | 29 ++++++++++++++++++++--------- src/libstd/sys/cloudabi/mod.rs | 9 ++++++--- src/libstd/sys/cloudabi/time.rs | 8 ++++---- 4 files changed, 31 insertions(+), 16 deletions(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 49fb4be39b451..fbc68c610ee39 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -273,6 +273,7 @@ #![feature(link_args)] #![feature(linkage)] #![feature(maybe_uninit_ref)] +#![feature(maybe_uninit_slice)] #![feature(mem_take)] #![feature(needs_panic_runtime)] #![feature(never_type)] diff --git a/src/libstd/sys/cloudabi/condvar.rs b/src/libstd/sys/cloudabi/condvar.rs index 7aa0b0b6f4912..bce76a082e64b 100644 --- a/src/libstd/sys/cloudabi/condvar.rs +++ b/src/libstd/sys/cloudabi/condvar.rs @@ -79,16 +79,21 @@ impl Condvar { }, ..mem::zeroed() }; - let mut event: abi::event = mem::uninitialized(); - let mut nevents: usize = mem::uninitialized(); - let ret = abi::poll(&subscription, &mut event, 1, &mut nevents); + let mut event: mem::MaybeUninit = mem::MaybeUninit::uninit(); + let mut nevents: mem::MaybeUninit = mem::MaybeUninit::uninit(); + let ret = abi::poll( + &subscription, + event.as_mut_ptr(), + 1, + nevents.get_mut() + ); assert_eq!( ret, abi::errno::SUCCESS, "Failed to wait on condition variable" ); assert_eq!( - event.error, + event.assume_init().error, abi::errno::SUCCESS, "Failed to wait on condition variable" ); @@ -131,21 +136,27 @@ impl Condvar { ..mem::zeroed() }, ]; - let mut events: [abi::event; 2] = mem::uninitialized(); - let mut nevents: usize = mem::uninitialized(); - let ret = abi::poll(subscriptions.as_ptr(), events.as_mut_ptr(), 2, &mut nevents); + let mut events: [mem::MaybeUninit; 2] = [mem::MaybeUninit::uninit(); 2]; + let mut nevents: mem::MaybeUninit = mem::MaybeUninit::uninit(); + let ret = abi::poll( + subscriptions.as_ptr(), + mem::MaybeUninit::first_ptr_mut(&mut events), + 2, + nevents.get_mut() + ); assert_eq!( ret, abi::errno::SUCCESS, "Failed to wait on condition variable" ); + let nevents = nevents.assume_init(); for i in 0..nevents { assert_eq!( - events[i].error, + events[i].assume_init().error, abi::errno::SUCCESS, "Failed to wait on condition variable" ); - if events[i].type_ == abi::eventtype::CONDVAR { + if events[i].assume_init().type_ == abi::eventtype::CONDVAR { return true; } } diff --git a/src/libstd/sys/cloudabi/mod.rs b/src/libstd/sys/cloudabi/mod.rs index 77a52a8743d95..091b31002fdeb 100644 --- a/src/libstd/sys/cloudabi/mod.rs +++ b/src/libstd/sys/cloudabi/mod.rs @@ -61,8 +61,11 @@ pub use libc::strlen; pub fn hashmap_random_keys() -> (u64, u64) { unsafe { - let mut v = mem::uninitialized(); - libc::arc4random_buf(&mut v as *mut _ as *mut libc::c_void, mem::size_of_val(&v)); - v + let mut v: mem::MaybeUninit<(u64, u64)> = mem::MaybeUninit::uninit(); + libc::arc4random_buf( + v.as_mut_ptr() as *mut libc::c_void, + mem::size_of_val(v.get_ref()) + ); + v.assume_init() } } diff --git a/src/libstd/sys/cloudabi/time.rs b/src/libstd/sys/cloudabi/time.rs index 49a234e115804..fc5ffb8756083 100644 --- a/src/libstd/sys/cloudabi/time.rs +++ b/src/libstd/sys/cloudabi/time.rs @@ -18,8 +18,8 @@ pub fn checked_dur2intervals(dur: &Duration) -> Option { impl Instant { pub fn now() -> Instant { unsafe { - let mut t = mem::uninitialized(); - let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, &mut t); + let mut t: mem::MaybeUninit = mem::MaybeUninit::uninit(); + let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, t.get_mut()); assert_eq!(ret, abi::errno::SUCCESS); Instant { t } } @@ -59,8 +59,8 @@ pub struct SystemTime { impl SystemTime { pub fn now() -> SystemTime { unsafe { - let mut t = mem::uninitialized(); - let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, &mut t); + let mut t: mem::MaybeUninit = mem::MaybeUninit::uninit(); + let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, t.get_mut()); assert_eq!(ret, abi::errno::SUCCESS); SystemTime { t } } From 82dd54baf3fda351abd56ee4bda9f8464da2df67 Mon Sep 17 00:00:00 2001 From: Nathan Date: Mon, 22 Jul 2019 17:31:35 -0400 Subject: [PATCH 2/4] Modify CloudABI ReentrantMutex to use MaybeUninit Remove uses of mem::uninitialized, which is now deprecated --- src/libstd/sys/cloudabi/mutex.rs | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/src/libstd/sys/cloudabi/mutex.rs b/src/libstd/sys/cloudabi/mutex.rs index 5e191e31d5fc4..d1203a3536971 100644 --- a/src/libstd/sys/cloudabi/mutex.rs +++ b/src/libstd/sys/cloudabi/mutex.rs @@ -1,5 +1,6 @@ use crate::cell::UnsafeCell; use crate::mem; +use crate::mem::MaybeUninit; use crate::sync::atomic::{AtomicU32, Ordering}; use crate::sys::cloudabi::abi; use crate::sys::rwlock::{self, RWLock}; @@ -47,25 +48,28 @@ impl Mutex { } pub struct ReentrantMutex { - lock: UnsafeCell, - recursion: UnsafeCell, + lock: UnsafeCell>, + recursion: UnsafeCell>, } impl ReentrantMutex { pub unsafe fn uninitialized() -> ReentrantMutex { - mem::uninitialized() + ReentrantMutex { + lock: UnsafeCell::new(MaybeUninit::uninit()), + recursion: UnsafeCell::new(MaybeUninit::uninit()) + } } pub unsafe fn init(&mut self) { - self.lock = UnsafeCell::new(AtomicU32::new(abi::LOCK_UNLOCKED.0)); - self.recursion = UnsafeCell::new(0); + self.lock = UnsafeCell::new(MaybeUninit::new(AtomicU32::new(abi::LOCK_UNLOCKED.0))); + self.recursion = UnsafeCell::new(MaybeUninit::new(0)); } pub unsafe fn try_lock(&self) -> bool { // Attempt to acquire the lock. let lock = self.lock.get(); let recursion = self.recursion.get(); - if let Err(old) = (*lock).compare_exchange( + if let Err(old) = (*(*lock).as_mut_ptr()).compare_exchange( abi::LOCK_UNLOCKED.0, __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0, Ordering::Acquire, @@ -74,14 +78,14 @@ impl ReentrantMutex { // If we fail to acquire the lock, it may be the case // that we've already acquired it and may need to recurse. if old & !abi::LOCK_KERNEL_MANAGED.0 == __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0 { - *recursion += 1; + *(*recursion).as_mut_ptr() += 1; true } else { false } } else { // Success. - assert_eq!(*recursion, 0, "Mutex has invalid recursion count"); + assert_eq!(*(*recursion).as_mut_ptr(), 0, "Mutex has invalid recursion count"); true } } @@ -112,14 +116,14 @@ impl ReentrantMutex { let lock = self.lock.get(); let recursion = self.recursion.get(); assert_eq!( - (*lock).load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0, + (*(*lock).as_mut_ptr()).load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0, __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0, "This mutex is locked by a different thread" ); - if *recursion > 0 { - *recursion -= 1; - } else if !(*lock) + if *(*recursion).as_mut_ptr() > 0 { + *(*recursion).as_mut_ptr() -= 1; + } else if !(*(*lock).as_mut_ptr()) .compare_exchange( __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0, abi::LOCK_UNLOCKED.0, @@ -139,10 +143,10 @@ impl ReentrantMutex { let lock = self.lock.get(); let recursion = self.recursion.get(); assert_eq!( - (*lock).load(Ordering::Relaxed), + (*(*lock).as_mut_ptr()).load(Ordering::Relaxed), abi::LOCK_UNLOCKED.0, "Attempted to destroy locked mutex" ); - assert_eq!(*recursion, 0, "Recursion counter invalid"); + assert_eq!(*(*recursion).as_mut_ptr(), 0, "Recursion counter invalid"); } } From 0ac6afafa61044831c6e019e8aee46ecc7243d90 Mon Sep 17 00:00:00 2001 From: Nathan Date: Tue, 23 Jul 2019 10:20:33 -0400 Subject: [PATCH 3/4] Cleanup std::sys::cloudabi --- src/libstd/sys/cloudabi/mod.rs | 2 +- src/libstd/sys/cloudabi/mutex.rs | 32 ++++++++++++++++---------------- src/libstd/sys/cloudabi/time.rs | 4 ++-- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/src/libstd/sys/cloudabi/mod.rs b/src/libstd/sys/cloudabi/mod.rs index 091b31002fdeb..6e147612eb4b7 100644 --- a/src/libstd/sys/cloudabi/mod.rs +++ b/src/libstd/sys/cloudabi/mod.rs @@ -64,7 +64,7 @@ pub fn hashmap_random_keys() -> (u64, u64) { let mut v: mem::MaybeUninit<(u64, u64)> = mem::MaybeUninit::uninit(); libc::arc4random_buf( v.as_mut_ptr() as *mut libc::c_void, - mem::size_of_val(v.get_ref()) + mem::size_of_val(&v) ); v.assume_init() } diff --git a/src/libstd/sys/cloudabi/mutex.rs b/src/libstd/sys/cloudabi/mutex.rs index d1203a3536971..d3ff0077b20e5 100644 --- a/src/libstd/sys/cloudabi/mutex.rs +++ b/src/libstd/sys/cloudabi/mutex.rs @@ -54,7 +54,7 @@ pub struct ReentrantMutex { impl ReentrantMutex { pub unsafe fn uninitialized() -> ReentrantMutex { - ReentrantMutex { + ReentrantMutex { lock: UnsafeCell::new(MaybeUninit::uninit()), recursion: UnsafeCell::new(MaybeUninit::uninit()) } @@ -67,9 +67,9 @@ impl ReentrantMutex { pub unsafe fn try_lock(&self) -> bool { // Attempt to acquire the lock. - let lock = self.lock.get(); - let recursion = self.recursion.get(); - if let Err(old) = (*(*lock).as_mut_ptr()).compare_exchange( + let lock = (*self.lock.get()).as_mut_ptr(); + let recursion = (*self.recursion.get()).as_mut_ptr(); + if let Err(old) = (*lock).compare_exchange( abi::LOCK_UNLOCKED.0, __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0, Ordering::Acquire, @@ -78,14 +78,14 @@ impl ReentrantMutex { // If we fail to acquire the lock, it may be the case // that we've already acquired it and may need to recurse. if old & !abi::LOCK_KERNEL_MANAGED.0 == __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0 { - *(*recursion).as_mut_ptr() += 1; + *recursion += 1; true } else { false } } else { // Success. - assert_eq!(*(*recursion).as_mut_ptr(), 0, "Mutex has invalid recursion count"); + assert_eq!(*recursion, 0, "Mutex has invalid recursion count"); true } } @@ -113,17 +113,17 @@ impl ReentrantMutex { } pub unsafe fn unlock(&self) { - let lock = self.lock.get(); - let recursion = self.recursion.get(); + let lock = (*self.lock.get()).as_mut_ptr(); + let recursion = (*self.recursion.get()).as_mut_ptr(); assert_eq!( - (*(*lock).as_mut_ptr()).load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0, + (*lock).load(Ordering::Relaxed) & !abi::LOCK_KERNEL_MANAGED.0, __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0, "This mutex is locked by a different thread" ); - if *(*recursion).as_mut_ptr() > 0 { - *(*recursion).as_mut_ptr() -= 1; - } else if !(*(*lock).as_mut_ptr()) + if *recursion > 0 { + *recursion -= 1; + } else if !(*lock) .compare_exchange( __pthread_thread_id.0 | abi::LOCK_WRLOCKED.0, abi::LOCK_UNLOCKED.0, @@ -140,13 +140,13 @@ impl ReentrantMutex { } pub unsafe fn destroy(&self) { - let lock = self.lock.get(); - let recursion = self.recursion.get(); + let lock = (*self.lock.get()).as_mut_ptr(); + let recursion = (*self.recursion.get()).as_mut_ptr(); assert_eq!( - (*(*lock).as_mut_ptr()).load(Ordering::Relaxed), + (*lock).load(Ordering::Relaxed), abi::LOCK_UNLOCKED.0, "Attempted to destroy locked mutex" ); - assert_eq!(*(*recursion).as_mut_ptr(), 0, "Recursion counter invalid"); + assert_eq!(*recursion, 0, "Recursion counter invalid"); } } diff --git a/src/libstd/sys/cloudabi/time.rs b/src/libstd/sys/cloudabi/time.rs index fc5ffb8756083..d90f7dec496cf 100644 --- a/src/libstd/sys/cloudabi/time.rs +++ b/src/libstd/sys/cloudabi/time.rs @@ -21,7 +21,7 @@ impl Instant { let mut t: mem::MaybeUninit = mem::MaybeUninit::uninit(); let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, t.get_mut()); assert_eq!(ret, abi::errno::SUCCESS); - Instant { t } + Instant { t: t.assume_init() } } } @@ -62,7 +62,7 @@ impl SystemTime { let mut t: mem::MaybeUninit = mem::MaybeUninit::uninit(); let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, t.get_mut()); assert_eq!(ret, abi::errno::SUCCESS); - SystemTime { t } + SystemTime { t: t.assume_init() } } } From b70f21726238d73e671179ca6fe54ec228c75870 Mon Sep 17 00:00:00 2001 From: Nathan Date: Tue, 23 Jul 2019 13:51:28 -0400 Subject: [PATCH 4/4] Use raw pointers in std::sys::cloudabi when passing MaybeUninit values --- src/libstd/sys/cloudabi/abi/cloudabi.rs | 4 ++-- src/libstd/sys/cloudabi/condvar.rs | 4 ++-- src/libstd/sys/cloudabi/time.rs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libstd/sys/cloudabi/abi/cloudabi.rs b/src/libstd/sys/cloudabi/abi/cloudabi.rs index 2307e2167c5c1..9addba8b6118e 100644 --- a/src/libstd/sys/cloudabi/abi/cloudabi.rs +++ b/src/libstd/sys/cloudabi/abi/cloudabi.rs @@ -1884,7 +1884,7 @@ pub unsafe fn clock_res_get(clock_id_: clockid, resolution_: &mut timestamp) -> /// **time**: /// The time value of the clock. #[inline] -pub unsafe fn clock_time_get(clock_id_: clockid, precision_: timestamp, time_: &mut timestamp) -> errno { +pub unsafe fn clock_time_get(clock_id_: clockid, precision_: timestamp, time_: *mut timestamp) -> errno { cloudabi_sys_clock_time_get(clock_id_, precision_, time_) } @@ -2643,7 +2643,7 @@ pub unsafe fn mem_unmap(mapping_: &mut [u8]) -> errno { /// **nevents**: /// The number of events stored. #[inline] -pub unsafe fn poll(in_: *const subscription, out_: *mut event, nsubscriptions_: usize, nevents_: &mut usize) -> errno { +pub unsafe fn poll(in_: *const subscription, out_: *mut event, nsubscriptions_: usize, nevents_: *mut usize) -> errno { cloudabi_sys_poll(in_, out_, nsubscriptions_, nevents_) } diff --git a/src/libstd/sys/cloudabi/condvar.rs b/src/libstd/sys/cloudabi/condvar.rs index bce76a082e64b..ec1fca7805a17 100644 --- a/src/libstd/sys/cloudabi/condvar.rs +++ b/src/libstd/sys/cloudabi/condvar.rs @@ -85,7 +85,7 @@ impl Condvar { &subscription, event.as_mut_ptr(), 1, - nevents.get_mut() + nevents.as_mut_ptr() ); assert_eq!( ret, @@ -142,7 +142,7 @@ impl Condvar { subscriptions.as_ptr(), mem::MaybeUninit::first_ptr_mut(&mut events), 2, - nevents.get_mut() + nevents.as_mut_ptr() ); assert_eq!( ret, diff --git a/src/libstd/sys/cloudabi/time.rs b/src/libstd/sys/cloudabi/time.rs index d90f7dec496cf..5e502dcb2ba50 100644 --- a/src/libstd/sys/cloudabi/time.rs +++ b/src/libstd/sys/cloudabi/time.rs @@ -19,7 +19,7 @@ impl Instant { pub fn now() -> Instant { unsafe { let mut t: mem::MaybeUninit = mem::MaybeUninit::uninit(); - let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, t.get_mut()); + let ret = abi::clock_time_get(abi::clockid::MONOTONIC, 0, t.as_mut_ptr()); assert_eq!(ret, abi::errno::SUCCESS); Instant { t: t.assume_init() } } @@ -60,7 +60,7 @@ impl SystemTime { pub fn now() -> SystemTime { unsafe { let mut t: mem::MaybeUninit = mem::MaybeUninit::uninit(); - let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, t.get_mut()); + let ret = abi::clock_time_get(abi::clockid::REALTIME, 0, t.as_mut_ptr()); assert_eq!(ret, abi::errno::SUCCESS); SystemTime { t: t.assume_init() } }