Implement exit, partly

This commit is contained in:
Jeremy Soller 2016-09-11 22:03:03 -06:00
parent aa2915001e
commit 85fef883d6
3 changed files with 25 additions and 8 deletions

View file

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

View file

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

View file

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