diff --git a/kernel/context/mod.rs b/kernel/context/mod.rs index ad73f4d..1e96a01 100644 --- a/kernel/context/mod.rs +++ b/kernel/context/mod.rs @@ -99,6 +99,7 @@ pub fn init() { let context_lock = contexts.new_context().expect("could not initialize first context"); let mut context = context_lock.write(); context.running = true; + context.blocked = false; CONTEXT_ID.store(context.id, Ordering::SeqCst); } @@ -141,7 +142,7 @@ pub unsafe fn switch() { for (_pid, context_lock) in contexts().map.iter() { let mut context = context_lock.write(); - if ! context.running && ! context.blocked { + if ! context.running && ! context.blocked && ! context.exited { to_ptr = context.deref_mut() as *mut Context; break; } @@ -151,6 +152,7 @@ pub unsafe fn switch() { // TODO: Sleep, wait for interrupt // Unset global lock if no context found arch::context::CONTEXT_SWITCH_LOCK.store(false, Ordering::SeqCst); + println!("No to_ptr"); return; } @@ -166,20 +168,23 @@ pub unsafe fn switch() { pub struct Context { /// The ID of this context pub id: usize, + //TODO: Status enum /// Running or not pub running: bool, /// Blocked or not pub blocked: bool, + /// Exited or not` + pub exited: bool, /// The architecture specific context pub arch: ArchContext, /// Kernel stack pub kstack: Option>, /// Executable image pub image: Vec, - /// User stack - pub stack: Option, /// User heap pub heap: Option, + /// User stack + pub stack: Option, /// The open files in the scheme pub files: Vec> } @@ -191,11 +196,12 @@ impl Context { id: id, running: false, blocked: true, + exited: false, arch: ArchContext::new(), kstack: None, image: Vec::new(), - stack: None, heap: None, + stack: None, files: Vec::new() } } diff --git a/kernel/elf.rs b/kernel/elf.rs index d8200ad..ad252ef 100644 --- a/kernel/elf.rs +++ b/kernel/elf.rs @@ -63,7 +63,8 @@ impl<'a> Elf<'a> { // Unmap previous image and stack context.image.clear(); - context.stack.take(); + drop(context.heap.take()); + drop(context.stack.take()); for segment in self.segments() { if segment.p_type == program_header::PT_LOAD { diff --git a/kernel/syscall/process.rs b/kernel/syscall/process.rs index 2307f1c..78e0bc6 100644 --- a/kernel/syscall/process.rs +++ b/kernel/syscall/process.rs @@ -3,7 +3,6 @@ use core::str; use arch; -use arch::interrupt::halt; use arch::paging::{VirtualAddress, entry}; use context; use elf; @@ -50,9 +49,20 @@ pub fn clone(flags: usize) -> Result { pub fn exit(status: usize) -> ! { println!("Exit {}", status); - loop { - unsafe { halt() }; + + { + let contexts = context::contexts(); + let context_lock = contexts.current().expect("tried to exit without context"); + let mut context = context_lock.write(); + context.image.clear(); + drop(context.heap.take()); + drop(context.stack.take()); + context.exited = true; } + + unsafe { context::switch(); } + + unreachable!(); } pub fn exec(path: &[u8], _args: &[[usize; 2]]) -> Result {