Create threads with a argument. See bin/threads_arg.rs

This commit is contained in:
Yifan Wu 2021-10-08 13:50:36 -07:00
parent c951c1781e
commit 5b56961b8c
11 changed files with 59 additions and 19 deletions

View file

@ -45,7 +45,7 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize {
SYSCALL_FORK => sys_fork(), SYSCALL_FORK => sys_fork(),
SYSCALL_EXEC => sys_exec(args[0] as *const u8, args[1] as *const usize), SYSCALL_EXEC => sys_exec(args[0] as *const u8, args[1] as *const usize),
SYSCALL_WAITPID => sys_waitpid(args[0] as isize, args[1] as *mut i32), SYSCALL_WAITPID => sys_waitpid(args[0] as isize, args[1] as *mut i32),
SYSCALL_THREAD_CREATE => sys_thread_create(args[0]), SYSCALL_THREAD_CREATE => sys_thread_create(args[0], args[1]),
SYSCALL_GETTID => sys_gettid(), SYSCALL_GETTID => sys_gettid(),
SYSCALL_WAITTID => sys_waittid(args[0]) as isize, SYSCALL_WAITTID => sys_waittid(args[0]) as isize,
SYSCALL_MUTEX_CREATE => sys_mutex_create(args[0] == 1), SYSCALL_MUTEX_CREATE => sys_mutex_create(args[0] == 1),

View file

@ -1,7 +1,7 @@
use alloc::sync::Arc; use alloc::sync::Arc;
use crate::{mm::kernel_token, task::{TaskControlBlock, add_task, current_task}, trap::{TrapContext, trap_handler}}; use crate::{mm::kernel_token, task::{TaskControlBlock, add_task, current_task}, trap::{TrapContext, trap_handler}};
pub fn sys_thread_create(entry: usize) -> isize { pub fn sys_thread_create(entry: usize, arg: usize) -> isize {
let task = current_task().unwrap(); let task = current_task().unwrap();
let process = task.process.upgrade().unwrap(); let process = task.process.upgrade().unwrap();
// create a new thread // create a new thread
@ -30,6 +30,7 @@ pub fn sys_thread_create(entry: usize) -> isize {
new_task.kstack.get_top(), new_task.kstack.get_top(),
trap_handler as usize, trap_handler as usize,
); );
(*new_task_trap_cx).x[10] = arg;
new_task_tid as isize new_task_tid as isize
} }

View file

