mirror of
https://github.com/rcore-os/rCore-Tutorial-v3.git
synced 2024-11-22 01:16:26 +04:00
usertest: Simplify using vload and vstore macro
This commit is contained in:
parent
3f0cef23c6
commit
afbe3709f4
@ -8,7 +8,7 @@ extern crate user_lib;
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::ptr::{addr_of, addr_of_mut, read_volatile};
|
||||
use core::ptr::addr_of_mut;
|
||||
use core::sync::atomic::{compiler_fence, Ordering};
|
||||
use user_lib::{exit, get_time, thread_create, waittid};
|
||||
|
||||
@ -39,7 +39,7 @@ unsafe fn lock(id: usize) {
|
||||
// Otherwise the compiler will assume that they will never
|
||||
// be changed on this thread. Thus, they will be accessed
|
||||
// only once!
|
||||
while read_volatile(addr_of!(FLAG[j])) && read_volatile(addr_of!(TURN)) == j {}
|
||||
while vload!(FLAG[j]) && vload!(TURN) == j {}
|
||||
}
|
||||
|
||||
unsafe fn unlock(id: usize) {
|
||||
|
@ -6,7 +6,7 @@ extern crate user_lib;
|
||||
extern crate alloc;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::ptr::{addr_of, addr_of_mut, read_volatile};
|
||||
use core::ptr::addr_of_mut;
|
||||
use user_lib::{exit, get_time, thread_create, waittid};
|
||||
|
||||
static mut A: usize = 0;
|
||||
@ -25,7 +25,7 @@ unsafe fn critical_section(t: &mut usize) {
|
||||
}
|
||||
|
||||
unsafe fn lock() {
|
||||
while read_volatile(addr_of!(OCCUPIED)) {}
|
||||
while vload!(OCCUPIED) {}
|
||||
OCCUPIED = true;
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ extern crate core;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::{
|
||||
ptr::{addr_of, addr_of_mut, read_volatile, write_volatile},
|
||||
sync::atomic::{AtomicUsize, Ordering},
|
||||
};
|
||||
use user_lib::{exit, sleep, thread_create, waittid};
|
||||
@ -44,15 +43,15 @@ unsafe fn eisenberg_enter_critical(id: usize) {
|
||||
/* announce that we want to enter */
|
||||
loop {
|
||||
println!("Thread[{}] try enter", id);
|
||||
write_volatile(addr_of_mut!(FLAG[id]), FlagState::Want);
|
||||
vstore!(FLAG[id], FlagState::Want);
|
||||
loop {
|
||||
/* check if any with higher priority is `Want` or `In` */
|
||||
let mut prior_thread: Option<usize> = None;
|
||||
let turn = read_volatile(addr_of!(TURN));
|
||||
let turn = vload!(TURN);
|
||||
let ring_id = if id < turn { id + THREAD_NUM } else { id };
|
||||
// FLAG.iter() may lead to some errors, use for-loop instead
|
||||
for i in turn..ring_id {
|
||||
if read_volatile(addr_of!(FLAG[i % THREAD_NUM])) != FlagState::Out {
|
||||
if vload!(FLAG[i % THREAD_NUM]) != FlagState::Out {
|
||||
prior_thread = Some(i % THREAD_NUM);
|
||||
break;
|
||||
}
|
||||
@ -68,13 +67,13 @@ unsafe fn eisenberg_enter_critical(id: usize) {
|
||||
sleep(1);
|
||||
}
|
||||
/* now tentatively claim the resource */
|
||||
write_volatile(addr_of_mut!(FLAG[id]), FlagState::In);
|
||||
vstore!(FLAG[id], FlagState::In);
|
||||
/* enforce the order of `claim` and `conflict check`*/
|
||||
memory_fence!();
|
||||
/* check if anthor thread is also `In`, which imply a conflict*/
|
||||
let mut conflict = false;
|
||||
for i in 0..THREAD_NUM {
|
||||
if i != id && read_volatile(addr_of!(FLAG[i])) == FlagState::In {
|
||||
if i != id && vload!(FLAG[i]) == FlagState::In {
|
||||
conflict = true;
|
||||
}
|
||||
}
|
||||
@ -85,7 +84,7 @@ unsafe fn eisenberg_enter_critical(id: usize) {
|
||||
/* no need to sleep */
|
||||
}
|
||||
/* clain the trun */
|
||||
write_volatile(addr_of_mut!(TURN), id);
|
||||
vstore!(TURN, id);
|
||||
println!("Thread[{}] enter", id);
|
||||
}
|
||||
|
||||
@ -95,14 +94,14 @@ unsafe fn eisenberg_exit_critical(id: usize) {
|
||||
let ring_id = id + THREAD_NUM;
|
||||
for i in (id + 1)..ring_id {
|
||||
let idx = i % THREAD_NUM;
|
||||
if read_volatile(addr_of!(FLAG[idx])) == FlagState::Want {
|
||||
if vload!(FLAG[idx]) == FlagState::Want {
|
||||
next = idx;
|
||||
break;
|
||||
}
|
||||
}
|
||||
write_volatile(addr_of_mut!(TURN), next);
|
||||
vstore!(TURN, next);
|
||||
/* All done */
|
||||
write_volatile(addr_of_mut!(FLAG[id]), FlagState::Out);
|
||||
vstore!(FLAG[id], FlagState::Out);
|
||||
println!("Thread[{}] exit, give turn to {}", id, next);
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@ extern crate alloc;
|
||||
extern crate core;
|
||||
|
||||
use alloc::vec::Vec;
|
||||
use core::ptr::{addr_of, addr_of_mut, read_volatile, write_volatile};
|
||||
use core::sync::atomic::{AtomicUsize, Ordering};
|
||||
use user_lib::{exit, sleep, thread_create, waittid};
|
||||
const N: usize = 1000;
|
||||
@ -30,10 +29,10 @@ fn critical_test_exit() {
|
||||
|
||||
unsafe fn peterson_enter_critical(id: usize, peer_id: usize) {
|
||||
// println!("Thread[{}] try enter", id);
|
||||
write_volatile(addr_of_mut!(FLAG[id]), true);
|
||||
write_volatile(addr_of_mut!(TURN), peer_id);
|
||||
vstore!(FLAG[id], true);
|
||||
vstore!(TURN, peer_id);
|
||||
memory_fence!();
|
||||
while read_volatile(addr_of!(FLAG[peer_id])) && read_volatile(addr_of!(TURN)) == peer_id {
|
||||
while vload!(FLAG[peer_id]) && vload!(TURN) == peer_id {
|
||||
// println!("Thread[{}] enter fail", id);
|
||||
sleep(1);
|
||||
// println!("Thread[{}] retry enter", id);
|
||||
@ -42,7 +41,7 @@ unsafe fn peterson_enter_critical(id: usize, peer_id: usize) {
|
||||
}
|
||||
|
||||
unsafe fn peterson_exit_critical(id: usize) {
|
||||
write_volatile(addr_of_mut!(FLAG[id]), false);
|
||||
vstore!(FLAG[id], false);
|
||||
// println!("Thread[{}] exit", id);
|
||||
}
|
||||
|
||||
|
@ -70,15 +70,17 @@ fn main(_argc: usize, _argv: &[&str]) -> i32 {
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! vstore {
|
||||
($var_ref: expr, $value: expr) => {
|
||||
unsafe { core::intrinsics::volatile_store($var_ref as *const _ as _, $value) }
|
||||
($var: expr, $value: expr) => {
|
||||
// unsafe { core::intrinsics::volatile_store($var_ref as *const _ as _, $value) }
|
||||
unsafe { core::ptr::write_volatile(core::ptr::addr_of_mut!($var), $value); }
|
||||
};
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! vload {
|
||||
($var_ref: expr) => {
|
||||
unsafe { core::intrinsics::volatile_load($var_ref as *const _ as _) }
|
||||
($var: expr) => {
|
||||
// unsafe { core::intrinsics::volatile_load($var_ref as *const _ as _) }
|
||||
unsafe { core::ptr::read_volatile(core::ptr::addr_of!($var)) }
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user