Add signal support - exit on signal

This commit is contained in:
Jeremy Soller 2016-11-17 12:12:02 -07:00
parent b551b30300
commit bf292bc0d1
31 changed files with 396 additions and 314 deletions

View file

@ -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,

View file

@ -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);
}