diff --git a/os/src/syscall/mod.rs b/os/src/syscall/mod.rs index dbcf37cc..7c8ef58a 100644 --- a/os/src/syscall/mod.rs +++ b/os/src/syscall/mod.rs @@ -45,7 +45,7 @@ pub fn syscall(syscall_id: usize, args: [usize; 3]) -> isize { SYSCALL_FORK => sys_fork(), 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_THREAD_CREATE => sys_thread_create(args[0]), + SYSCALL_THREAD_CREATE => sys_thread_create(args[0], args[1]), SYSCALL_GETTID => sys_gettid(), SYSCALL_WAITTID => sys_waittid(args[0]) as isize, SYSCALL_MUTEX_CREATE => sys_mutex_create(args[0] == 1), diff --git a/os/src/syscall/thread.rs b/os/src/syscall/thread.rs index d9e42ba1..fa3b181a 100644 --- a/os/src/syscall/thread.rs +++ b/os/src/syscall/thread.rs @@ -1,7 +1,7 @@ use alloc::sync::Arc; 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 process = task.process.upgrade().unwrap(); // create a new thread @@ -30,6 +30,7 @@ pub fn sys_thread_create(entry: usize) -> isize { new_task.kstack.get_top(), trap_handler as usize, ); + (*new_task_trap_cx).x[10] = arg; new_task_tid as isize } diff --git a/user/src/bin/race_adder.rs b/user/src/bin/race_adder.rs index 0392b346..bae009ec 100644 --- a/user/src/bin/race_adder.rs +++ b/user/src/bin/race_adder.rs @@ -28,7 +28,7 @@ pub fn main() -> i32 { let start = get_time(); let mut v = Vec::new(); 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(); for tid in v.iter() { diff --git a/user/src/bin/race_adder_atomic.rs b/user/src/bin/race_adder_atomic.rs index bb2d20e1..dfbe490e 100644 --- a/user/src/bin/race_adder_atomic.rs +++ b/user/src/bin/race_adder_atomic.rs @@ -11,8 +11,8 @@ use core::sync::atomic::{AtomicBool, Ordering}; static mut A: usize = 0; static OCCUPIED: AtomicBool = AtomicBool::new(false); -const PER_THREAD: usize = 100000; -const THREAD_COUNT: usize = 8; +const PER_THREAD: usize = 1000; +const THREAD_COUNT: usize = 16; unsafe fn f() -> ! { let mut t = 2usize; @@ -34,7 +34,7 @@ pub fn main() -> i32 { let start = get_time(); let mut v = Vec::new(); 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(); for tid in v.iter() { diff --git a/user/src/bin/race_adder_loop.rs b/user/src/bin/race_adder_loop.rs index 64e431a4..035772e2 100644 --- a/user/src/bin/race_adder_loop.rs +++ b/user/src/bin/race_adder_loop.rs @@ -10,8 +10,8 @@ use alloc::vec::Vec; static mut A: usize = 0; static mut OCCUPIED: bool = false; -const PER_THREAD: usize = 10000; -const THREAD_COUNT: usize = 8; +const PER_THREAD: usize = 1000; +const THREAD_COUNT: usize = 16; unsafe fn f() -> ! { let mut t = 2usize; @@ -35,7 +35,7 @@ pub fn main() -> i32 { let start = get_time(); let mut v = Vec::new(); 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(); for tid in v.iter() { diff --git a/user/src/bin/race_adder_mutex_blocking.rs b/user/src/bin/race_adder_mutex_blocking.rs index 3df340f7..0424eba4 100644 --- a/user/src/bin/race_adder_mutex_blocking.rs +++ b/user/src/bin/race_adder_mutex_blocking.rs @@ -10,8 +10,8 @@ use user_lib::{mutex_blocking_create, mutex_lock, mutex_unlock}; use alloc::vec::Vec; static mut A: usize = 0; -const PER_THREAD: usize = 10000; -const THREAD_COUNT: usize = 8; +const PER_THREAD: usize = 1000; +const THREAD_COUNT: usize = 16; unsafe fn f() -> ! { let mut t = 2usize; @@ -32,7 +32,7 @@ pub fn main() -> i32 { assert_eq!(mutex_blocking_create(), 0); let mut v = Vec::new(); 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(); for tid in v.iter() { diff --git a/user/src/bin/race_adder_mutex_spin.rs b/user/src/bin/race_adder_mutex_spin.rs index 038e01aa..fb168666 100644 --- a/user/src/bin/race_adder_mutex_spin.rs +++ b/user/src/bin/race_adder_mutex_spin.rs @@ -32,7 +32,7 @@ pub fn main() -> i32 { assert_eq!(mutex_create(), 0); let mut v = Vec::new(); 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(); for tid in v.iter() { diff --git a/user/src/bin/threads.rs b/user/src/bin/threads.rs index 7641dde5..97ce43f0 100644 --- a/user/src/bin/threads.rs +++ b/user/src/bin/threads.rs @@ -26,9 +26,9 @@ pub fn thread_c() -> ! { #[no_mangle] pub fn main() -> i32 { let mut v = Vec::new(); - v.push(thread_create(thread_a as usize)); - v.push(thread_create(thread_b as usize)); - v.push(thread_create(thread_c as usize)); + v.push(thread_create(thread_a as usize, 0)); + v.push(thread_create(thread_b as usize, 0)); + v.push(thread_create(thread_c as usize, 0)); for tid in v.iter() { let exit_code = waittid(*tid as usize); println!("thread#{} exited with code {}", tid, exit_code); diff --git a/user/src/bin/threads_arg.rs b/user/src/bin/threads_arg.rs new file mode 100644 index 00000000..a29b23dd --- /dev/null +++ b/user/src/bin/threads_arg.rs @@ -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 +} diff --git a/user/src/lib.rs b/user/src/lib.rs index 356360e9..6f034d6e 100644 --- a/user/src/lib.rs +++ b/user/src/lib.rs @@ -104,7 +104,7 @@ pub fn sleep(sleep_ms: usize) { 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 waittid(tid: usize) -> isize { loop { diff --git a/user/src/syscall.rs b/user/src/syscall.rs index 793b36dd..0edcb9ce 100644 --- a/user/src/syscall.rs +++ b/user/src/syscall.rs @@ -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]) } -pub fn sys_thread_create(entry: usize) -> isize { - syscall(SYSCALL_THREAD_CREATE, [entry, 0, 0]) +pub fn sys_thread_create(entry: usize, arg: usize) -> isize { + syscall(SYSCALL_THREAD_CREATE, [entry, arg, 0]) } pub fn sys_gettid() -> isize {