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