diff --git a/src/sync/ordered.rs b/src/sync/ordered.rs index 8bbe4c4d31..1bcfa4926f 100644 --- a/src/sync/ordered.rs +++ b/src/sync/ordered.rs @@ -271,38 +271,6 @@ impl Mutex { }) } - /// Arcquires the lock_token to replace older MutexGuard. - /// SAFETY: Caller must guarantee lock_token is coming from MutexWriteGuard::into_token() from the same lock. - /// OR Caller must guarantee lock_token is coming from different lock, which can happen when two lock need to copy data each other. - pub unsafe fn relock<'a>(&'a self, lock_token: LockToken<'a, L>) -> MutexGuard<'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_lock() { - 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 mutex may have triggered") - } - } - } - } - } - }; - MutexGuard { - inner, - lock_token: lock_token, - } - } - /// Consumes this Mutex, returning the underlying data. pub fn into_inner(self) -> T { self.inner.into_inner() @@ -331,14 +299,6 @@ impl<'a, L: Level, T: ?Sized + 'a> MutexGuard<'a, L, T> { pub fn into_split(self) -> (spin::MutexGuard<'a, T>, LockToken<'a, L>) { (self.inner, self.lock_token) } - - /// Merge the guard from `into_split` - pub fn from_split(lock: spin::MutexGuard<'a, T>, token: LockToken<'a, L>) -> Self { - Self { - inner: lock, - lock_token: token, - } - } } impl<'a, L: Level, T: ?Sized + 'a> core::ops::Deref for MutexGuard<'a, L, T> { diff --git a/src/sync/wait_queue.rs b/src/sync/wait_queue.rs index 7e2c21e2df..b049ef7849 100644 --- a/src/sync/wait_queue.rs +++ b/src/sync/wait_queue.rs @@ -2,7 +2,7 @@ use alloc::collections::VecDeque; use syscall::{EAGAIN, EINTR}; use crate::{ - sync::{CleanLockToken, LockToken, Mutex, MutexGuard, WaitCondition, L1, L2, L3}, + sync::{CleanLockToken, LockToken, Mutex, WaitCondition, L1, L2}, syscall::{ error::{Error, Result, EINVAL}, usercopy::UserSliceWo, @@ -11,24 +11,20 @@ use crate::{ #[derive(Debug)] pub struct WaitQueue { - incoming: Mutex>, - outgoing: Mutex>, + inner: Mutex>, pub condition: WaitCondition, } impl WaitQueue { pub const fn new() -> WaitQueue { WaitQueue { - incoming: Mutex::new(VecDeque::new()), - outgoing: Mutex::new(VecDeque::new()), + inner: Mutex::new(VecDeque::new()), condition: WaitCondition::new(), } } - pub fn is_currently_empty(&self, token: &mut CleanLockToken) -> bool { - self.incoming.lock(token.token()).is_empty() && self.outgoing.lock(token.token()).is_empty() + self.inner.lock(token.token()).is_empty() } - pub fn receive_into_user( &self, buf: UserSliceWo, @@ -36,42 +32,17 @@ impl WaitQueue { reason: &'static str, token: &mut CleanLockToken, ) -> Result { - let mut out_guard = self.outgoing.lock(token.token()); loop { - let (mut outgoing, mut token) = out_guard.into_split(); - if !outgoing.is_empty() { - let (s1, s2) = outgoing.as_slices(); - let s1_bytes = unsafe { - core::slice::from_raw_parts(s1.as_ptr().cast::(), size_of_val(s1)) - }; - let s2_bytes = unsafe { - core::slice::from_raw_parts(s2.as_ptr().cast::(), size_of_val(s2)) - }; + let inner = self.inner.lock(token.token()); + let (mut inner, mut token) = inner.into_split(); - let mut bytes_copied = buf.copy_common_bytes_from_slice(s1_bytes)?; - - if let Some(buf_for_s2) = buf.advance(s1_bytes.len()) { - bytes_copied += buf_for_s2.copy_common_bytes_from_slice(s2_bytes)?; - } - - let _ = outgoing.drain(..bytes_copied / size_of::()); - return Ok(bytes_copied); - } - - let mut incoming = self.incoming.lock(token.token()); - - if incoming.is_empty() { + if inner.is_empty() { if block { - drop(incoming); // SAFETY: Uses wait_inner because this inner is L2. It's guaranteed there's no other // lock held at this point because clean token is provided from caller. - if !self - .condition - .wait_inner(outgoing, reason, &mut token.token()) - { + if !self.condition.wait_inner(inner, reason, &mut token) { return Err(Error::new(EINTR)); } - out_guard = unsafe { self.outgoing.relock(token) }; continue; } else if buf.is_empty() { return Ok(0); @@ -83,10 +54,21 @@ impl WaitQueue { } } - core::mem::swap(&mut *incoming, &mut outgoing); - drop(incoming); + let (s1, s2) = inner.as_slices(); + let s1_bytes = + unsafe { core::slice::from_raw_parts(s1.as_ptr().cast::(), size_of_val(s1)) }; + let s2_bytes = + unsafe { core::slice::from_raw_parts(s2.as_ptr().cast::(), size_of_val(s2)) }; - out_guard = MutexGuard::from_split(outgoing, token); + let mut bytes_copied = buf.copy_common_bytes_from_slice(s1_bytes)?; + + if let Some(buf_for_s2) = buf.advance(s1_bytes.len()) { + bytes_copied += buf_for_s2.copy_common_bytes_from_slice(s2_bytes)?; + } + + let _ = inner.drain(..bytes_copied / size_of::()); + + return Ok(bytes_copied); } } @@ -96,7 +78,7 @@ impl WaitQueue { pub fn send_locked(&self, value: T, mut token: LockToken<'_, L1>) -> usize { let len = { - let mut inner = self.incoming.lock(token.token()); + let mut inner = self.inner.lock(token.token()); inner.push_back(value); inner.len() };