Add signal support - exit on signal
This commit is contained in:
parent
b551b30300
commit
bf292bc0d1
31 changed files with 396 additions and 314 deletions
|
@ -1,6 +1,6 @@
|
|||
use alloc::arc::Arc;
|
||||
use alloc::boxed::Box;
|
||||
use collections::{BTreeMap, Vec};
|
||||
use collections::{BTreeMap, Vec, VecDeque};
|
||||
use spin::Mutex;
|
||||
|
||||
use arch;
|
||||
|
@ -48,6 +48,8 @@ pub struct Context {
|
|||
pub vfork: bool,
|
||||
/// Context is being waited on
|
||||
pub waitpid: Arc<WaitMap<ContextId, usize>>,
|
||||
/// Context should handle pending signals
|
||||
pub pending: VecDeque<u8>,
|
||||
/// Context should wake up at specified time
|
||||
pub wake: Option<(u64, u64)>,
|
||||
/// The architecture specific context
|
||||
|
@ -94,6 +96,7 @@ impl Context {
|
|||
cpu_id: None,
|
||||
vfork: false,
|
||||
waitpid: Arc::new(WaitMap::new()),
|
||||
pending: VecDeque::new(),
|
||||
wake: None,
|
||||
arch: arch::context::Context::new(),
|
||||
kfx: None,
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
use core::sync::atomic::Ordering;
|
||||
|
||||
use arch;
|
||||
use super::{contexts, Context, Status, CONTEXT_ID};
|
||||
use context::{contexts, Context, Status, CONTEXT_ID};
|
||||
use syscall;
|
||||
|
||||
/// Switch to the next context
|
||||
///
|
||||
|
@ -20,6 +21,7 @@ pub unsafe fn switch() -> bool {
|
|||
|
||||
let from_ptr;
|
||||
let mut to_ptr = 0 as *mut Context;
|
||||
let mut to_sig = None;
|
||||
{
|
||||
let contexts = contexts();
|
||||
{
|
||||
|
@ -34,6 +36,10 @@ pub unsafe fn switch() -> bool {
|
|||
// println!("{}: take {} {}", cpu_id, context.id, ::core::str::from_utf8_unchecked(&context.name.lock()));
|
||||
}
|
||||
|
||||
if context.status == Status::Blocked && ! context.pending.is_empty() {
|
||||
context.unblock();
|
||||
}
|
||||
|
||||
if context.status == Status::Blocked && context.wake.is_some() {
|
||||
let wake = context.wake.expect("context::switch: wake not set");
|
||||
|
||||
|
@ -57,6 +63,7 @@ pub unsafe fn switch() -> bool {
|
|||
let mut context = context_lock.write();
|
||||
if check_context(&mut context) {
|
||||
to_ptr = context.deref_mut() as *mut Context;
|
||||
to_sig = context.pending.pop_front();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +75,7 @@ pub unsafe fn switch() -> bool {
|
|||
let mut context = context_lock.write();
|
||||
if check_context(&mut context) {
|
||||
to_ptr = context.deref_mut() as *mut Context;
|
||||
to_sig = context.pending.pop_front();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -91,7 +99,17 @@ pub unsafe fn switch() -> bool {
|
|||
// Unset global lock before switch, as arch is only usable by the current CPU at this time
|
||||
arch::context::CONTEXT_SWITCH_LOCK.store(false, Ordering::SeqCst);
|
||||
|
||||
if let Some(sig) = to_sig {
|
||||
println!("Handle {}", sig);
|
||||
(&mut *to_ptr).arch.signal_stack(signal_handler, sig);
|
||||
}
|
||||
|
||||
(&mut *from_ptr).arch.switch_to(&mut (&mut *to_ptr).arch);
|
||||
|
||||
true
|
||||
}
|
||||
|
||||
extern fn signal_handler(signal: usize) {
|
||||
println!("Signal handler: {}", signal);
|
||||
syscall::exit(signal);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue