Downgrade context sigcontrol to read
This commit is contained in:
@@ -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,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
@@ -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
@@ -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()
|
||||
|
||||
@@ -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> {
|
||||
|
||||
@@ -80,13 +80,13 @@ impl WaitCondition {
|
||||
let mut preempt = PreemptGuardL2::new(¤t_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
@@ -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");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user