Implement exit, partly
This commit is contained in:
parent
aa2915001e
commit
85fef883d6
|
@ -99,6 +99,7 @@ pub fn init() {
|
||||||
let context_lock = contexts.new_context().expect("could not initialize first context");
|
let context_lock = contexts.new_context().expect("could not initialize first context");
|
||||||
let mut context = context_lock.write();
|
let mut context = context_lock.write();
|
||||||
context.running = true;
|
context.running = true;
|
||||||
|
context.blocked = false;
|
||||||
CONTEXT_ID.store(context.id, Ordering::SeqCst);
|
CONTEXT_ID.store(context.id, Ordering::SeqCst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +142,7 @@ pub unsafe fn switch() {
|
||||||
|
|
||||||
for (_pid, context_lock) in contexts().map.iter() {
|
for (_pid, context_lock) in contexts().map.iter() {
|
||||||
let mut context = context_lock.write();
|
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;
|
to_ptr = context.deref_mut() as *mut Context;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -151,6 +152,7 @@ pub unsafe fn switch() {
|
||||||
// TODO: Sleep, wait for interrupt
|
// TODO: Sleep, wait for interrupt
|
||||||
// Unset global lock if no context found
|
// Unset global lock if no context found
|
||||||
arch::context::CONTEXT_SWITCH_LOCK.store(false, Ordering::SeqCst);
|
arch::context::CONTEXT_SWITCH_LOCK.store(false, Ordering::SeqCst);
|
||||||
|
println!("No to_ptr");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,20 +168,23 @@ pub unsafe fn switch() {
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
/// The ID of this context
|
/// The ID of this context
|
||||||
pub id: usize,
|
pub id: usize,
|
||||||
|
//TODO: Status enum
|
||||||
/// Running or not
|
/// Running or not
|
||||||
pub running: bool,
|
pub running: bool,
|
||||||
/// Blocked or not
|
/// Blocked or not
|
||||||
pub blocked: bool,
|
pub blocked: bool,
|
||||||
|
/// Exited or not`
|
||||||
|
pub exited: bool,
|
||||||
/// The architecture specific context
|
/// The architecture specific context
|
||||||
pub arch: ArchContext,
|
pub arch: ArchContext,
|
||||||
/// Kernel stack
|
/// Kernel stack
|
||||||
pub kstack: Option<Box<[u8]>>,
|
pub kstack: Option<Box<[u8]>>,
|
||||||
/// Executable image
|
/// Executable image
|
||||||
pub image: Vec<memory::Memory>,
|
pub image: Vec<memory::Memory>,
|
||||||
/// User stack
|
|
||||||
pub stack: Option<memory::Memory>,
|
|
||||||
/// User heap
|
/// User heap
|
||||||
pub heap: Option<memory::Memory>,
|
pub heap: Option<memory::Memory>,
|
||||||
|
/// User stack
|
||||||
|
pub stack: Option<memory::Memory>,
|
||||||
/// The open files in the scheme
|
/// The open files in the scheme
|
||||||
pub files: Vec<Option<file::File>>
|
pub files: Vec<Option<file::File>>
|
||||||
}
|
}
|
||||||
|
@ -191,11 +196,12 @@ impl Context {
|
||||||
id: id,
|
id: id,
|
||||||
running: false,
|
running: false,
|
||||||
blocked: true,
|
blocked: true,
|
||||||
|
exited: false,
|
||||||
arch: ArchContext::new(),
|
arch: ArchContext::new(),
|
||||||
kstack: None,
|
kstack: None,
|
||||||
image: Vec::new(),
|
image: Vec::new(),
|
||||||
stack: None,
|
|
||||||
heap: None,
|
heap: None,
|
||||||
|
stack: None,
|
||||||
files: Vec::new()
|
files: Vec::new()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -63,7 +63,8 @@ impl<'a> Elf<'a> {
|
||||||
|
|
||||||
// Unmap previous image and stack
|
// Unmap previous image and stack
|
||||||
context.image.clear();
|
context.image.clear();
|
||||||
context.stack.take();
|
drop(context.heap.take());
|
||||||
|
drop(context.stack.take());
|
||||||
|
|
||||||
for segment in self.segments() {
|
for segment in self.segments() {
|
||||||
if segment.p_type == program_header::PT_LOAD {
|
if segment.p_type == program_header::PT_LOAD {
|
||||||
|
|
|
@ -3,7 +3,6 @@
|
||||||
use core::str;
|
use core::str;
|
||||||
|
|
||||||
use arch;
|
use arch;
|
||||||
use arch::interrupt::halt;
|
|
||||||
use arch::paging::{VirtualAddress, entry};
|
use arch::paging::{VirtualAddress, entry};
|
||||||
use context;
|
use context;
|
||||||
use elf;
|
use elf;
|
||||||
|
@ -50,9 +49,20 @@ pub fn clone(flags: usize) -> Result<usize> {
|
||||||
|
|
||||||
pub fn exit(status: usize) -> ! {
|
pub fn exit(status: usize) -> ! {
|
||||||
println!("Exit {}", status);
|
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> {
|
pub fn exec(path: &[u8], _args: &[[usize; 2]]) -> Result<usize> {
|
||||||
|
|
Loading…
Reference in a new issue