1
Fork 0

#![deny(unsafe_op_in_unsafe_fn)] in sys/hermit

This commit is contained in:
maekawatoshiki 2020-07-31 18:50:11 +09:00
parent ac91673d89
commit 7cae9e8c88
10 changed files with 149 additions and 77 deletions

View file

@ -1,3 +1,5 @@
#![deny(unsafe_op_in_unsafe_fn)]
use crate::alloc::{GlobalAlloc, Layout, System}; use crate::alloc::{GlobalAlloc, Layout, System};
use crate::ptr; use crate::ptr;
use crate::sys::hermit::abi; use crate::sys::hermit::abi;
@ -6,26 +8,33 @@ use crate::sys::hermit::abi;
unsafe impl GlobalAlloc for System { unsafe impl GlobalAlloc for System {
#[inline] #[inline]
unsafe fn alloc(&self, layout: Layout) -> *mut u8 { unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
abi::malloc(layout.size(), layout.align()) // SAFETY: The safety contract for `malloc` must be upheld by the caller.
unsafe { abi::malloc(layout.size(), layout.align()) }
} }
unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 { unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut u8 {
let addr = abi::malloc(layout.size(), layout.align()); // SAFETY: The safety contract for `malloc` must be upheld by the caller.
// Also, `addr` must be valid for writes of `layout.size() * size_of::<u8>()` bytes.
unsafe {
let addr = abi::malloc(layout.size(), layout.align());
if !addr.is_null() { if !addr.is_null() {
ptr::write_bytes(addr, 0x00, layout.size()); ptr::write_bytes(addr, 0x00, layout.size());
}
addr
} }
addr
} }
#[inline] #[inline]
unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) { unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
abi::free(ptr, layout.size(), layout.align()) // SAFETY: The safety contract for `free` must be upheld by the caller.
unsafe { abi::free(ptr, layout.size(), layout.align()) }
} }
#[inline] #[inline]
unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 { unsafe fn realloc(&self, ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8 {
abi::realloc(ptr, layout.size(), layout.align(), new_size) // SAFETY: The safety contract for `realloc` must be upheld by the caller.
unsafe { abi::realloc(ptr, layout.size(), layout.align(), new_size) }
} }
} }

View file

@ -1,15 +1,17 @@
#![deny(unsafe_op_in_unsafe_fn)]
use crate::ffi::OsString; use crate::ffi::OsString;
use crate::marker::PhantomData; use crate::marker::PhantomData;
use crate::vec; use crate::vec;
/// One-time global initialization. /// One-time global initialization.
pub unsafe fn init(argc: isize, argv: *const *const u8) { pub unsafe fn init(argc: isize, argv: *const *const u8) {
imp::init(argc, argv) unsafe { imp::init(argc, argv) }
} }
/// One-time global cleanup. /// One-time global cleanup.
pub unsafe fn cleanup() { pub unsafe fn cleanup() {
imp::cleanup() unsafe { imp::cleanup() }
} }
/// Returns the command line arguments /// Returns the command line arguments
@ -65,14 +67,18 @@ mod imp {
pub unsafe fn init(argc: isize, argv: *const *const u8) { pub unsafe fn init(argc: isize, argv: *const *const u8) {
let _guard = LOCK.lock(); let _guard = LOCK.lock();
ARGC = argc; unsafe {
ARGV = argv; ARGC = argc;
ARGV = argv;
}
} }
pub unsafe fn cleanup() { pub unsafe fn cleanup() {
let _guard = LOCK.lock(); let _guard = LOCK.lock();
ARGC = 0; ARGC = 0;
ARGV = ptr::null(); unsafe {
ARGV = ptr::null();
}
} }
pub fn args() -> Args { pub fn args() -> Args {

View file

@ -1,3 +1,5 @@
#![deny(unsafe_op_in_unsafe_fn)]
use crate::ffi::c_void; use crate::ffi::c_void;
use crate::ptr; use crate::ptr;
use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst}; use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
@ -23,33 +25,43 @@ impl Condvar {
} }
pub unsafe fn init(&mut self) { pub unsafe fn init(&mut self) {
let _ = abi::sem_init(&mut self.sem1 as *mut *const c_void, 0); unsafe {
let _ = abi::sem_init(&mut self.sem2 as *mut *const c_void, 0); let _ = abi::sem_init(&mut self.sem1 as *mut *const c_void, 0);
let _ = abi::sem_init(&mut self.sem2 as *mut *const c_void, 0);
}
} }
pub unsafe fn notify_one(&self) { pub unsafe fn notify_one(&self) {
if self.counter.load(SeqCst) > 0 { if self.counter.load(SeqCst) > 0 {
self.counter.fetch_sub(1, SeqCst); self.counter.fetch_sub(1, SeqCst);
abi::sem_post(self.sem1); unsafe {
abi::sem_timedwait(self.sem2, 0); abi::sem_post(self.sem1);
abi::sem_timedwait(self.sem2, 0);
}
} }
} }
pub unsafe fn notify_all(&self) { pub unsafe fn notify_all(&self) {
let counter = self.counter.swap(0, SeqCst); let counter = self.counter.swap(0, SeqCst);
for _ in 0..counter { for _ in 0..counter {
abi::sem_post(self.sem1); unsafe {
abi::sem_post(self.sem1);
}
} }
for _ in 0..counter { for _ in 0..counter {
abi::sem_timedwait(self.sem2, 0); unsafe {
abi::sem_timedwait(self.sem2, 0);
}
} }
} }
pub unsafe fn wait(&self, mutex: &Mutex) { pub unsafe fn wait(&self, mutex: &Mutex) {
self.counter.fetch_add(1, SeqCst); self.counter.fetch_add(1, SeqCst);
mutex.unlock(); mutex.unlock();
abi::sem_timedwait(self.sem1, 0); unsafe {
abi::sem_post(self.sem2); abi::sem_timedwait(self.sem1, 0);
abi::sem_post(self.sem2);
}
mutex.lock(); mutex.lock();
} }
@ -58,7 +70,9 @@ impl Condvar {
} }
pub unsafe fn destroy(&self) { pub unsafe fn destroy(&self) {
let _ = abi::sem_destroy(self.sem1); unsafe {
let _ = abi::sem_destroy(self.sem2); let _ = abi::sem_destroy(self.sem1);
let _ = abi::sem_destroy(self.sem2);
}
} }
} }

View file

@ -1,3 +1,4 @@
#![deny(unsafe_op_in_unsafe_fn)]
#![unstable(reason = "not public", issue = "none", feature = "fd")] #![unstable(reason = "not public", issue = "none", feature = "fd")]
use crate::io::{self, ErrorKind, Read}; use crate::io::{self, ErrorKind, Read};

View file

@ -13,6 +13,8 @@
//! compiling for wasm. That way it's a compile time error for something that's //! compiling for wasm. That way it's a compile time error for something that's
//! guaranteed to be a runtime error! //! guaranteed to be a runtime error!
#![deny(unsafe_op_in_unsafe_fn)]
use crate::intrinsics; use crate::intrinsics;
use crate::os::raw::c_char; use crate::os::raw::c_char;
@ -62,8 +64,12 @@ pub enum Void {}
pub unsafe fn strlen(start: *const c_char) -> usize { pub unsafe fn strlen(start: *const c_char) -> usize {
let mut str = start; let mut str = start;
while *str != 0 { // SAFETY: The safety contract for `*str != 0` must be upheld by the caller.
str = str.offset(1); // `start` must not be null.
unsafe {
while *str != 0 {
str = str.offset(1);
}
} }
(str as usize) - (start as usize) (str as usize) - (start as usize)
@ -111,13 +117,15 @@ pub unsafe extern "C" fn runtime_entry(
fn main(argc: isize, argv: *const *const c_char) -> i32; fn main(argc: isize, argv: *const *const c_char) -> i32;
} }
// initialize environment unsafe {
os::init_environment(env as *const *const i8); // initialize environment
os::init_environment(env as *const *const i8);
let result = main(argc as isize, argv); let result = main(argc as isize, argv);
run_dtors(); run_dtors();
abi::exit(result); abi::exit(result);
}
} }
pub fn decode_error_kind(errno: i32) -> ErrorKind { pub fn decode_error_kind(errno: i32) -> ErrorKind {

View file

@ -1,3 +1,5 @@
#![deny(unsafe_op_in_unsafe_fn)]
use crate::ffi::c_void; use crate::ffi::c_void;
use crate::ptr; use crate::ptr;
use crate::sys::hermit::abi; use crate::sys::hermit::abi;
@ -16,28 +18,34 @@ impl Mutex {
#[inline] #[inline]
pub unsafe fn init(&mut self) { pub unsafe fn init(&mut self) {
let _ = abi::sem_init(&mut self.inner as *mut *const c_void, 1); unsafe {
let _ = abi::sem_init(&mut self.inner as *mut *const c_void, 1);
}
} }
#[inline] #[inline]
pub unsafe fn lock(&self) { pub unsafe fn lock(&self) {
let _ = abi::sem_timedwait(self.inner, 0); unsafe {
let _ = abi::sem_timedwait(self.inner, 0);
}
} }
#[inline] #[inline]
pub unsafe fn unlock(&self) { pub unsafe fn unlock(&self) {
let _ = abi::sem_post(self.inner); unsafe {
let _ = abi::sem_post(self.inner);
}
} }
#[inline] #[inline]
pub unsafe fn try_lock(&self) -> bool { pub unsafe fn try_lock(&self) -> bool {
let result = abi::sem_trywait(self.inner); let result = unsafe { abi::sem_trywait(self.inner) };
result == 0 result == 0
} }
#[inline] #[inline]
pub unsafe fn destroy(&self) { pub unsafe fn destroy(&self) {
let _ = abi::sem_destroy(self.inner); let _ = unsafe { abi::sem_destroy(self.inner) };
} }
} }
@ -52,12 +60,12 @@ impl ReentrantMutex {
#[inline] #[inline]
pub unsafe fn init(&self) { pub unsafe fn init(&self) {
let _ = abi::recmutex_init(&self.inner as *const *const c_void as *mut _); let _ = unsafe { abi::recmutex_init(&self.inner as *const *const c_void as *mut _) };
} }
#[inline] #[inline]
pub unsafe fn lock(&self) { pub unsafe fn lock(&self) {
let _ = abi::recmutex_lock(self.inner); let _ = unsafe { abi::recmutex_lock(self.inner) };
} }
#[inline] #[inline]
@ -67,11 +75,11 @@ impl ReentrantMutex {
#[inline] #[inline]
pub unsafe fn unlock(&self) { pub unsafe fn unlock(&self) {
let _ = abi::recmutex_unlock(self.inner); let _ = unsafe { abi::recmutex_unlock(self.inner) };
} }
#[inline] #[inline]
pub unsafe fn destroy(&self) { pub unsafe fn destroy(&self) {
let _ = abi::recmutex_destroy(self.inner); let _ = unsafe { abi::recmutex_destroy(self.inner) };
} }
} }

View file

@ -1,3 +1,5 @@
#![deny(unsafe_op_in_unsafe_fn)]
use crate::collections::HashMap; use crate::collections::HashMap;
use crate::error::Error as StdError; use crate::error::Error as StdError;
use crate::ffi::{CStr, OsStr, OsString}; use crate::ffi::{CStr, OsStr, OsString};

View file

@ -1,3 +1,5 @@
#![deny(unsafe_op_in_unsafe_fn)]
use crate::cell::UnsafeCell; use crate::cell::UnsafeCell;
use crate::sys::condvar::Condvar; use crate::sys::condvar::Condvar;
use crate::sys::mutex::Mutex; use crate::sys::mutex::Mutex;
@ -32,62 +34,76 @@ impl RWLock {
#[inline] #[inline]
pub unsafe fn read(&self) { pub unsafe fn read(&self) {
self.lock.lock(); unsafe {
while !(*self.state.get()).inc_readers() { self.lock.lock();
self.cond.wait(&self.lock); while !(*self.state.get()).inc_readers() {
self.cond.wait(&self.lock);
}
self.lock.unlock();
} }
self.lock.unlock();
} }
#[inline] #[inline]
pub unsafe fn try_read(&self) -> bool { pub unsafe fn try_read(&self) -> bool {
self.lock.lock(); unsafe {
let ok = (*self.state.get()).inc_readers(); self.lock.lock();
self.lock.unlock(); let ok = (*self.state.get()).inc_readers();
self.lock.unlock();
}
return ok; return ok;
} }
#[inline] #[inline]
pub unsafe fn write(&self) { pub unsafe fn write(&self) {
self.lock.lock(); unsafe {
while !(*self.state.get()).inc_writers() { self.lock.lock();
self.cond.wait(&self.lock); while !(*self.state.get()).inc_writers() {
self.cond.wait(&self.lock);
}
} }
self.lock.unlock(); self.lock.unlock();
} }
#[inline] #[inline]
pub unsafe fn try_write(&self) -> bool { pub unsafe fn try_write(&self) -> bool {
self.lock.lock(); unsafe {
let ok = (*self.state.get()).inc_writers(); self.lock.lock();
self.lock.unlock(); let ok = (*self.state.get()).inc_writers();
self.lock.unlock();
}
return ok; return ok;
} }
#[inline] #[inline]
pub unsafe fn read_unlock(&self) { pub unsafe fn read_unlock(&self) {
self.lock.lock(); unsafe {
let notify = (*self.state.get()).dec_readers(); self.lock.lock();
self.lock.unlock(); let notify = (*self.state.get()).dec_readers();
if notify { self.lock.unlock();
if notify {
// FIXME: should only wake up one of these some of the time
self.cond.notify_all();
}
}
}
#[inline]
pub unsafe fn write_unlock(&self) {
unsafe {
self.lock.lock();
(*self.state.get()).dec_writers();
self.lock.unlock();
// FIXME: should only wake up one of these some of the time // FIXME: should only wake up one of these some of the time
self.cond.notify_all(); self.cond.notify_all();
} }
} }
#[inline]
pub unsafe fn write_unlock(&self) {
self.lock.lock();
(*self.state.get()).dec_writers();
self.lock.unlock();
// FIXME: should only wake up one of these some of the time
self.cond.notify_all();
}
#[inline] #[inline]
pub unsafe fn destroy(&self) { pub unsafe fn destroy(&self) {
self.lock.destroy(); unsafe {
self.cond.destroy(); self.lock.destroy();
self.cond.destroy();
}
} }
} }

