Revert "Add ordered lock for WaitQueue mutex"

This reverts commit 735c68ec30.
This commit is contained in:
Wildan M
2026-03-10 12:11:09 +07:00
parent d5ed9d8007
commit eeb03bdcb1
8 changed files with 40 additions and 90 deletions
+1 -1
View File
@@ -78,7 +78,7 @@ pub fn excp_handler(excp: syscall::Exception) {
let context = current.write(token.token());
let Some(_eh) = context.sig.as_ref().and_then(|s| s.excp_handler) else {
let Some(eh) = context.sig.as_ref().and_then(|s| s.excp_handler) else {
// TODO: Let procmgr print this?
info!(
"UNHANDLED EXCEPTION, CPU {}, PID {}, NAME {}, CONTEXT {current:p}",
+2 -2
View File
@@ -34,8 +34,8 @@ impl EventQueue {
}
}
pub fn is_currently_empty(&self, token: &mut CleanLockToken) -> bool {
self.queue.is_currently_empty(token)
pub fn is_currently_empty(&self) -> bool {
self.queue.is_currently_empty()
}
pub fn read(&self, buf: UserSliceWo, block: bool, token: &mut CleanLockToken) -> Result<usize> {
+1 -1
View File
@@ -122,7 +122,7 @@ impl KernelScheme for EventScheme {
// It is always possible to write events
ready |= EventFlags::EVENT_WRITE;
}
if flags.contains(EventFlags::EVENT_READ) && !queue.is_currently_empty(token) {
if flags.contains(EventFlags::EVENT_READ) && !queue.is_currently_empty() {
// It is possible to read if queue is not empty
ready |= EventFlags::EVENT_READ;
}
+2 -2
View File
@@ -312,8 +312,8 @@ impl KernelScheme for SchemeList {
token: &mut CleanLockToken,
) -> Result<EventFlags> {
match self.get_user_inner(id, token) {
Some(inner) => inner.fevent(flags, token),
_ => return Err(Error::new(EBADF)),
Some(inner) => inner.fevent(flags),
_ => Err(Error::new(EBADF)),
}
}
+1 -1
View File
@@ -5,7 +5,7 @@
use ::syscall::{
dirent::{DirEntry, DirentBuf, DirentKind},
EACCES, EINVAL, EIO, EISDIR, ENOTDIR, EPERM,
EACCES, EBADFD, EINVAL, EIO, EISDIR, ENOTDIR, EPERM,
};
use alloc::{sync::Arc, vec::Vec};
use core::{
+2 -2
View File
@@ -965,10 +965,10 @@ impl UserInner {
Ok(())
}
pub fn fevent(&self, flags: EventFlags, token: &mut CleanLockToken) -> Result<EventFlags> {
pub fn fevent(&self, flags: EventFlags) -> Result<EventFlags> {
// TODO: Should the root scheme also suppress events if `flags` does not contain
// `EVENT_READ`?
Ok(if self.todo.is_currently_empty(token) {
Ok(if self.todo.is_currently_empty() {
EventFlags::empty()
} else {
EventFlags::EVENT_READ.intersection(flags)
+23 -56
View File
@@ -7,12 +7,12 @@ use alloc::{
use crate::{
context::{self, ContextLock, PreemptGuard},
sync::{CleanLockToken, LockToken, Lower, Mutex, L1, L2, L3},
sync::{CleanLockToken, Mutex, L1},
};
#[derive(Debug)]
pub struct WaitCondition {
contexts: Mutex<L3, Vec<Weak<ContextLock>>>,
contexts: Mutex<L1, Vec<Weak<ContextLock>>>,
}
impl WaitCondition {
@@ -48,8 +48,7 @@ impl WaitCondition {
len
}
/// Wait until notified. Unlocks guard when blocking is ready. Returns false if resumed by a signal or the notify_signal function.
/// Wrapper to wait_setup -> drop(guard) -> context::switch -> wait_cleanup without currently holding lock for guard.
// Wait until notified. Unlocks guard when blocking is ready. Returns false if resumed by a signal or the notify_signal function
pub fn wait<T>(&self, guard: T, reason: &'static str, token: &mut CleanLockToken) -> bool {
let current_context_ref = context::current();
{
@@ -59,68 +58,36 @@ impl WaitCondition {
// to deadlock if we were woken up immediately.
let mut preempt = PreemptGuard::new(&current_context_ref, token);
let token = preempt.token();
if !self.wait_setup(&current_context_ref, reason, token.token()) {
return false;
{
let mut context = current_context_ref.write(token.token());
if let Some((control, pctl, _)) = context.sigcontrol()
&& control.currently_pending_unblocked(pctl) != 0
{
return false;
}
context.block(reason);
}
self.contexts
.lock(token.token())
.push(Arc::downgrade(&current_context_ref));
drop(guard);
}
context::switch(token);
self.wait_cleanup(&current_context_ref, token.token())
}
/// Enqueues the context and sets it to blocked.
/// Returns true if successfully blocked, false if a signal is pending.
pub fn wait_setup<'a, LP>(
&self,
current_context_ref: &Arc<ContextLock>,
reason: &'static str,
mut lock_token: LockToken<'a, LP>,
) -> bool
where
LP: Lower<L2>,
{
{
let mut context = current_context_ref.write(LockToken::downgraded(lock_token.token()));
if let Some((control, pctl, _)) = context.sigcontrol()
&& control.currently_pending_unblocked(pctl) != 0
{
return false;
}
context.block(reason);
}
self.contexts
.lock(LockToken::downgraded(lock_token))
.push(Arc::downgrade(current_context_ref));
true
}
/// Cleans up the wait list after waking up.
/// Returns true if we actually waited, false if we were removed by signal/notify_signal.
pub fn wait_cleanup<'a, LP>(
&self,
current_context_ref: &Arc<ContextLock>,
lock_token: LockToken<'a, LP>,
) -> bool
where
LP: Lower<L1>,
{
let mut waited = true;
let mut contexts = self.contexts.lock(LockToken::downgraded(lock_token));
// TODO: retain
let mut i = 0;
while i < contexts.len() {
if Weak::as_ptr(&contexts[i]) == Arc::as_ptr(current_context_ref) {
contexts.remove(i);
{
let mut contexts = self.contexts.lock(token.token());
if let Some(index) = contexts
.iter()
.position(|c| Weak::as_ptr(c) == Arc::as_ptr(&current_context_ref))
{
contexts.remove(index);
waited = false;
break;
} else {
i += 1;
}
}
+8 -25
View File
@@ -1,9 +1,9 @@
use alloc::collections::VecDeque;
use spin::Mutex;
use syscall::{EAGAIN, EINTR};
use crate::{
context::{self, PreemptGuard},
sync::{CleanLockToken, Mutex, WaitCondition, L1},
sync::{CleanLockToken, WaitCondition},
syscall::{
error::{Error, Result, EINVAL},
usercopy::UserSliceWo,
@@ -12,7 +12,7 @@ use crate::{
#[derive(Debug)]
pub struct WaitQueue<T> {
inner: Mutex<L1, VecDeque<T>>,
pub inner: Mutex<VecDeque<T>>,
pub condition: WaitCondition,
}
@@ -23,8 +23,8 @@ impl<T> WaitQueue<T> {
condition: WaitCondition::new(),
}
}
pub fn is_currently_empty(&self, token: &mut CleanLockToken) -> bool {
self.inner.lock(token.token()).is_empty()
pub fn is_currently_empty(&self) -> bool {
self.inner.lock().is_empty()
}
pub fn receive_into_user(
&self,
@@ -33,31 +33,14 @@ impl<T> WaitQueue<T> {
reason: &'static str,
token: &mut CleanLockToken,
) -> Result<usize> {
let current_context_ref = context::current();
loop {
let mut preempt = PreemptGuard::new(&current_context_ref, token);
let mut inner = self.inner.lock(preempt.token().token());
let mut inner = self.inner.lock();
if inner.is_empty() {
if block {
let (_, mut inner_token) = inner.token_split();
if !self
.condition
.wait_setup(&current_context_ref, reason, inner_token.token())
{
if !self.condition.wait(inner, reason, token) {
return Err(Error::new(EINTR));
}
drop(inner);
drop(preempt);
context::switch(token);
self.condition
.wait_cleanup(&current_context_ref, token.token());
continue;
} else if buf.is_empty() {
return Ok(0);
@@ -91,7 +74,7 @@ impl<T> WaitQueue<T> {
pub fn send(&self, value: T, token: &mut CleanLockToken) -> usize {
let len = {
let mut inner = self.inner.lock(token.token());
let mut inner = self.inner.lock();
inner.push_back(value);
inner.len()
};