Fix rust/sh and add rust/tls test

master
Jiajie Chen 6 years ago
parent 5ce1d2f788
commit 0029070acb

@ -22,9 +22,12 @@ pub fn main() -> i32 {
print!(">> ");
let cmd = get_line(&mut history);
// split cmd, make argc & argv
let cmd = cmd.replace(' ', "\0");
let mut ptrs: Vec<usize> = cmd.split('\0')
.filter(|s| !s.is_empty()).map(|s| s.as_ptr() as usize).collect();
let cmd = cmd.replace(' ', "\0") + "\0";
let mut ptrs: Vec<usize> = cmd
.split('\0')
.filter(|s| !s.is_empty())
.map(|s| s.as_ptr() as usize)
.collect();
if ptrs.is_empty() {
continue;
}
@ -33,7 +36,11 @@ pub fn main() -> i32 {
let pid = sys_fork();
assert!(pid >= 0);
if pid == 0 {
return sys_exec(ptrs[0] as *const u8, ptrs.as_ptr() as *const *const u8, ptr::null());
return sys_exec(
ptrs[0] as *const u8,
ptrs.as_ptr() as *const *const u8,
ptr::null(),
);
} else {
let mut code: i32 = 0;
sys_wait(pid as usize, &mut code);

@ -0,0 +1,52 @@
#![no_std]
#![no_main]
#![feature(asm)]
#[macro_use]
extern crate rcore_user;
use rcore_user::syscall::{sys_arch_prctl, sys_fork, sys_getpid, sys_sleep};
fn set_tls(tls: usize, pid: usize) {
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
unsafe {
asm!("mv tp, $0" : : "r"(tls));
}
#[cfg(target_arch = "x86_64")]
unsafe {
static mut DATA: [usize; 1024] = [0; 1024];
DATA[pid] = tls;
// set fs base
sys_arch_prctl(0x1002, &DATA[pid] as *const usize as usize);
}
}
fn get_tls() -> usize {
let mut tls: usize = 0;
#[cfg(any(target_arch = "riscv32", target_arch = "riscv64"))]
unsafe {
asm!("mv $0, tp" : "=r"(tls) :);
}
#[cfg(target_arch = "x86_64")]
unsafe {
asm!("mov %fs:0, $0" : "=r"(tls) :);
}
tls
}
// IMPORTANT: Must define main() like this
#[no_mangle]
pub fn main() {
println!("I am going to set TLS specific registers");
println!("And see if it changes between context switch");
sys_fork();
sys_fork();
let pid = sys_getpid();
for i in 0..10 {
let magic = 0xcafebabe;
set_tls(magic + i, pid as usize);
sys_sleep(1);
assert_eq!(get_tls(), magic + i);
println!("pid {} time {}: working", pid, i);
}
}

@ -93,8 +93,19 @@ pub fn sys_getpid() -> i32 {
sys_call(SyscallId::GetPid, 0, 0, 0, 0, 0, 0)
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct TimeSpec {
sec: u64,
nsec: u64,
}
pub fn sys_sleep(time: usize) -> i32 {
sys_call(SyscallId::Sleep, time, 0, 0, 0, 0, 0)
let ts = TimeSpec {
sec: time as u64,
nsec: 0
};
sys_call(SyscallId::Sleep, &ts as *const TimeSpec as usize, 0, 0, 0, 0, 0)
}
pub fn sys_get_time() -> i32 {
@ -105,6 +116,10 @@ pub fn sys_set_priority(priority: usize) -> i32 {
sys_call(SyscallId::SetPriority, priority, 0, 0, 0, 0, 0)
}
pub fn sys_arch_prctl(code: i32, addr: usize) -> i32 {
sys_call(SyscallId::ArchPrctl, code as usize, addr, 0, 0, 0, 0)
}
#[allow(dead_code)]
enum SyscallId {
Read = 0,
@ -130,4 +145,5 @@ enum SyscallId {
GetCwd = 79,
GetTime = 96,
SetPriority = 141,
ArchPrctl = 158,
}

Loading…
Cancel
Save