-
Notifications
You must be signed in to change notification settings - Fork 21
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Replaces RefCell with Cell on td_locks and td_pticks (#1268)
- Loading branch information
1 parent
49917f5
commit b25bd7d
Showing
4 changed files
with
70 additions
and
39 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,48 +1,73 @@ | ||
use super::Thread; | ||
use crate::context::{current_thread, BorrowedArc}; | ||
use core::cell::{RefCell, RefMut}; | ||
use core::cell::Cell; | ||
|
||
/// Encapsulates a field of [Thread] that can only be accessed by the CPU that currently executing | ||
/// the thread. | ||
pub struct PrivateCell<T>(RefCell<T>); | ||
/// | ||
/// # Context safety | ||
/// [`Default`] implementation of this type does not require a CPU context as long as implementation | ||
/// on `T` does not. | ||
#[derive(Default)] | ||
pub struct PrivateCell<T>(T); | ||
|
||
impl<T> PrivateCell<T> { | ||
/// # Context safety | ||
/// This function does not require a CPU context. | ||
pub fn new(v: T) -> Self { | ||
Self(RefCell::new(v)) | ||
fn validate(&self, owner: &Thread) { | ||
// This check will optimized out for most of the time due to the implementation of | ||
// current_thread() use "pure" + "nomem" on inline assembly. | ||
let current = current_thread(); | ||
|
||
if !core::ptr::eq(BorrowedArc::as_ptr(¤t), owner) { | ||
panic!("accessing a private cell from the other thread is not supported"); | ||
} | ||
} | ||
} | ||
|
||
/// See [borrow_mut] for a safe wrapper. | ||
impl<T> PrivateCell<Cell<T>> { | ||
/// See [set] for a safe wrapper. | ||
/// | ||
/// # Safety | ||
/// `owner` must be an owner of this field. | ||
/// | ||
/// # Panics | ||
/// If `owner` is not the current thread. | ||
pub unsafe fn borrow_mut(&self, owner: &Thread) -> RefMut<T> { | ||
pub unsafe fn set(&self, owner: &Thread, v: T) { | ||
self.validate(owner); | ||
self.0.borrow_mut() | ||
self.0.set(v); | ||
} | ||
} | ||
|
||
fn validate(&self, owner: &Thread) { | ||
// This check will optimized out for most of the time due to the implementation of | ||
// current_thread() use "pure" + "nomem" on inline assembly. | ||
let current = current_thread(); | ||
|
||
if !core::ptr::eq(BorrowedArc::as_ptr(¤t), owner) { | ||
panic!("accessing a private cell from the other thread is not supported"); | ||
} | ||
impl<T: Copy> PrivateCell<Cell<T>> { | ||
/// See [get] for a safe wrapper. | ||
/// | ||
/// # Safety | ||
/// `owner` must be an owner of this field. | ||
/// | ||
/// # Panics | ||
/// If `owner` is not the current thread. | ||
pub unsafe fn get(&self, owner: &Thread) -> T { | ||
self.validate(owner); | ||
self.0.get() | ||
} | ||
} | ||
|
||
unsafe impl<T> Sync for PrivateCell<T> {} | ||
unsafe impl<T: Send> Sync for PrivateCell<T> {} | ||
|
||
/// Safe wrapper of [PrivateCell::set()]. | ||
macro_rules! set { | ||
($t:ident, $f:ident, $v:expr) => { | ||
// SAFETY: $t is an owner of $f. | ||
unsafe { $t.$f.set($t, $v) } | ||
}; | ||
} | ||
|
||
/// Safe wrapper of [PrivateCell::borrow_mut()]. | ||
macro_rules! borrow_mut { | ||
/// Safe wrapper of [PrivateCell::get()]. | ||
macro_rules! get { | ||
($t:ident, $f:ident) => { | ||
unsafe { $t.$f.borrow_mut($t) } | ||
// SAFETY: $t is an owner of $f. | ||
unsafe { $t.$f.get($t) } | ||
}; | ||
} | ||
|
||
pub(super) use borrow_mut; | ||
pub(super) use get; | ||
pub(super) use set; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters