Solve borrow rules for memory.rs

This commit is contained in:
Wildan M
2026-03-31 14:08:23 +07:00
committed by Jeremy Soller
parent 55e6fe9add
commit 3161a44c25
4 changed files with 136 additions and 39 deletions
+79 -1
View File
@@ -498,6 +498,72 @@ impl<L: Level, T> RwLock<L, T> {
})
}
/// Arcquires the lock_token to replace older LockWriteGuard.
/// SAFETY: Caller must guarantee lock_token is coming from RwLockWriteGuard::into_token() from the same lock.
pub unsafe fn rewrite<'a>(
&'a self,
lock_token: LockToken<'a, L>,
) -> RwLockWriteGuard<'a, L, T> {
let inner = {
#[cfg(feature = "busy_panic")]
let mut i = DEADLOCK_SPIN_CAP;
let my_percpu = PercpuBlock::current();
loop {
match self.inner.try_write() {
Some(inner) => break inner,
None => {
my_percpu.maybe_handle_tlb_shootdown();
core::hint::spin_loop();
#[cfg(feature = "busy_panic")]
{
i -= 1;
if i == 0 {
panic!("Deadlock at write may have triggered")
}
}
}
}
}
};
RwLockWriteGuard {
inner,
lock_token: lock_token,
}
}
/// Arcquires the lock_token to replace older LockUpgradableGuard.
/// SAFETY: Caller must guarantee lock_token is coming from RwLockUpgradableGuard::into_token() from the same lock.
pub unsafe fn reupgradeable_read<'a>(
&'a self,
lock_token: LockToken<'a, L>,
) -> RwLockUpgradableGuard<'a, L, T> {
let inner = {
#[cfg(feature = "busy_panic")]
let mut i = DEADLOCK_SPIN_CAP;
let my_percpu = PercpuBlock::current();
loop {
match self.inner.try_upgradeable_read() {
Some(inner) => break inner,
None => {
my_percpu.maybe_handle_tlb_shootdown();
core::hint::spin_loop();
#[cfg(feature = "busy_panic")]
{
i -= 1;
if i == 0 {
panic!("Deadlock at reupgradeable_read may have triggered")
}
}
}
}
}
};
RwLockUpgradableGuard {
inner,
lock_token: lock_token,
}
}
// Unsafe due to not using token, currently required by context::switch
pub unsafe fn write_arc(self: &Arc<Self>) -> ArcRwLockWriteGuard<L, T> {
core::mem::forget(self.inner.write());
@@ -513,12 +579,18 @@ pub struct RwLockWriteGuard<'a, L: Level, T> {
lock_token: LockToken<'a, L>,
}
impl<L: Level, T> RwLockWriteGuard<'_, L, T> {
impl<'a, L: Level, T> RwLockWriteGuard<'_, L, T> {
/// Split the guard into two parts, the first a mutable reference to the held content
/// the second a [`LockToken`] that can be used for further locking
pub fn token_split(&mut self) -> (&mut T, LockToken<'_, L>) {
(&mut self.inner, self.lock_token.token())
}
/// Drop this Guard and extract the token to be reused for another write lock with rewrite()
pub fn into_token(self) -> LockToken<'a, L> {
drop(self.inner);
self.lock_token
}
}
impl<L: Level, T> core::ops::Deref for RwLockWriteGuard<'_, L, T> {
@@ -577,6 +649,12 @@ impl<'a, L: Level, T> RwLockUpgradableGuard<'a, L, T> {
lock_token: self.lock_token,
}
}
/// Drop this Guard and extract the token to be reused for another write lock with reupgradeable_read()
pub fn into_token(self) -> LockToken<'a, L> {
drop(self.inner);
self.lock_token
}
}
impl<L: Level, T> core::ops::Deref for RwLockUpgradableGuard<'_, L, T> {