Rollup merge of #77722 - fusion-engineering-forks:safe-unsupported-locks, r=Mark-Simulacrum

Remove unsafety from sys/unsupported and add deny(unsafe_op_in_unsafe_fn).

Replacing `UnsafeCell`s by a `Cell`s simplifies things and makes the mutex and rwlock implementations safe. Other than that, only unsafety in strlen() contained unsafe code.

@rustbot modify labels: +F-unsafe-block-in-unsafe-fn +C-cleanup
This commit is contained in:
Yuki Okushi 2020-10-14 06:02:21 +09:00 committed by GitHub
commit cc5a1aad4e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 34 additions and 37 deletions

View File

@ -39,10 +39,13 @@ pub fn hashmap_random_keys() -> (u64, u64) {
pub enum Void {} pub enum Void {}
pub unsafe fn strlen(mut s: *const c_char) -> usize { pub unsafe fn strlen(mut s: *const c_char) -> usize {
let mut n = 0; // SAFETY: The caller must guarantee `s` points to a valid 0-terminated string.
while *s != 0 { unsafe {
n += 1; let mut n = 0;
s = s.offset(1); while *s != 0 {
n += 1;
s = s.offset(1);
}
n
} }
return n;
} }

View File

@ -1,3 +1,5 @@
#![deny(unsafe_op_in_unsafe_fn)]
pub mod alloc; pub mod alloc;
pub mod args; pub mod args;
pub mod cmath; pub mod cmath;

View File

@ -1,7 +1,8 @@
use crate::cell::UnsafeCell; use crate::cell::Cell;
pub struct Mutex { pub struct Mutex {
locked: UnsafeCell<bool>, // This platform has no threads, so we can use a Cell here.
locked: Cell<bool>,
} }
pub type MovableMutex = Mutex; pub type MovableMutex = Mutex;
@ -11,7 +12,7 @@ unsafe impl Sync for Mutex {} // no threads on this platform
impl Mutex { impl Mutex {
pub const fn new() -> Mutex { pub const fn new() -> Mutex {
Mutex { locked: UnsafeCell::new(false) } Mutex { locked: Cell::new(false) }
} }
#[inline] #[inline]
@ -19,25 +20,17 @@ impl Mutex {
#[inline] #[inline]
pub unsafe fn lock(&self) { pub unsafe fn lock(&self) {
let locked = self.locked.get(); assert_eq!(self.locked.replace(true), false, "cannot recursively acquire mutex");
assert!(!*locked, "cannot recursively acquire mutex");
*locked = true;
} }
#[inline] #[inline]
pub unsafe fn unlock(&self) { pub unsafe fn unlock(&self) {
*self.locked.get() = false; self.locked.set(false);
} }
#[inline] #[inline]
pub unsafe fn try_lock(&self) -> bool { pub unsafe fn try_lock(&self) -> bool {
let locked = self.locked.get(); self.locked.replace(true) == false
if *locked {
false
} else {
*locked = true;
true
}
} }
#[inline] #[inline]

View File

@ -1,7 +1,8 @@
use crate::cell::UnsafeCell; use crate::cell::Cell;
pub struct RWLock { pub struct RWLock {
mode: UnsafeCell<isize>, // This platform has no threads, so we can use a Cell here.
mode: Cell<isize>,
} }
unsafe impl Send for RWLock {} unsafe impl Send for RWLock {}
@ -9,14 +10,14 @@ unsafe impl Sync for RWLock {} // no threads on this platform
impl RWLock { impl RWLock {
pub const fn new() -> RWLock { pub const fn new() -> RWLock {
RWLock { mode: UnsafeCell::new(0) } RWLock { mode: Cell::new(0) }
} }
#[inline] #[inline]
pub unsafe fn read(&self) { pub unsafe fn read(&self) {
let mode = self.mode.get(); let m = self.mode.get();
if *mode >= 0 { if m >= 0 {
*mode += 1; self.mode.set(m + 1);
} else { } else {
rtabort!("rwlock locked for writing"); rtabort!("rwlock locked for writing");
} }
@ -24,9 +25,9 @@ impl RWLock {
#[inline] #[inline]
pub unsafe fn try_read(&self) -> bool { pub unsafe fn try_read(&self) -> bool {
let mode = self.mode.get(); let m = self.mode.get();
if *mode >= 0 { if m >= 0 {
*mode += 1; self.mode.set(m + 1);
true true
} else { } else {
false false
@ -35,19 +36,15 @@ impl RWLock {
#[inline] #[inline]
pub unsafe fn write(&self) { pub unsafe fn write(&self) {
let mode = self.mode.get(); if self.mode.replace(-1) != 0 {
if *mode == 0 {
*mode = -1;
} else {
rtabort!("rwlock locked for reading") rtabort!("rwlock locked for reading")
} }
} }
#[inline] #[inline]
pub unsafe fn try_write(&self) -> bool { pub unsafe fn try_write(&self) -> bool {
let mode = self.mode.get(); if self.mode.get() == 0 {
if *mode == 0 { self.mode.set(-1);
*mode = -1;
true true
} else { } else {
false false
@ -56,12 +53,12 @@ impl RWLock {
#[inline] #[inline]
pub unsafe fn read_unlock(&self) { pub unsafe fn read_unlock(&self) {
*self.mode.get() -= 1; self.mode.set(self.mode.get() - 1);
} }
#[inline] #[inline]
pub unsafe fn write_unlock(&self) { pub unsafe fn write_unlock(&self) {
*self.mode.get() += 1; assert_eq!(self.mode.replace(0), -1);
} }
#[inline] #[inline]

View File

@ -53,6 +53,7 @@ pub mod thread_local_key;
pub mod time; pub mod time;
#[path = "../unsupported/common.rs"] #[path = "../unsupported/common.rs"]
#[deny(unsafe_op_in_unsafe_fn)]
#[allow(unused)] #[allow(unused)]
mod common; mod common;
pub use common::*; pub use common::*;

View File

@ -66,5 +66,6 @@ cfg_if::cfg_if! {
} }
#[path = "../unsupported/common.rs"] #[path = "../unsupported/common.rs"]
#[deny(unsafe_op_in_unsafe_fn)]
mod common; mod common;
pub use common::*; pub use common::*;