mirror of
https://github.com/rust-lang/rust
synced 2024-09-15 22:50:55 +00:00
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:
commit
cc5a1aad4e
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
#![deny(unsafe_op_in_unsafe_fn)]
|
||||
|
||||
pub mod alloc;
|
||||
pub mod args;
|
||||
pub mod cmath;
|
||||
|
|
|
@ -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;
|
||||
|
@ -11,7 +12,7 @@ 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]
|
||||
|
@ -19,25 +20,17 @@ 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]
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
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 {}
|
||||
|
@ -9,14 +10,14 @@ 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");
|
||||
}
|
||||
|
@ -24,9 +25,9 @@ pub unsafe fn read(&self) {
|
|||
|
||||
#[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
|
||||
|
@ -35,19 +36,15 @@ pub unsafe fn try_read(&self) -> bool {
|
|||
|
||||
#[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
|
||||
|
@ -56,12 +53,12 @@ pub unsafe fn try_write(&self) -> bool {
|
|||
|
||||
#[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]
|
||||
|
|
|
@ -53,6 +53,7 @@
|
|||
pub mod time;
|
||||
|
||||
#[path = "../unsupported/common.rs"]
|
||||
#[deny(unsafe_op_in_unsafe_fn)]
|
||||
#[allow(unused)]
|
||||
mod common;
|
||||
pub use common::*;
|
||||
|
|
|
@ -66,5 +66,6 @@
|
|||
}
|
||||
|
||||
#[path = "../unsupported/common.rs"]
|
||||
#[deny(unsafe_op_in_unsafe_fn)]
|
||||
mod common;
|
||||
pub use common::*;
|
||||
|
|
Loading…
Reference in a new issue