Smp (#23)
* Fire up multiple processors * Use IPIs to wake up secondary processors * Much better exception information * Modifications to show more information on fault * WIP: Use real libstd * Add TLS (not complete) * Add random function, export getpid, cleanup * Do not spin APs until new context * Update rust * Update rust * Use rd/wrfsbase * Implement TLS * Implement compiler builtins and update rust * Update rust * Back to Redox libstd * Update rust
This commit is contained in:
parent
25dc44b348
commit
149b0297a4
54 changed files with 1121 additions and 380 deletions
|
@ -62,6 +62,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
|
|||
let rgid;
|
||||
let euid;
|
||||
let egid;
|
||||
let mut cpu_id = None;
|
||||
let arch;
|
||||
let vfork;
|
||||
let mut kfx_option = None;
|
||||
|
@ -70,6 +71,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
|
|||
let mut image = vec![];
|
||||
let mut heap_option = None;
|
||||
let mut stack_option = None;
|
||||
let mut tls_option = None;
|
||||
let grants;
|
||||
let name;
|
||||
let cwd;
|
||||
|
@ -88,6 +90,10 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
|
|||
euid = context.euid;
|
||||
egid = context.egid;
|
||||
|
||||
if flags & CLONE_VM == CLONE_VM {
|
||||
cpu_id = context.cpu_id;
|
||||
}
|
||||
|
||||
arch = context.arch.clone();
|
||||
|
||||
if let Some(ref fx) = context.kfx {
|
||||
|
@ -181,6 +187,29 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
|
|||
stack_option = Some(new_stack);
|
||||
}
|
||||
|
||||
if let Some(ref tls) = context.tls {
|
||||
let mut new_tls = context::memory::Tls {
|
||||
master: tls.master,
|
||||
file_size: tls.file_size,
|
||||
mem: context::memory::Memory::new(
|
||||
VirtualAddress::new(arch::USER_TMP_TLS_OFFSET),
|
||||
tls.mem.size(),
|
||||
entry::PRESENT | entry::NO_EXECUTE | entry::WRITABLE,
|
||||
true,
|
||||
false
|
||||
)
|
||||
};
|
||||
|
||||
unsafe {
|
||||
arch::externs::memcpy(new_tls.mem.start_address().get() as *mut u8,
|
||||
tls.master.get() as *const u8,
|
||||
tls.file_size);
|
||||
}
|
||||
|
||||
new_tls.mem.remap(tls.mem.flags(), true);
|
||||
tls_option = Some(new_tls);
|
||||
}
|
||||
|
||||
if flags & CLONE_VM == CLONE_VM {
|
||||
grants = context.grants.clone();
|
||||
} else {
|
||||
|
@ -277,6 +306,8 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
|
|||
context.euid = euid;
|
||||
context.egid = egid;
|
||||
|
||||
context.cpu_id = cpu_id;
|
||||
|
||||
context.status = context::Status::Runnable;
|
||||
|
||||
context.vfork = vfork;
|
||||
|
@ -393,6 +424,12 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
|
|||
context.stack = Some(stack);
|
||||
}
|
||||
|
||||
// Setup user TLS
|
||||
if let Some(mut tls) = tls_option {
|
||||
tls.mem.move_to(VirtualAddress::new(arch::USER_TLS_OFFSET), &mut new_table, &mut temporary_page, true);
|
||||
context.tls = Some(tls);
|
||||
}
|
||||
|
||||
context.name = name;
|
||||
|
||||
context.cwd = cwd;
|
||||
|
@ -411,6 +448,7 @@ pub fn clone(flags: usize, stack_base: usize) -> Result<usize> {
|
|||
pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
||||
let entry;
|
||||
let mut sp = arch::USER_STACK_OFFSET + arch::USER_STACK_SIZE - 256;
|
||||
let fs = arch::USER_STACK_OFFSET;
|
||||
|
||||
{
|
||||
let mut args = Vec::new();
|
||||
|
@ -466,11 +504,12 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
|||
// Set name
|
||||
context.name = Arc::new(Mutex::new(canonical));
|
||||
|
||||
// Unmap previous image and stack
|
||||
// Unmap previous image, heap, grants, stack, and tls
|
||||
context.image.clear();
|
||||
drop(context.heap.take());
|
||||
drop(context.stack.take());
|
||||
context.grants = Arc::new(Mutex::new(Vec::new()));
|
||||
drop(context.stack.take());
|
||||
drop(context.tls.take());
|
||||
|
||||
if stat.st_mode & syscall::flag::MODE_SETUID == syscall::flag::MODE_SETUID {
|
||||
context.euid = stat.st_uid;
|
||||
|
@ -481,6 +520,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
|||
}
|
||||
|
||||
// Map and copy new segments
|
||||
let mut tls_option = None;
|
||||
for segment in elf.segments() {
|
||||
if segment.p_type == program_header::PT_LOAD {
|
||||
let mut memory = context::memory::Memory::new(
|
||||
|
@ -514,6 +554,12 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
|||
memory.remap(flags, true);
|
||||
|
||||
context.image.push(memory.to_shared());
|
||||
} else if segment.p_type == program_header::PT_TLS {
|
||||
tls_option = Some((
|
||||
VirtualAddress::new(segment.p_vaddr as usize),
|
||||
segment.p_filesz as usize,
|
||||
segment.p_memsz as usize
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -535,6 +581,35 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
|||
true
|
||||
));
|
||||
|
||||
// Map TLS
|
||||
if let Some((master, file_size, size)) = tls_option {
|
||||
let tls = context::memory::Tls {
|
||||
master: master,
|
||||
file_size: file_size,
|
||||
mem: context::memory::Memory::new(
|
||||
VirtualAddress::new(arch::USER_TLS_OFFSET),
|
||||
size,
|
||||
entry::NO_EXECUTE | entry::WRITABLE | entry::USER_ACCESSIBLE,
|
||||
true,
|
||||
true
|
||||
)
|
||||
};
|
||||
|
||||
unsafe {
|
||||
// Copy file data
|
||||
memcpy(tls.mem.start_address().get() as *mut u8,
|
||||
master.get() as *const u8,
|
||||
file_size);
|
||||
}
|
||||
|
||||
// Set TLS pointer
|
||||
//TODO: Do not use stack to store TLS pointer, use a TCB structure instead
|
||||
unsafe { *(arch::USER_STACK_OFFSET as *mut usize) = tls.mem.start_address().get() + size; }
|
||||
|
||||
context.tls = Some(tls);
|
||||
}
|
||||
|
||||
// Push arguments
|
||||
let mut arg_size = 0;
|
||||
for arg in args.iter().rev() {
|
||||
sp -= mem::size_of::<usize>();
|
||||
|
@ -597,7 +672,7 @@ pub fn exec(path: &[u8], arg_ptrs: &[[usize; 2]]) -> Result<usize> {
|
|||
}
|
||||
|
||||
// Go to usermode
|
||||
unsafe { usermode(entry, sp); }
|
||||
unsafe { usermode(entry, sp, fs); }
|
||||
}
|
||||
|
||||
pub fn exit(status: usize) -> ! {
|
||||
|
@ -897,6 +972,7 @@ pub fn virttophys(virtual_address: usize) -> Result<usize> {
|
|||
pub fn waitpid(pid: usize, status_ptr: usize, flags: usize) -> Result<usize> {
|
||||
loop {
|
||||
let mut exited = false;
|
||||
let mut running;
|
||||
let waitpid;
|
||||
{
|
||||
let contexts = context::contexts();
|
||||
|
@ -909,10 +985,23 @@ pub fn waitpid(pid: usize, status_ptr: usize, flags: usize) -> Result<usize> {
|
|||
}
|
||||
exited = true;
|
||||
}
|
||||
running = context.running;
|
||||
waitpid = context.waitpid.clone();
|
||||
}
|
||||
|
||||
if exited {
|
||||
// Spin until not running
|
||||
while running {
|
||||
{
|
||||
let contexts = context::contexts();
|
||||
let context_lock = contexts.get(pid).ok_or(Error::new(ESRCH))?;
|
||||
let context = context_lock.read();
|
||||
running = context.running;
|
||||
}
|
||||
|
||||
arch::interrupt::pause();
|
||||
}
|
||||
|
||||
let mut contexts = context::contexts_mut();
|
||||
return contexts.remove(pid).ok_or(Error::new(ESRCH)).and(Ok(pid));
|
||||
} else if flags & WNOHANG == WNOHANG {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue