Downgrade context sigcontrol to read

This commit is contained in:
Wildan M
2026-04-29 21:48:31 +07:00
parent ba28216ae8
commit 844f393ae8
7 changed files with 25 additions and 17 deletions
+5 -6
View File
@@ -453,12 +453,11 @@ impl Context {
let kstack = self.kstack.as_ref()?;
Some(unsafe { &mut *kstack.initial_top().sub(size_of::<InterruptStack>()).cast() })
}
pub fn sigcontrol(&mut self) -> Option<(&Sigcontrol, &SigProcControl, &mut SignalState)> {
Some(Self::sigcontrol_raw(self.sig.as_mut()?))
pub fn sigcontrol(&self) -> Option<(&Sigcontrol, &SigProcControl, &SignalState)> {
let (for_thread, for_proc) = Self::sigcontrol_raw(self.sig.as_ref()?);
Some((for_thread, for_proc, self.sig.as_ref()?))
}
pub fn sigcontrol_raw(
sig: &mut SignalState,
) -> (&Sigcontrol, &SigProcControl, &mut SignalState) {
pub fn sigcontrol_raw(sig: &SignalState) -> (&Sigcontrol, &SigProcControl) {
let check = |off| {
assert_eq!(usize::from(off) % align_of::<usize>(), 0);
assert!(usize::from(off).saturating_add(size_of::<Sigcontrol>()) < PAGE_SIZE);
@@ -475,7 +474,7 @@ impl Context {
.byte_add(usize::from(sig.procctl_off))
};
(for_thread, for_proc, sig)
(for_thread, for_proc)
}
pub fn caller_ctx(&self) -> CallerCtx {
CallerCtx {
+4 -3
View File
@@ -4,13 +4,12 @@ use crate::{context, sync::CleanLockToken, syscall::flag::SigcontrolFlags};
pub fn signal_handler(token: &mut CleanLockToken) {
let context_lock = context::current();
let mut context_guard = context_lock.write(token.token());
let context = &mut *context_guard;
let context = context_lock.upgradeable_read(token.token());
let being_sigkilled = context.being_sigkilled;
if being_sigkilled {
drop(context_guard);
drop(context);
drop(context_lock);
crate::syscall::process::exit_this_context(None, token);
}
@@ -48,6 +47,7 @@ pub fn signal_handler(token: &mut CleanLockToken) {
let sigh_instr_ptr = st.user_handler.get();
let mut context = context.upgrade();
let Some(regs) = context.regs_mut() else {
// TODO: is this even reachable?
trace!("No registers, returning");
@@ -59,6 +59,7 @@ pub fn signal_handler(token: &mut CleanLockToken) {
regs.set_instr_pointer(sigh_instr_ptr);
let mut context = context.downgrade();
let (thread_ctl, _, _) = context
.sigcontrol()
.expect("cannot have been unset while holding the lock");
+1 -1
View File
@@ -181,7 +181,7 @@ impl KernelScheme for AcpiScheme {
Ok(OpenResult::SchemeLocal(fd, int_flags))
}
fn fsize(&self, id: usize, token: &mut CleanLockToken) -> Result<u64> {
let mut handles = HANDLES.read(token.token());
let handles = HANDLES.read(token.token());
let handle = handles.get(id)?;
if handle.stat {
+3 -3
View File
@@ -633,7 +633,7 @@ impl KernelScheme for ProcScheme {
) -> Result<usize> {
// TODO: simplify
let handle = {
let mut handles = HANDLES.read(token.token());
let handles = HANDLES.read(token.token());
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
handle.clone()
};
@@ -667,7 +667,7 @@ impl KernelScheme for ProcScheme {
// Don't hold a global lock during the context switch later on
let handle = {
let mut handles = HANDLES.read(token.token());
let handles = HANDLES.read(token.token());
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
handle.clone()
};
@@ -696,7 +696,7 @@ impl KernelScheme for ProcScheme {
}
fn fsize(&self, id: usize, token: &mut CleanLockToken) -> Result<u64> {
let mut handles = HANDLES.read(token.token());
let handles = HANDLES.read(token.token());
let handle = handles.get(&id).ok_or(Error::new(EBADF))?;
handle.fsize()
+8
View File
@@ -620,6 +620,14 @@ impl<'a, L: Level, T> RwLockWriteGuard<'a, L, T> {
drop(self.inner);
self.lock_token
}
/// Upgrade to RO lock
pub fn downgrade(self) -> RwLockReadGuard<'a, L, T> {
RwLockReadGuard {
inner: self.inner.downgrade(),
lock_token: self.lock_token,
}
}
}
impl<L: Level, T> core::ops::Deref for RwLockWriteGuard<'_, L, T> {
+2 -2
View File
@@ -80,13 +80,13 @@ impl WaitCondition {
let mut preempt = PreemptGuardL2::new(&current_context_ref, &mut token);
let token = preempt.token();
{
let mut context = current_context_ref.write(token.token());
let context = current_context_ref.upgradeable_read(token.token());
if let Some((control, pctl, _)) = context.sigcontrol()
&& control.currently_pending_unblocked(pctl) != 0
{
return false;
}
context.block(reason);
context.upgrade().block(reason);
}
self.contexts
+2 -2
View File
@@ -41,14 +41,14 @@ pub fn nanosleep(
let current_context = context::current();
{
let mut context = current_context.write(token.token());
let context = current_context.upgradeable_read(token.token());
if let Some((tctl, pctl, _)) = context.sigcontrol()
&& tctl.currently_pending_unblocked(pctl) != 0
{
return Err(Error::new(EINTR));
}
let mut context = context.upgrade();
context.wake = Some(end);
context.block("nanosleep");
}