From 70bf79a9778d8912800d2c1ca7f7c314dfc0ec65 Mon Sep 17 00:00:00 2001 From: Jeremy Soller <jackpot51@gmail.com> Date: Sun, 11 Sep 2016 22:03:03 -0600 Subject: [PATCH] Implement exit, partly --- context/mod.rs | 14 ++++++++++---- elf.rs | 3 ++- syscall/process.rs | 16 +++++++++++++--- 3 files changed, 25 insertions(+), 8 deletions(-) diff --git a/context/mod.rs b/context/mod.rs index ad73f4d4..1e96a01c 100644 --- a/context/mod.rs +++ b/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<Box<[u8]>>, /// Executable image pub image: Vec<memory::Memory>, - /// User stack - pub stack: Option<memory::Memory>, /// User heap pub heap: Option<memory::Memory>, + /// User stack + pub stack: Option<memory::Memory>, /// The open files in the scheme pub files: Vec<Option<file::File>> } @@ -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/elf.rs b/elf.rs index d8200ad3..ad252ef9 100644 --- a/elf.rs +++ b/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/syscall/process.rs b/syscall/process.rs index 2307f1c6..78e0bc69 100644 --- a/syscall/process.rs +++ b/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<usize> { 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<usize> { -- GitLab