View file

@ -1,4 +1,5 @@
#![allow(dead_code)] #![allow(dead_code)]
#![deny(unsafe_op_in_unsafe_fn)]
use crate::ffi::CStr; use crate::ffi::CStr;
use crate::io; use crate::io;
@ -25,18 +26,22 @@ impl Thread {
core_id: isize, core_id: isize,
) -> io::Result<Thread> { ) -> io::Result<Thread> {
let p = Box::into_raw(box p); let p = Box::into_raw(box p);
let tid = abi::spawn2( let tid = unsafe {
thread_start, abi::spawn2(
p as usize, thread_start,
abi::Priority::into(abi::NORMAL_PRIO), p as usize,
stack, abi::Priority::into(abi::NORMAL_PRIO),
core_id, stack,
); core_id,
)
};
return if tid == 0 { return if tid == 0 {
// The thread failed to start and as a result p was not consumed. Therefore, it is // The thread failed to start and as a result p was not consumed. Therefore, it is
// safe to reconstruct the box so that it gets deallocated. // safe to reconstruct the box so that it gets deallocated.
drop(Box::from_raw(p)); unsafe {
drop(Box::from_raw(p));
}
Err(io::Error::new(io::ErrorKind::Other, "Unable to create thread!")) Err(io::Error::new(io::ErrorKind::Other, "Unable to create thread!"))
} else { } else {
Ok(Thread { tid: tid }) Ok(Thread { tid: tid })

View file

@ -1,5 +1,6 @@
#![cfg(target_thread_local)] #![cfg(target_thread_local)]
#![unstable(feature = "thread_local_internals", issue = "none")] #![unstable(feature = "thread_local_internals", issue = "none")]
#![deny(unsafe_op_in_unsafe_fn)]
// Simplify dtor registration by using a list of destructors. // Simplify dtor registration by using a list of destructors.
// The this solution works like the implementation of macOS and // The this solution works like the implementation of macOS and
@ -19,7 +20,8 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
DTORS.set(Box::into_raw(v)); DTORS.set(Box::into_raw(v));
} }
let list: &mut List = &mut *DTORS.get(); // SAFETY: `DTORS.get()` is not null.
let list: &mut List = unsafe { &mut *DTORS.get() };
list.push((t, dtor)); list.push((t, dtor));
} }
@ -27,7 +29,8 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
pub unsafe fn run_dtors() { pub unsafe fn run_dtors() {
let mut ptr = DTORS.replace(ptr::null_mut()); let mut ptr = DTORS.replace(ptr::null_mut());
while !ptr.is_null() { while !ptr.is_null() {
let list = Box::from_raw(ptr); // SAFETY: `ptr` is not null.
let list = unsafe { Box::from_raw(ptr) };
for (ptr, dtor) in list.into_iter() { for (ptr, dtor) in list.into_iter() {
dtor(ptr); dtor(ptr);
} }