Map stacks based on provided size.

This commit is contained in:
Jeremy Soller
2019-03-31 15:04:37 -06:00
parent 17372b4f69
commit 42d40da973
7 changed files with 138 additions and 32 deletions
Generated
+6 -6
View File
@@ -173,7 +173,7 @@ dependencies = [
name = "ralloc_shim"
version = "0.1.1"
dependencies = [
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)",
"sc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -220,7 +220,7 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.1.51"
version = "0.1.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -228,7 +228,7 @@ name = "redox_termios"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -243,7 +243,7 @@ dependencies = [
"posix-regex 0.1.0",
"ralloc 1.0.0",
"rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)",
"sc 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"spin 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
"va_list 0.1.0",
@@ -378,7 +378,7 @@ version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.47 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -480,7 +480,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum rand_core 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1961a422c4d189dfb50ffa9320bf1f2a9bd54ecb92792fb9477f99a1045f3372"
"checksum rand_core 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0905b6b7079ec73b314d4c748701f6931eb79fd97c668caa3f1899b22b32c6db"
"checksum rdrand 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
"checksum redox_syscall 0.1.51 (registry+https://github.com/rust-lang/crates.io-index)" = "423e376fffca3dfa06c9e9790a9ccd282fafb3cc6e6397d01dbf64f9bacc6b85"
"checksum redox_syscall 0.1.52 (registry+https://github.com/rust-lang/crates.io-index)" = "d32b3053e5ced86e4bc0411fec997389532bf56b000e66cb4884eeeb41413d69"
"checksum redox_termios 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7e891cfe48e9100a70a3b6eb652fef28920c117d366339687bd5576160db0f76"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
"checksum rustc_version 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084"
+1 -1
View File
@@ -37,7 +37,7 @@ optional = true
sc = "0.2.2"
[target.'cfg(target_os = "redox")'.dependencies]
redox_syscall = "0.1"
redox_syscall = "0.1.52"
spin = "0.4.10"
[features]
+1
View File
@@ -4,6 +4,7 @@
#![allow(unused_variables)]
#![feature(alloc)]
#![feature(allocator_api)]
#![feature(asm)]
#![feature(const_fn)]
#![feature(const_raw_ptr_deref)]
#![feature(const_str_as_bytes)]
+40 -11
View File
@@ -23,6 +23,7 @@ const AT_FDCWD: c_int = -100;
const AT_EMPTY_PATH: c_int = 0x1000;
const AT_REMOVEDIR: c_int = 0x200;
const SYS_CLONE: usize = 56;
const CLONE_VM: usize = 0x0100;
const CLONE_FS: usize = 0x0200;
const CLONE_FILES: usize = 0x0400;
@@ -326,17 +327,45 @@ impl Pal for Sys {
e(unsafe { syscall!(POLL, fds, nfds, timeout) }) as c_int
}
fn pte_clone() -> pid_t {
e(unsafe {
syscall!(
CLONE,
CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGHAND,
0,
0,
0,
0
)
}) as pid_t
#[cfg(target_arch = "x86_64")]
unsafe fn pte_clone(stack: *mut usize) -> pid_t {
let flags =
CLONE_VM |
CLONE_FS |
CLONE_FILES |
CLONE_SIGHAND;
let pid;
asm!("
# Call clone syscall
syscall
# Check if child or parent
test rax, rax
jnz .parent
# Call entry point
pop rdi
pop rax
call rax
# Exit
mov rax, 60
xor rdi, rdi
syscall
# Invalid instruction on failure to exit
ud2
# Return PID if parent
.parent:
"
: "={rax}"(pid)
: "{rax}"(SYS_CLONE), "{rdi}"(flags), "{rsi}"(stack), "{rdx}"(0), "{rcx}"(0), "{r8}"(0)
: "memory", "rbx", "rcx", "rdx", "rsi", "rdi", "r8",
"r9", "r10", "r11", "r12", "r13", "r14", "r15"
: "intel", "volatile"
);
e(pid) as pid_t
}
fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t {
+1 -1
View File
@@ -117,7 +117,7 @@ pub trait Pal {
fn poll(fds: *mut pollfd, nfds: nfds_t, timeout: c_int) -> c_int;
fn pte_clone() -> pid_t;
unsafe fn pte_clone(stack: *mut usize) -> pid_t;
fn read(fildes: c_int, buf: &mut [u8]) -> ssize_t;
+49 -4
View File
@@ -5,9 +5,10 @@ use alloc::collections::BTreeMap;
use core::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
use core::{intrinsics, ptr};
use header::sys_mman;
use header::time::timespec;
use mutex::{FUTEX_WAIT, FUTEX_WAKE};
use platform::types::{c_int, c_uint, c_void, pid_t};
use platform::types::{c_int, c_uint, c_void, pid_t, size_t};
use platform::{Pal, Sys};
pub struct Semaphore {
@@ -36,6 +37,9 @@ use self::pte_osResult::*;
static mut pid_mutexes: Option<BTreeMap<pte_osThreadHandle, pte_osMutexHandle>> = None;
static mut pid_mutexes_lock: i32 = 0;
static mut pid_stacks: Option<BTreeMap<pte_osThreadHandle, (*mut c_void, size_t)>> = None;
static mut pid_stacks_lock: i32 = 0;
#[thread_local]
static mut LOCALS: *mut BTreeMap<c_uint, *mut c_void> = ptr::null_mut();
@@ -57,17 +61,41 @@ pub unsafe extern "C" fn pte_osInit() -> pte_osResult {
#[no_mangle]
pub unsafe extern "C" fn pte_osThreadCreate(
entryPoint: pte_osThreadEntryPoint,
_stackSize: c_int,
stackSize: c_int,
_initialPriority: c_int,
argv: *mut c_void,
ppte_osThreadHandle: *mut pte_osThreadHandle,
) -> pte_osResult {
// XXX error handling
let stack_size = if stackSize == 0 {
1024 * 1024
} else {
stackSize as usize
};
let stack_base = sys_mman::mmap(
ptr::null_mut(),
stack_size,
sys_mman::PROT_READ | sys_mman::PROT_WRITE,
sys_mman::MAP_SHARED | sys_mman::MAP_ANONYMOUS,
-1,
0
);
if stack_base as isize == -1 {
return PTE_OS_GENERAL_FAILURE;
}
let stack_end = stack_base.add(stack_size);
let mut stack = stack_end as *mut usize;
{
stack = stack.offset(-1);
*stack = entryPoint as usize;
stack = stack.offset(-1);
*stack = argv as usize;
}
// Create a locked mutex, unlocked by pte_osThreadStart
let mutex = Box::into_raw(Box::new(2));
{
let id = Sys::pte_clone();
let id = Sys::pte_clone(stack);
if id < 0 {
return PTE_OS_GENERAL_FAILURE;
}
@@ -84,6 +112,14 @@ pub unsafe extern "C" fn pte_osThreadCreate(
}
pid_mutexes.as_mut().unwrap().insert(id, mutex);
pte_osMutexUnlock(&mut pid_mutexes_lock);
pte_osMutexLock(&mut pid_stacks_lock);
if pid_stacks.is_none() {
pid_stacks = Some(BTreeMap::new());
}
pid_stacks.as_mut().unwrap().insert(id, (stack_base, stack_size));
pte_osMutexUnlock(&mut pid_stacks_lock);
*ppte_osThreadHandle = id;
}
}
@@ -129,6 +165,15 @@ pub unsafe extern "C" fn pte_osThreadDelete(handle: pte_osThreadHandle) -> pte_o
}
}
pte_osMutexUnlock(&mut pid_mutexes_lock);
pte_osMutexLock(&mut pid_stacks_lock);
if let Some(ref mut stacks) = pid_stacks {
if let Some((stack_base, stack_size)) = stacks.remove(&handle) {
sys_mman::munmap(stack_base, stack_size);
}
}
pte_osMutexUnlock(&mut pid_stacks_lock);
PTE_OS_OK
}
+40 -9
View File
@@ -815,15 +815,46 @@ impl Pal for Sys {
total
}
fn pte_clone() -> pid_t {
e(unsafe {
syscall::clone(
syscall::CLONE_VM
| syscall::CLONE_FS
| syscall::CLONE_FILES
| syscall::CLONE_SIGHAND,
)
}) as pid_t
#[cfg(target_arch = "x86_64")]
unsafe fn pte_clone(stack: *mut usize) -> pid_t {
let flags =
syscall::CLONE_VM |
syscall::CLONE_FS |
syscall::CLONE_FILES |
syscall::CLONE_SIGHAND |
syscall::CLONE_STACK;
let pid;
asm!("
# Call clone syscall
syscall
# Check if child or parent
test rax, rax
jnz .parent
# Call entry point
pop rdi
pop rax
call rax
# Exit
mov rax, 1
xor rdi, rdi
syscall
# Invalid instruction on failure to exit
ud2
# Return PID if parent
.parent:
"
: "={rax}"(pid)
: "{rax}"(syscall::SYS_CLONE), "{rdi}"(flags), "{rsi}"(stack)
: "memory", "rbx", "rcx", "rdx", "rsi", "rdi", "r8",
"r9", "r10", "r11", "r12", "r13", "r14", "r15"
: "intel", "volatile"
);
e(syscall::Error::demux(pid)) as pid_t
}
fn read(fd: c_int, buf: &mut [u8]) -> ssize_t {