diff --git a/user/src/bin/race_adder.rs b/user/src/bin/race_adder.rs index dabead16..68bee9f9 100644 --- a/user/src/bin/race_adder.rs +++ b/user/src/bin/race_adder.rs @@ -9,21 +9,23 @@ use user_lib::{exit, thread_create, waittid, get_time}; use alloc::vec::Vec; static mut A: usize = 0; -const PER_THREAD: usize = 2000000; +const PER_THREAD: usize = 10000; const THREAD_COUNT: usize = 8; unsafe fn f() -> ! { - let start = get_time(); + let mut t = 2usize; for _ in 0..PER_THREAD { let a = &mut A as *mut usize; let cur = a.read_volatile(); + for _ in 0..500 { t = t * t % 10007; } a.write_volatile(cur + 1); } - exit((get_time() - start) as i32) + exit(t as i32) } #[no_mangle] 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); @@ -32,9 +34,7 @@ pub fn main() -> i32 { for tid in v.iter() { time_cost.push(waittid(*tid)); } - for (i, cost) in time_cost.iter().enumerate() { - println!("cost of thread#{} is {}ms", i, cost); - } + println!("time cost is {}ms", get_time() - start); assert_eq!(unsafe { A }, PER_THREAD * THREAD_COUNT); 0 } diff --git a/user/src/bin/race_adder_atomic.rs b/user/src/bin/race_adder_atomic.rs new file mode 100644 index 00000000..bb2d20e1 --- /dev/null +++ b/user/src/bin/race_adder_atomic.rs @@ -0,0 +1,46 @@ +#![no_std] +#![no_main] + +#[macro_use] +extern crate user_lib; +extern crate alloc; + +use user_lib::{exit, thread_create, waittid, get_time, yield_}; +use alloc::vec::Vec; +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; + +unsafe fn f() -> ! { + let mut t = 2usize; + for _ in 0..PER_THREAD { + while OCCUPIED.compare_exchange(false, true, Ordering::Relaxed, Ordering::Relaxed).is_err() { + yield_(); + } + let a = &mut A as *mut usize; + let cur = a.read_volatile(); + for _ in 0..500 { t = t * t % 10007; } + a.write_volatile(cur + 1); + OCCUPIED.store(false, Ordering::Relaxed); + } + exit(t as i32) +} + +#[no_mangle] +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); + } + let mut time_cost = Vec::new(); + for tid in v.iter() { + time_cost.push(waittid(*tid)); + } + println!("time cost is {}ms", get_time() - start); + assert_eq!(unsafe { A }, PER_THREAD * THREAD_COUNT); + 0 +} diff --git a/user/src/bin/race_adder_loop.rs b/user/src/bin/race_adder_loop.rs new file mode 100644 index 00000000..64e431a4 --- /dev/null +++ b/user/src/bin/race_adder_loop.rs @@ -0,0 +1,47 @@ +#![no_std] +#![no_main] + +#[macro_use] +extern crate user_lib; +extern crate alloc; + +use user_lib::{exit, thread_create, waittid, get_time, yield_}; +use alloc::vec::Vec; + +static mut A: usize = 0; +static mut OCCUPIED: bool = false; +const PER_THREAD: usize = 10000; +const THREAD_COUNT: usize = 8; + +unsafe fn f() -> ! { + let mut t = 2usize; + for _ in 0..PER_THREAD { + while OCCUPIED { yield_(); } + OCCUPIED = true; + // enter critical section + let a = &mut A as *mut usize; + let cur = a.read_volatile(); + for _ in 0..500 { t = t * t % 10007; } + a.write_volatile(cur + 1); + // exit critical section + OCCUPIED = false; + } + + exit(t as i32) +} + +#[no_mangle] +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); + } + let mut time_cost = Vec::new(); + for tid in v.iter() { + time_cost.push(waittid(*tid)); + } + println!("time cost is {}ms", get_time() - start); + assert_eq!(unsafe { A }, PER_THREAD * THREAD_COUNT); + 0 +}