Remove is_pending flag, read word directly instead.
This commit is contained in:
@@ -212,10 +212,6 @@ pub struct SignalState {
|
||||
/// Offset within the control pages of respective word-aligned structs.
|
||||
pub threadctl_off: u16,
|
||||
pub procctl_off: u16,
|
||||
|
||||
/// Set whenever the kernel is about to have the context jump to its signal trampoline, but the
|
||||
/// context is currently running.
|
||||
pub is_pending: bool,
|
||||
}
|
||||
|
||||
impl Context {
|
||||
|
||||
+11
-31
@@ -15,30 +15,6 @@ use crate::{
|
||||
|
||||
use super::ContextId;
|
||||
|
||||
pub fn kmain_signal_handler() {
|
||||
/*if context::context_id() != ContextId::new(1) {
|
||||
log::warn!("kmain signal didn't target PID 1, ignoring");
|
||||
return;
|
||||
}
|
||||
|
||||
let deliverable = context::current().expect("context::kmain_signal_handler not inside of context");
|
||||
let kstop_bit = 1 << (SIGKILL - 1);
|
||||
let kreset_bit = 1 << (SIGTERM - 1);
|
||||
let bits = deliverable.read().sig.deliverable();
|
||||
|
||||
if bits & kstop_bit == kstop_bit {
|
||||
unsafe {
|
||||
kstop();
|
||||
}
|
||||
} else if bits & kreset_bit == kreset_bit {
|
||||
unsafe {
|
||||
kreset();
|
||||
}
|
||||
} else {
|
||||
log::warn!("Spurious kmain signal, bitmask {bits:#0x}.");
|
||||
}*/
|
||||
}
|
||||
|
||||
pub fn signal_handler() {
|
||||
let context_lock = context::current().expect("running signal handler outside of context");
|
||||
let mut context = context_lock.write();
|
||||
@@ -48,11 +24,11 @@ pub fn signal_handler() {
|
||||
crate::syscall::process::exit(SIGKILL << 8);
|
||||
}
|
||||
|
||||
let thumbs_down = ptrace::breakpoint_callback(
|
||||
/*let thumbs_down = ptrace::breakpoint_callback(
|
||||
PTRACE_STOP_SIGNAL,
|
||||
Some(ptrace_event!(PTRACE_STOP_SIGNAL)),
|
||||
)
|
||||
.and_then(|_| ptrace::next_breakpoint().map(|f| f.contains(PTRACE_FLAG_IGNORE)));
|
||||
.and_then(|_| ptrace::next_breakpoint().map(|f| f.contains(PTRACE_FLAG_IGNORE)));*/
|
||||
|
||||
// TODO: thumbs_down
|
||||
let Some((thread_ctl, proc_ctl, st)) = context.sigcontrol() else {
|
||||
@@ -60,6 +36,15 @@ pub fn signal_handler() {
|
||||
log::trace!("no sigcontrol, returning");
|
||||
return;
|
||||
};
|
||||
if thread_ctl.currently_pending_unblocked() == 0 {
|
||||
// The context is currently Runnable. When transitioning into Blocked, it will check for
|
||||
// signals (with the context lock held, which is required when sending signals). After
|
||||
// that, any detection of pending unblocked signals by the sender, will result in the
|
||||
// context being unblocked, and signals sent.
|
||||
|
||||
// TODO: prioritize signals over regular program execution
|
||||
return;
|
||||
}
|
||||
let control_flags = SigcontrolFlags::from_bits_retain(thread_ctl.control_flags.load(Ordering::Acquire));
|
||||
|
||||
if control_flags.contains(SigcontrolFlags::INHIBIT_DELIVERY) {
|
||||
@@ -69,11 +54,6 @@ pub fn signal_handler() {
|
||||
return;
|
||||
}
|
||||
|
||||
if !core::mem::take(&mut st.is_pending) {
|
||||
log::trace!("Not pending, returning");
|
||||
return;
|
||||
}
|
||||
|
||||
let sigh_instr_ptr = st.user_handler.get();
|
||||
|
||||
let Some(regs) = context.regs_mut() else {
|
||||
|
||||
+7
-16
@@ -11,7 +11,7 @@ use crate::{
|
||||
use super::{ContextId, Status};
|
||||
|
||||
enum UpdateResult {
|
||||
CanSwitch { signal: bool },
|
||||
CanSwitch,
|
||||
Skip,
|
||||
}
|
||||
|
||||
@@ -50,7 +50,7 @@ unsafe fn update_runnable(context: &mut Context, cpu_id: LogicalCpuId) -> Update
|
||||
|
||||
// Switch to context if it needs to run
|
||||
if context.status.is_runnable() {
|
||||
UpdateResult::CanSwitch { signal: context.sig.as_mut().map_or(false, |s| s.is_pending) }
|
||||
UpdateResult::CanSwitch
|
||||
} else {
|
||||
UpdateResult::Skip
|
||||
}
|
||||
@@ -69,12 +69,8 @@ pub fn tick() {
|
||||
|
||||
// Switch after 3 ticks (about 6.75 ms)
|
||||
if new_ticks >= 3 {
|
||||
match switch() {
|
||||
SwitchResult::Switched { signal: true } => {
|
||||
crate::context::signal::signal_handler();
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
switch();
|
||||
crate::context::signal::signal_handler();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -91,7 +87,7 @@ pub unsafe extern "C" fn switch_finish_hook() {
|
||||
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum SwitchResult {
|
||||
Switched { signal: bool },
|
||||
Switched,
|
||||
AllContextsIdle,
|
||||
}
|
||||
|
||||
@@ -156,10 +152,9 @@ pub fn switch() -> SwitchResult {
|
||||
let mut next_context_guard = next_context_lock.write_arc();
|
||||
|
||||
// Update state of next context and check if runnable
|
||||
if let UpdateResult::CanSwitch { signal } = unsafe { update_runnable(&mut *next_context_guard, cpu_id) } {
|
||||
if let UpdateResult::CanSwitch = unsafe { update_runnable(&mut *next_context_guard, cpu_id) } {
|
||||
// Store locks for previous and next context
|
||||
switch_context_opt = Some((prev_context_guard, next_context_guard));
|
||||
percpu.switch_internals.switch_signal.set(signal);
|
||||
break;
|
||||
} else {
|
||||
continue;
|
||||
@@ -226,10 +221,7 @@ pub fn switch() -> SwitchResult {
|
||||
// contexts will return directly to the function pointer passed to context::spawn, and not
|
||||
// reach this code until the next context switch back.
|
||||
|
||||
let new_percpu = PercpuBlock::current();
|
||||
// For the same reason, we obviously can't reuse the percpu block
|
||||
|
||||
SwitchResult::Switched { signal: new_percpu.switch_internals.switch_signal.get() }
|
||||
SwitchResult::Switched
|
||||
} else {
|
||||
// No target was found, unset global lock and return
|
||||
arch::CONTEXT_SWITCH_LOCK.store(false, Ordering::SeqCst);
|
||||
@@ -248,7 +240,6 @@ pub struct ContextSwitchPercpu {
|
||||
|
||||
// The ID of the idle process
|
||||
idle_id: Cell<ContextId>,
|
||||
switch_signal: Cell<bool>,
|
||||
}
|
||||
impl ContextSwitchPercpu {
|
||||
pub fn context_id(&self) -> ContextId {
|
||||
|
||||
+1
-4
@@ -245,10 +245,7 @@ fn run_userspace() -> ! {
|
||||
unsafe {
|
||||
interrupt::disable();
|
||||
match context::switch() {
|
||||
SwitchResult::Switched { signal } => {
|
||||
if signal {
|
||||
crate::context::signal::kmain_signal_handler();
|
||||
}
|
||||
SwitchResult::Switched => {
|
||||
interrupt::enable_and_nop();
|
||||
}
|
||||
SwitchResult::AllContextsIdle => {
|
||||
|
||||
@@ -1165,7 +1165,6 @@ impl<const FULL: bool> KernelScheme for ProcScheme<FULL> {
|
||||
.borrow_frame_enforce_rw_allocated(Page::containing_address(VirtualAddress::new(data.thread_control_addr)))?,
|
||||
proc_control: addrsp
|
||||
.borrow_frame_enforce_rw_allocated(Page::containing_address(VirtualAddress::new(data.proc_control_addr)))?,
|
||||
is_pending: false,
|
||||
})
|
||||
} else {
|
||||
None
|
||||
|
||||
@@ -171,7 +171,6 @@ pub fn kill(pid: ContextId, sig: usize) -> Result<usize> {
|
||||
ctl.word[0].fetch_and(!(sig_bit(SIGTTIN) | sig_bit(SIGTTOU) | sig_bit(SIGTSTP)), Ordering::Relaxed);
|
||||
ctl.word[0].fetch_or(sig_bit(SIGCONT), Ordering::Relaxed);
|
||||
if (ctl.word[0].load(Ordering::Relaxed) >> 32) & sig_bit(SIGCONT) != 0 {
|
||||
st.is_pending = true;
|
||||
}
|
||||
}
|
||||
} else if sig == SIGSTOP || (matches!(sig, SIGTTIN | SIGTTOU | SIGTSTP) && context.sigcontrol().map_or(false, |(_, proc, _)| proc.signal_will_stop(sig))) {
|
||||
@@ -185,7 +184,6 @@ pub fn kill(pid: ContextId, sig: usize) -> Result<usize> {
|
||||
} else if let Some((ctl, _, st)) = context.sigcontrol() {
|
||||
let _was_new = ctl.word[sig_group].fetch_or(sig_bit(sig), Ordering::Relaxed);
|
||||
if (ctl.word[sig_group].load(Ordering::Relaxed) >> 32) & sig_bit(sig) != 0 {
|
||||
st.is_pending = true;
|
||||
context.unblock();
|
||||
}
|
||||
} else {
|
||||
@@ -249,12 +247,9 @@ pub fn kill(pid: ContextId, sig: usize) -> Result<usize> {
|
||||
} else if sent == 0 {
|
||||
Err(Error::new(EPERM))
|
||||
} else {
|
||||
// Switch to ensure delivery to self
|
||||
if let SwitchResult::Switched { signal: true } = context::switch() {
|
||||
context::signal::signal_handler();
|
||||
}
|
||||
// Inform userspace it should check its own mask
|
||||
|
||||
Ok(0)
|
||||
Err(Error::new(EINTR))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
Submodule syscall updated: 9609c7bc26...87b8ac6581
Reference in New Issue
Block a user