codecheck: Remove UB of ch8 usertests #140

This commit is contained in:
Yifan Wu 2024-01-21 15:32:33 +08:00
parent 8cd58cbe3a
commit 98255231b4
12 changed files with 47 additions and 39 deletions

View File

@ -6,6 +6,7 @@ extern crate user_lib;
extern crate alloc; extern crate alloc;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::ptr::addr_of_mut;
use user_lib::{exit, get_time, thread_create, waittid}; use user_lib::{exit, get_time, thread_create, waittid};
static mut A: usize = 0; static mut A: usize = 0;
@ -14,7 +15,7 @@ const THREAD_COUNT_DEFAULT: usize = 16;
static mut PER_THREAD: usize = 0; static mut PER_THREAD: usize = 0;
unsafe fn critical_section(t: &mut usize) { unsafe fn critical_section(t: &mut usize) {
let a = &mut A as *mut usize; let a = addr_of_mut!(A);
let cur = a.read_volatile(); let cur = a.read_volatile();
for _ in 0..500 { for _ in 0..500 {
*t = (*t) * (*t) % 10007; *t = (*t) * (*t) % 10007;

View File

@ -6,6 +6,7 @@ extern crate user_lib;
extern crate alloc; extern crate alloc;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::ptr::addr_of_mut;
use core::sync::atomic::{AtomicBool, Ordering}; use core::sync::atomic::{AtomicBool, Ordering};
use user_lib::{exit, get_time, thread_create, waittid, yield_}; use user_lib::{exit, get_time, thread_create, waittid, yield_};
@ -16,7 +17,7 @@ const THREAD_COUNT_DEFAULT: usize = 16;
static mut PER_THREAD: usize = 0; static mut PER_THREAD: usize = 0;
unsafe fn critical_section(t: &mut usize) { unsafe fn critical_section(t: &mut usize) {
let a = &mut A as *mut usize; let a = addr_of_mut!(A);
let cur = a.read_volatile(); let cur = a.read_volatile();
for _ in 0..500 { for _ in 0..500 {
*t = (*t) * (*t) % 10007; *t = (*t) * (*t) % 10007;

View File

@ -6,6 +6,7 @@ extern crate user_lib;
extern crate alloc; extern crate alloc;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::ptr::addr_of_mut;
use user_lib::{exit, get_time, thread_create, waittid}; use user_lib::{exit, get_time, thread_create, waittid};
use user_lib::{mutex_blocking_create, mutex_lock, mutex_unlock}; use user_lib::{mutex_blocking_create, mutex_lock, mutex_unlock};
@ -15,7 +16,7 @@ const THREAD_COUNT_DEFAULT: usize = 16;
static mut PER_THREAD: usize = 0; static mut PER_THREAD: usize = 0;
unsafe fn critical_section(t: &mut usize) { unsafe fn critical_section(t: &mut usize) {
let a = &mut A as *mut usize; let a = addr_of_mut!(A);
let cur = a.read_volatile(); let cur = a.read_volatile();
for _ in 0..500 { for _ in 0..500 {
*t = (*t) * (*t) % 10007; *t = (*t) * (*t) % 10007;

View File

@ -6,6 +6,7 @@ extern crate user_lib;
extern crate alloc; extern crate alloc;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::ptr::addr_of_mut;
use user_lib::{exit, get_time, thread_create, waittid}; use user_lib::{exit, get_time, thread_create, waittid};
use user_lib::{mutex_create, mutex_lock, mutex_unlock}; use user_lib::{mutex_create, mutex_lock, mutex_unlock};
@ -15,7 +16,7 @@ const THREAD_COUNT_DEFAULT: usize = 16;
static mut PER_THREAD: usize = 0; static mut PER_THREAD: usize = 0;
unsafe fn critical_section(t: &mut usize) { unsafe fn critical_section(t: &mut usize) {
let a = &mut A as *mut usize; let a = addr_of_mut!(A);
let cur = a.read_volatile(); let cur = a.read_volatile();
for _ in 0..500 { for _ in 0..500 {
*t = (*t) * (*t) % 10007; *t = (*t) * (*t) % 10007;

View File

@ -2,13 +2,13 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(core_intrinsics)]
#[macro_use] #[macro_use]
extern crate user_lib; extern crate user_lib;
extern crate alloc; extern crate alloc;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::ptr::{addr_of, addr_of_mut, read_volatile};
use core::sync::atomic::{compiler_fence, Ordering}; use core::sync::atomic::{compiler_fence, Ordering};
use user_lib::{exit, get_time, thread_create, waittid}; use user_lib::{exit, get_time, thread_create, waittid};
@ -20,7 +20,7 @@ const THREAD_COUNT_DEFAULT: usize = 2;
static mut PER_THREAD: usize = 0; static mut PER_THREAD: usize = 0;
unsafe fn critical_section(t: &mut usize) { unsafe fn critical_section(t: &mut usize) {
let a = &mut A as *mut usize; let a = addr_of_mut!(A);
let cur = a.read_volatile(); let cur = a.read_volatile();
for _ in 0..500 { for _ in 0..500 {
*t = (*t) * (*t) % 10007; *t = (*t) * (*t) % 10007;
@ -39,7 +39,7 @@ unsafe fn lock(id: usize) {
// Otherwise the compiler will assume that they will never // Otherwise the compiler will assume that they will never
// be changed on this thread. Thus, they will be accessed // be changed on this thread. Thus, they will be accessed
// only once! // only once!
while vload!(&FLAG[j]) && vload!(&TURN) == j {} while read_volatile(addr_of!(FLAG[j])) && read_volatile(addr_of!(TURN)) == j {}
} }
unsafe fn unlock(id: usize) { unsafe fn unlock(id: usize) {

View File

@ -2,14 +2,16 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(core_intrinsics)]
#[macro_use] #[macro_use]
extern crate user_lib; extern crate user_lib;
extern crate alloc; extern crate alloc;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::sync::atomic::{compiler_fence, Ordering}; use core::{
ptr::addr_of_mut,
sync::atomic::{compiler_fence, Ordering},
};
use user_lib::{exit, get_time, thread_create, waittid, yield_}; use user_lib::{exit, get_time, thread_create, waittid, yield_};
static mut A: usize = 0; static mut A: usize = 0;
@ -20,7 +22,7 @@ const THREAD_COUNT_DEFAULT: usize = 2;
static mut PER_THREAD: usize = 0; static mut PER_THREAD: usize = 0;
unsafe fn critical_section(t: &mut usize) { unsafe fn critical_section(t: &mut usize) {
let a = &mut A as *mut usize; let a = addr_of_mut!(A);
let cur = a.read_volatile(); let cur = a.read_volatile();
for _ in 0..500 { for _ in 0..500 {
*t = (*t) * (*t) % 10007; *t = (*t) * (*t) % 10007;

View File

@ -1,12 +1,12 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(core_intrinsics)]
#[macro_use] #[macro_use]
extern crate user_lib; extern crate user_lib;
extern crate alloc; extern crate alloc;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::ptr::{addr_of, addr_of_mut, read_volatile};
use user_lib::{exit, get_time, thread_create, waittid}; use user_lib::{exit, get_time, thread_create, waittid};
static mut A: usize = 0; static mut A: usize = 0;
@ -16,7 +16,7 @@ const THREAD_COUNT_DEFAULT: usize = 16;
static mut PER_THREAD: usize = 0; static mut PER_THREAD: usize = 0;
unsafe fn critical_section(t: &mut usize) { unsafe fn critical_section(t: &mut usize) {
let a = &mut A as *mut usize; let a = addr_of_mut!(A);
let cur = a.read_volatile(); let cur = a.read_volatile();
for _ in 0..500 { for _ in 0..500 {
*t = (*t) * (*t) % 10007; *t = (*t) * (*t) % 10007;
@ -25,7 +25,7 @@ unsafe fn critical_section(t: &mut usize) {
} }
unsafe fn lock() { unsafe fn lock() {
while vload!(&OCCUPIED) {} while read_volatile(addr_of!(OCCUPIED)) {}
OCCUPIED = true; OCCUPIED = true;
} }

View File

@ -1,12 +1,12 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(core_intrinsics)]
#[macro_use] #[macro_use]
extern crate user_lib; extern crate user_lib;
extern crate alloc; extern crate alloc;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::ptr::addr_of_mut;
use user_lib::{exit, get_time, thread_create, waittid, yield_}; use user_lib::{exit, get_time, thread_create, waittid, yield_};
static mut A: usize = 0; static mut A: usize = 0;
@ -16,7 +16,7 @@ const THREAD_COUNT_DEFAULT: usize = 16;
static mut PER_THREAD: usize = 0; static mut PER_THREAD: usize = 0;
unsafe fn critical_section(t: &mut usize) { unsafe fn critical_section(t: &mut usize) {
let a = &mut A as *mut usize; let a = addr_of_mut!(A);
let cur = a.read_volatile(); let cur = a.read_volatile();
for _ in 0..500 { for _ in 0..500 {
*t = (*t) * (*t) % 10007; *t = (*t) * (*t) % 10007;

View File

@ -1,6 +1,5 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(core_intrinsics)]
#[macro_use] #[macro_use]
extern crate user_lib; extern crate user_lib;
@ -8,7 +7,10 @@ extern crate alloc;
extern crate core; extern crate core;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::sync::atomic::{AtomicUsize, Ordering}; use core::{
ptr::{addr_of, addr_of_mut, read_volatile, write_volatile},
sync::atomic::{AtomicUsize, Ordering},
};
use user_lib::{exit, sleep, thread_create, waittid}; use user_lib::{exit, sleep, thread_create, waittid};
const N: usize = 2; const N: usize = 2;
@ -38,19 +40,19 @@ fn critical_test_exit() {
assert_eq!(GUARD.fetch_sub(1, Ordering::SeqCst), 1); assert_eq!(GUARD.fetch_sub(1, Ordering::SeqCst), 1);
} }
fn eisenberg_enter_critical(id: usize) { unsafe fn eisenberg_enter_critical(id: usize) {
/* announce that we want to enter */ /* announce that we want to enter */
loop { loop {
println!("Thread[{}] try enter", id); println!("Thread[{}] try enter", id);
vstore!(&FLAG[id], FlagState::Want); write_volatile(addr_of_mut!(FLAG[id]), FlagState::Want);
loop { loop {
/* check if any with higher priority is `Want` or `In` */ /* check if any with higher priority is `Want` or `In` */
let mut prior_thread: Option<usize> = None; let mut prior_thread: Option<usize> = None;
let turn = vload!(&TURN); let turn = read_volatile(addr_of!(TURN));
let ring_id = if id < turn { id + THREAD_NUM } else { id }; let ring_id = if id < turn { id + THREAD_NUM } else { id };
// FLAG.iter() may lead to some errors, use for-loop instead // FLAG.iter() may lead to some errors, use for-loop instead
for i in turn..ring_id { for i in turn..ring_id {
if vload!(&FLAG[i % THREAD_NUM]) != FlagState::Out { if read_volatile(addr_of!(FLAG[i % THREAD_NUM])) != FlagState::Out {
prior_thread = Some(i % THREAD_NUM); prior_thread = Some(i % THREAD_NUM);
break; break;
} }
@ -66,13 +68,13 @@ fn eisenberg_enter_critical(id: usize) {
sleep(1); sleep(1);
} }
/* now tentatively claim the resource */ /* now tentatively claim the resource */
vstore!(&FLAG[id], FlagState::In); write_volatile(addr_of_mut!(FLAG[id]), FlagState::In);
/* enforce the order of `claim` and `conflict check`*/ /* enforce the order of `claim` and `conflict check`*/
memory_fence!(); memory_fence!();
/* check if anthor thread is also `In`, which imply a conflict*/ /* check if anthor thread is also `In`, which imply a conflict*/
let mut conflict = false; let mut conflict = false;
for i in 0..THREAD_NUM { for i in 0..THREAD_NUM {
if i != id && vload!(&FLAG[i]) == FlagState::In { if i != id && read_volatile(addr_of!(FLAG[i])) == FlagState::In {
conflict = true; conflict = true;
} }
} }
@ -83,28 +85,28 @@ fn eisenberg_enter_critical(id: usize) {
/* no need to sleep */ /* no need to sleep */
} }
/* clain the trun */ /* clain the trun */
vstore!(&TURN, id); write_volatile(addr_of_mut!(TURN), id);
println!("Thread[{}] enter", id); println!("Thread[{}] enter", id);
} }
fn eisenberg_exit_critical(id: usize) { unsafe fn eisenberg_exit_critical(id: usize) {
/* find next one who wants to enter and give the turn to it*/ /* find next one who wants to enter and give the turn to it*/
let mut next = id; let mut next = id;
let ring_id = id + THREAD_NUM; let ring_id = id + THREAD_NUM;
for i in (id + 1)..ring_id { for i in (id + 1)..ring_id {
let idx = i % THREAD_NUM; let idx = i % THREAD_NUM;
if vload!(&FLAG[idx]) == FlagState::Want { if read_volatile(addr_of!(FLAG[idx])) == FlagState::Want {
next = idx; next = idx;
break; break;
} }
} }
vstore!(&TURN, next); write_volatile(addr_of_mut!(TURN), next);
/* All done */ /* All done */
vstore!(&FLAG[id], FlagState::Out); write_volatile(addr_of_mut!(FLAG[id]), FlagState::Out);
println!("Thread[{}] exit, give turn to {}", id, next); println!("Thread[{}] exit, give turn to {}", id, next);
} }
pub fn thread_fn(id: usize) -> ! { pub unsafe fn thread_fn(id: usize) -> ! {
println!("Thread[{}] init.", id); println!("Thread[{}] init.", id);
for _ in 0..N { for _ in 0..N {
eisenberg_enter_critical(id); eisenberg_enter_critical(id);

View File

@ -1,6 +1,5 @@
#![no_std] #![no_std]
#![no_main] #![no_main]
#![feature(core_intrinsics)]
#[macro_use] #[macro_use]
extern crate user_lib; extern crate user_lib;
@ -8,6 +7,7 @@ extern crate alloc;
extern crate core; extern crate core;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::ptr::{addr_of, addr_of_mut, read_volatile, write_volatile};
use core::sync::atomic::{AtomicUsize, Ordering}; use core::sync::atomic::{AtomicUsize, Ordering};
use user_lib::{exit, sleep, thread_create, waittid}; use user_lib::{exit, sleep, thread_create, waittid};
const N: usize = 1000; const N: usize = 1000;
@ -28,12 +28,12 @@ fn critical_test_exit() {
assert_eq!(GUARD.fetch_sub(1, Ordering::SeqCst), 1); assert_eq!(GUARD.fetch_sub(1, Ordering::SeqCst), 1);
} }
fn peterson_enter_critical(id: usize, peer_id: usize) { unsafe fn peterson_enter_critical(id: usize, peer_id: usize) {
// println!("Thread[{}] try enter", id); // println!("Thread[{}] try enter", id);
vstore!(&FLAG[id], true); write_volatile(addr_of_mut!(FLAG[id]), true);
vstore!(&TURN, peer_id); write_volatile(addr_of_mut!(TURN), peer_id);
memory_fence!(); memory_fence!();
while vload!(&FLAG[peer_id]) && vload!(&TURN) == peer_id { while read_volatile(addr_of!(FLAG[peer_id])) && read_volatile(addr_of!(TURN)) == peer_id {
// println!("Thread[{}] enter fail", id); // println!("Thread[{}] enter fail", id);
sleep(1); sleep(1);
// println!("Thread[{}] retry enter", id); // println!("Thread[{}] retry enter", id);
@ -41,12 +41,12 @@ fn peterson_enter_critical(id: usize, peer_id: usize) {
// println!("Thread[{}] enter", id); // println!("Thread[{}] enter", id);
} }
fn peterson_exit_critical(id: usize) { unsafe fn peterson_exit_critical(id: usize) {
vstore!(&FLAG[id], false); write_volatile(addr_of_mut!(FLAG[id]), false);
// println!("Thread[{}] exit", id); // println!("Thread[{}] exit", id);
} }
pub fn thread_fn(id: usize) -> ! { pub unsafe fn thread_fn(id: usize) -> ! {
// println!("Thread[{}] init.", id); // println!("Thread[{}] init.", id);
let peer_id: usize = id ^ 1; let peer_id: usize = id ^ 1;
for iter in 0..N { for iter in 0..N {

View File

@ -7,6 +7,7 @@ extern crate alloc;
use crate::alloc::string::ToString; use crate::alloc::string::ToString;
use alloc::vec::Vec; use alloc::vec::Vec;
use core::ptr::addr_of_mut;
use user_lib::{exit, get_time, thread_create, waittid}; use user_lib::{exit, get_time, thread_create, waittid};
static mut A: usize = 0; static mut A: usize = 0;
@ -16,7 +17,7 @@ const THREAD_COUNT: usize = 16;
unsafe fn f(count: usize) -> ! { unsafe fn f(count: usize) -> ! {
let mut t = 2usize; let mut t = 2usize;
for _ in 0..PER_THREAD { for _ in 0..PER_THREAD {
let a = &mut A as *mut usize; let a = addr_of_mut!(A);
let cur = a.read_volatile(); let cur = a.read_volatile();
for _ in 0..count { for _ in 0..count {
t = t * t % 10007; t = t * t % 10007;

View File

@ -2,7 +2,6 @@
#![feature(linkage)] #![feature(linkage)]
#![feature(panic_info_message)] #![feature(panic_info_message)]
#![feature(alloc_error_handler)] #![feature(alloc_error_handler)]
#![feature(core_intrinsics)]
#[macro_use] #[macro_use]
pub mod console; pub mod console;