mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +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 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;
|
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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]
|
||||||
|
@ -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]
|
||||||
|
@ -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::*;
|
||||||
|
@ -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::*;
|
||||||
|
Loading…
Reference in New Issue
Block a user