@ -28,7 +28,7 @@ pub fn main() -> i32 {
let start = get_time(); let start = get_time();
let mut v = Vec::new(); let mut v = Vec::new();
for _ in 0..THREAD_COUNT { for _ in 0..THREAD_COUNT {
v.push(thread_create(f as usize) as usize); v.push(thread_create(f as usize, 0) as usize);
} }
let mut time_cost = Vec::new(); let mut time_cost = Vec::new();
for tid in v.iter() { for tid in v.iter() {

View file

@ -11,8 +11,8 @@ use core::sync::atomic::{AtomicBool, Ordering};
static mut A: usize = 0; static mut A: usize = 0;
static OCCUPIED: AtomicBool = AtomicBool::new(false); static OCCUPIED: AtomicBool = AtomicBool::new(false);
const PER_THREAD: usize = 100000; const PER_THREAD: usize = 1000;
const THREAD_COUNT: usize = 8; const THREAD_COUNT: usize = 16;
unsafe fn f() -> ! { unsafe fn f() -> ! {
let mut t = 2usize; let mut t = 2usize;
@ -34,7 +34,7 @@ pub fn main() -> i32 {
let start = get_time(); let start = get_time();
let mut v = Vec::new(); let mut v = Vec::new();
for _ in 0..THREAD_COUNT { for _ in 0..THREAD_COUNT {
v.push(thread_create(f as usize) as usize); v.push(thread_create(f as usize, 0) as usize);
} }
let mut time_cost = Vec::new(); let mut time_cost = Vec::new();
for tid in v.iter() { for tid in v.iter() {

View file

@ -10,8 +10,8 @@ use alloc::vec::Vec;
static mut A: usize = 0; static mut A: usize = 0;
static mut OCCUPIED: bool = false; static mut OCCUPIED: bool = false;
const PER_THREAD: usize = 10000; const PER_THREAD: usize = 1000;
const THREAD_COUNT: usize = 8; const THREAD_COUNT: usize = 16;
unsafe fn f() -> ! { unsafe fn f() -> ! {
let mut t = 2usize; let mut t = 2usize;
@ -35,7 +35,7 @@ pub fn main() -> i32 {
let start = get_time(); let start = get_time();
let mut v = Vec::new(); let mut v = Vec::new();
for _ in 0..THREAD_COUNT { for _ in 0..THREAD_COUNT {
v.push(thread_create(f as usize) as usize); v.push(thread_create(f as usize, 0) as usize);
} }
let mut time_cost = Vec::new(); let mut time_cost = Vec::new();
for tid in v.iter() { for tid in v.iter() {

View file

@ -10,8 +10,8 @@ use user_lib::{mutex_blocking_create, mutex_lock, mutex_unlock};
use alloc::vec::Vec; use alloc::vec::Vec;
static mut A: usize = 0; static mut A: usize = 0;
const PER_THREAD: usize = 10000; const PER_THREAD: usize = 1000;
const THREAD_COUNT: usize = 8; const THREAD_COUNT: usize = 16;
unsafe fn f() -> ! { unsafe fn f() -> ! {
let mut t = 2usize; let mut t = 2usize;
@ -32,7 +32,7 @@ pub fn main() -> i32 {
assert_eq!(mutex_blocking_create(), 0); assert_eq!(mutex_blocking_create(), 0);
let mut v = Vec::new(); let mut v = Vec::new();
for _ in 0..THREAD_COUNT { for _ in 0..THREAD_COUNT {
v.push(thread_create(f as usize) as usize); v.push(thread_create(f as usize, 0) as usize);
} }
let mut time_cost = Vec::new(); let mut time_cost = Vec::new();
for tid in v.iter() { for tid in v.iter() {

View file

@ -32,7 +32,7 @@ pub fn main() -> i32 {
assert_eq!(mutex_create(), 0); assert_eq!(mutex_create(), 0);
let mut v = Vec::new(); let mut v = Vec::new();
for _ in 0..THREAD_COUNT { for _ in 0..THREAD_COUNT {
v.push(thread_create(f as usize) as usize); v.push(thread_create(f as usize, 0) as usize);
} }
let mut time_cost = Vec::new(); let mut time_cost = Vec::new();
for tid in v.iter() { for tid in v.iter() {

View file

@ -26,9 +26,9 @@ pub fn thread_c() -> ! {
#[no_mangle] #[no_mangle]
pub fn main() -> i32 { pub fn main() -> i32 {
let mut v = Vec::new(); let mut v = Vec::new();
v.push(thread_create(thread_a as usize)); v.push(thread_create(thread_a as usize, 0));
v.push(thread_create(thread_b as usize)); v.push(thread_create(thread_b as usize, 0));
v.push(thread_create(thread_c as usize)); v.push(thread_create(thread_c as usize, 0));
for tid in v.iter() { for tid in v.iter() {
let exit_code = waittid(*tid as usize); let exit_code = waittid(*tid as usize);
println!("thread#{} exited with code {}", tid, exit_code); println!("thread#{} exited with code {}", tid, exit_code);

View file

@ -0,0 +1,39 @@
#![no_std]
#![no_main]
#[macro_use]
extern crate user_lib;
extern crate alloc;
use user_lib::{thread_create, waittid, exit};
use alloc::vec::Vec;
struct Argument {
pub ch: char,
pub rc: i32,
}
fn thread_print(arg: *const Argument) -> ! {
let arg = unsafe { &*arg };
for _ in 0..1000 { print!("{}", arg.ch); }
exit(arg.rc)
}
#[no_mangle]
pub fn main() -> i32 {
let mut v = Vec::new();
let args = [
Argument { ch: 'a', rc: 1, },
Argument { ch: 'b', rc: 2, },
Argument { ch: 'c', rc: 3, },
];
for i in 0..3 {
v.push(thread_create(thread_print as usize, &args[i] as *const _ as usize));
}
for tid in v.iter() {
let exit_code = waittid(*tid as usize);
println!("thread#{} exited with code {}", tid, exit_code);
}
println!("main thread exited.");
0
}

View file

@ -104,7 +104,7 @@ pub fn sleep(sleep_ms: usize) {
sys_sleep(sleep_ms); sys_sleep(sleep_ms);
} }
pub fn thread_create(entry: usize) -> isize { sys_thread_create(entry) } pub fn thread_create(entry: usize, arg: usize) -> isize { sys_thread_create(entry, arg) }
pub fn gettid() -> isize { sys_gettid() } pub fn gettid() -> isize { sys_gettid() }
pub fn waittid(tid: usize) -> isize { pub fn waittid(tid: usize) -> isize {
loop { loop {

View file

@ -90,8 +90,8 @@ pub fn sys_waitpid(pid: isize, exit_code: *mut i32) -> isize {
syscall(SYSCALL_WAITPID, [pid as usize, exit_code as usize, 0]) syscall(SYSCALL_WAITPID, [pid as usize, exit_code as usize, 0])
} }
pub fn sys_thread_create(entry: usize) -> isize { pub fn sys_thread_create(entry: usize, arg: usize) -> isize {
syscall(SYSCALL_THREAD_CREATE, [entry, 0, 0]) syscall(SYSCALL_THREAD_CREATE, [entry, arg, 0])
} }
pub fn sys_gettid() -> isize { pub fn sys_gettid() -> isize {