Skip to content

Commit

Permalink
Rollup merge of rust-lang#77722 - fusion-engineering-forks:safe-unsup…
Browse files Browse the repository at this point in the history
…ported-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
  • Loading branch information
JohnTitor committed Oct 13, 2020
2 parents 1d8af29 + b26aa5d commit 9260b04
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 37 deletions.
13 changes: 8 additions & 5 deletions library/std/src/sys/unsupported/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,13 @@ pub fn hashmap_random_keys() -> (u64, u64) {
pub enum Void {}

pub unsafe fn strlen(mut s: *const c_char) -> usize {
let mut n = 0;
while *s != 0 {
n += 1;
s = s.offset(1);
// SAFETY: The caller must guarantee `s` points to a valid 0-terminated string.
unsafe {
let mut n = 0;
while *s != 0 {
n += 1;
s = s.offset(1);
}
n
}
return n;
}
2 changes: 2 additions & 0 deletions library/std/src/sys/unsupported/mod.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
#![deny(unsafe_op_in_unsafe_fn)]

pub mod alloc;
pub mod args;
pub mod cmath;
Expand Down
21 changes: 7 additions & 14 deletions library/std/src/sys/unsupported/mutex.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use crate::cell::UnsafeCell;
use crate::cell::Cell;

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;
Expand All @@ -11,33 +12,25 @@ unsafe impl Sync for Mutex {} // no threads on this platform

impl Mutex {
pub const fn new() -> Mutex {
Mutex { locked: UnsafeCell::new(false) }
Mutex { locked: Cell::new(false) }
}

#[inline]
pub unsafe fn init(&mut self) {}

#[inline]
pub unsafe fn lock(&self) {
let locked = self.locked.get();
assert!(!*locked, "cannot recursively acquire mutex");
*locked = true;
assert_eq!(self.locked.replace(true), false, "cannot recursively acquire mutex");
}

#[inline]
pub unsafe fn unlock(&self) {
*self.locked.get() = false;
self.locked.set(false);
}

#[inline]
pub unsafe fn try_lock(&self) -> bool {
let locked = self.locked.get();
if *locked {
false
} else {
*locked = true;
true
}
self.locked.replace(true) == false
}

#[inline]
Expand Down
33 changes: 15 additions & 18 deletions library/std/src/sys/unsupported/rwlock.rs
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
use crate::cell::UnsafeCell;
use crate::cell::Cell;

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 Sync for RWLock {} // no threads on this platform

impl RWLock {
pub const fn new() -> RWLock {
RWLock { mode: UnsafeCell::new(0) }
RWLock { mode: Cell::new(0) }
}

#[inline]
pub unsafe fn read(&self) {
let mode = self.mode.get();
if *mode >= 0 {
*mode += 1;
let m = self.mode.get();
if m >= 0 {
self.mode.set(m + 1);
} else {
rtabort!("rwlock locked for writing");
}
}

#[inline]
pub unsafe fn try_read(&self) -> bool {
let mode = self.mode.get();
if *mode >= 0 {
*mode += 1;
let m = self.mode.get();
if m >= 0 {
self.mode.set(m + 1);
true
} else {
false
Expand All @@ -35,19 +36,15 @@ impl RWLock {

#[inline]
pub unsafe fn write(&self) {
let mode = self.mode.get();
if *mode == 0 {
*mode = -1;
} else {
if self.mode.replace(-1) != 0 {
rtabort!("rwlock locked for reading")
}
}

#[inline]
pub unsafe fn try_write(&self) -> bool {
let mode = self.mode.get();
if *mode == 0 {
*mode = -1;
if self.mode.get() == 0 {
self.mode.set(-1);
true
} else {
false
Expand All @@ -56,12 +53,12 @@ impl RWLock {

#[inline]
pub unsafe fn read_unlock(&self) {
*self.mode.get() -= 1;
self.mode.set(self.mode.get() - 1);
}

#[inline]
pub unsafe fn write_unlock(&self) {
*self.mode.get() += 1;
assert_eq!(self.mode.replace(0), -1);
}

#[inline]
Expand Down

0 comments on commit 9260b04

Please sign in to comment.