From 3d48ce4c00ba3c8132b88ffbc0b8a4679ca97c64 Mon Sep 17 00:00:00 2001 From: cndoit18 Date: Tue, 16 Jan 2024 00:47:04 +0800 Subject: [PATCH 1/6] feat: support devcontainer Add devcontainer support to use the development environment directly via vscode or codespaces. Signed-off-by: cndoit18 --- .devcontainer/devcontainer.json | 21 +++++++++++++++++++ .gitignore | 1 + Dockerfile | 37 ++++++++++++++++++--------------- rust-toolchain.toml | 3 ++- 4 files changed, 44 insertions(+), 18 deletions(-) create mode 100644 .devcontainer/devcontainer.json diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..2d7932f --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,21 @@ +{ + "name": "rcore-tutorial-v3", + "build": { + "dockerfile": "../Dockerfile", + "args": { + "QEMU_VERSION": "7.0.0", + "DEBIAN_FRONTEND": "noninteractive", + "GDB_VERSION": "14.1" + } + }, + "postCreateCommand": "rustup show", + "customizations": { + "vscode": { + "extensions": [ + "rust-lang.rust-analyzer", + "ms-vscode.cpptools", + "tamasfe.even-better-toml" + ] + } + } +} diff --git a/.gitignore b/.gitignore index 852c161..45fffb0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,6 +1,7 @@ .*/* !.github/* !.vscode/settings.json +!.devcontainer/devcontainer.json **/target/ **/Cargo.lock diff --git a/Dockerfile b/Dockerfile index 284db4c..a365475 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,16 +7,17 @@ FROM ubuntu:20.04 ARG QEMU_VERSION=7.0.0 +ARG GDB_VERSION=14.1 ARG HOME=/root # 0. Install general tools ARG DEBIAN_FRONTEND=noninteractive RUN apt-get update && \ apt-get install -y \ - curl \ - git \ - python3 \ - wget + curl \ + git \ + python3 \ + wget # 1. Set up QEMU RISC-V # - https://learningos.github.io/rust-based-os-comp2022/0setup-devel-env.html#qemu @@ -29,13 +30,18 @@ WORKDIR ${HOME} RUN wget https://download.qemu.org/qemu-${QEMU_VERSION}.tar.xz && \ tar xvJf qemu-${QEMU_VERSION}.tar.xz +RUN wget https://ftp.gnu.org/gnu/gdb/gdb-${GDB_VERSION}.tar.xz && \ + tar xvJf gdb-${GDB_VERSION}.tar.xz + # 1.2. Install dependencies # - https://risc-v-getting-started-guide.readthedocs.io/en/latest/linux-qemu.html#prerequisites RUN apt-get install -y \ - autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev \ - gawk build-essential bison flex texinfo gperf libtool patchutils bc \ - zlib1g-dev libexpat-dev git \ - ninja-build pkg-config libglib2.0-dev libpixman-1-dev libsdl2-dev + autoconf automake autotools-dev curl libmpc-dev libmpfr-dev libgmp-dev \ + gawk build-essential bison flex texinfo gperf libtool patchutils bc \ + zlib1g-dev libexpat-dev git \ + ninja-build pkg-config libglib2.0-dev libpixman-1-dev libsdl2-dev \ + libncurses5-dev python2 python2-dev libreadline-dev tmux + # 1.3. Build and install from source WORKDIR ${HOME}/qemu-${QEMU_VERSION} @@ -43,9 +49,14 @@ RUN ./configure --target-list=riscv64-softmmu,riscv64-linux-user && \ make -j$(nproc) && \ make install +WORKDIR ${HOME}/gdb-${GDB_VERSION} +RUN ./configure --prefix=/usr/local --target=riscv64-unknown-elf --enable-tui=yes && \ + make -j$(nproc) && \ + make install + # 1.4. Clean up WORKDIR ${HOME} -RUN rm -rf qemu-${QEMU_VERSION} qemu-${QEMU_VERSION}.tar.xz +RUN rm -rf qemu-${QEMU_VERSION} qemu-${QEMU_VERSION}.tar.xz ${HOME}/gdb-${GDB_VERSION} gdb-${GDB_VERSION}.tar.xz # 1.5. Sanity checking RUN qemu-system-riscv64 --version && \ @@ -73,13 +84,5 @@ RUN rustup --version && \ cargo --version && \ rustc --version -# 3. Build env for labs -# See os1/Makefile `env:` for example. -# This avoids having to wait for these steps each time using a new container. -RUN rustup target add riscv64gc-unknown-none-elf && \ - cargo install cargo-binutils --vers ~0.2 && \ - rustup component add rust-src && \ - rustup component add llvm-tools-preview - # Ready to go WORKDIR ${HOME} diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 3425f94..61bbf13 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,6 @@ [toolchain] profile = "minimal" # use the nightly version of the last stable toolchain, see -channel = "nightly-2023-10-09" +channel = "nightly-2024-01-18" components = ["rust-src", "llvm-tools-preview", "rustfmt", "clippy"] +targets = ["riscv64gc-unknown-none-elf"] From 790c45ecb60c78a04bb795211850b575d56b15e7 Mon Sep 17 00:00:00 2001 From: Yifan Wu Date: Sat, 20 Jan 2024 21:50:24 +0800 Subject: [PATCH 2/6] Bump rust to version 1.77.0-nightly --- .github/workflows/doc-and-test.yml | 2 +- rust-toolchain.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/doc-and-test.yml b/.github/workflows/doc-and-test.yml index b1ea980..f4027c2 100644 --- a/.github/workflows/doc-and-test.yml +++ b/.github/workflows/doc-and-test.yml @@ -4,7 +4,7 @@ on: [push] env: CARGO_TERM_COLOR: always - rust_toolchain: nightly-2023-10-09 + rust_toolchain: nightly-2024-01-18 jobs: build-doc: diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 3425f94..dd54f2e 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,5 +1,5 @@ [toolchain] profile = "minimal" # use the nightly version of the last stable toolchain, see -channel = "nightly-2023-10-09" +channel = "nightly-2024-01-18" components = ["rust-src", "llvm-tools-preview", "rustfmt", "clippy"] From fa676157da7b3b0a19be9c95617b41a97de051bc Mon Sep 17 00:00:00 2001 From: Yifan Wu Date: Sat, 20 Jan 2024 23:53:56 +0800 Subject: [PATCH 3/6] codecheck: Fix warnings --- os/src/drivers/mod.rs | 1 - os/src/fs/mod.rs | 4 ++-- os/src/mm/mod.rs | 3 +-- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/os/src/drivers/mod.rs b/os/src/drivers/mod.rs index e16c51e..605397d 100644 --- a/os/src/drivers/mod.rs +++ b/os/src/drivers/mod.rs @@ -8,7 +8,6 @@ pub mod plic; pub use block::BLOCK_DEVICE; pub use bus::*; -pub use chardev::UART; pub use gpu::*; pub use input::*; pub use net::*; diff --git a/os/src/fs/mod.rs b/os/src/fs/mod.rs index 221d68b..cbde739 100644 --- a/os/src/fs/mod.rs +++ b/os/src/fs/mod.rs @@ -11,6 +11,6 @@ pub trait File: Send + Sync { fn write(&self, buf: UserBuffer) -> usize; } -pub use inode::{list_apps, open_file, OSInode, OpenFlags, ROOT_INODE}; -pub use pipe::{make_pipe, Pipe}; +pub use inode::{list_apps, open_file, OpenFlags}; +pub use pipe::make_pipe; pub use stdio::{Stdin, Stdout}; diff --git a/os/src/mm/mod.rs b/os/src/mm/mod.rs index 574cea0..642d0b7 100644 --- a/os/src/mm/mod.rs +++ b/os/src/mm/mod.rs @@ -7,12 +7,11 @@ mod page_table; pub use address::VPNRange; pub use address::{PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum}; pub use frame_allocator::{frame_alloc, frame_alloc_more, frame_dealloc, FrameTracker}; -pub use memory_set::remap_test; pub use memory_set::{kernel_token, MapArea, MapPermission, MapType, MemorySet, KERNEL_SPACE}; use page_table::PTEFlags; pub use page_table::{ translated_byte_buffer, translated_ref, translated_refmut, translated_str, PageTable, - PageTableEntry, UserBuffer, UserBufferIterator, + PageTableEntry, UserBuffer, }; pub fn init() { From 972534f70c32cfa2beb4bfc06bbe5445644da894 Mon Sep 17 00:00:00 2001 From: Yifan Wu Date: Sun, 21 Jan 2024 15:32:33 +0800 Subject: [PATCH 4/6] codecheck: Remove UB of ch8 usertests #140 --- user/src/bin/adder.rs | 3 ++- user/src/bin/adder_atomic.rs | 3 ++- user/src/bin/adder_mutex_blocking.rs | 3 ++- user/src/bin/adder_mutex_spin.rs | 3 ++- user/src/bin/adder_peterson_spin.rs | 6 +++--- user/src/bin/adder_peterson_yield.rs | 8 +++++--- user/src/bin/adder_simple_spin.rs | 6 +++--- user/src/bin/adder_simple_yield.rs | 4 ++-- user/src/bin/eisenberg.rs | 30 +++++++++++++++------------- user/src/bin/peterson.rs | 16 +++++++-------- user/src/bin/race_adder_arg.rs | 3 ++- user/src/lib.rs | 1 - 12 files changed, 47 insertions(+), 39 deletions(-) diff --git a/user/src/bin/adder.rs b/user/src/bin/adder.rs index d1addf1..1cdce95 100644 --- a/user/src/bin/adder.rs +++ b/user/src/bin/adder.rs @@ -6,6 +6,7 @@ extern crate user_lib; extern crate alloc; use alloc::vec::Vec; +use core::ptr::addr_of_mut; use user_lib::{exit, get_time, thread_create, waittid}; static mut A: usize = 0; @@ -14,7 +15,7 @@ const THREAD_COUNT_DEFAULT: usize = 16; static mut PER_THREAD: usize = 0; 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(); for _ in 0..500 { *t = (*t) * (*t) % 10007; diff --git a/user/src/bin/adder_atomic.rs b/user/src/bin/adder_atomic.rs index 8fb5639..5e216c6 100644 --- a/user/src/bin/adder_atomic.rs +++ b/user/src/bin/adder_atomic.rs @@ -6,6 +6,7 @@ extern crate user_lib; extern crate alloc; use alloc::vec::Vec; +use core::ptr::addr_of_mut; use core::sync::atomic::{AtomicBool, Ordering}; 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; 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(); for _ in 0..500 { *t = (*t) * (*t) % 10007; diff --git a/user/src/bin/adder_mutex_blocking.rs b/user/src/bin/adder_mutex_blocking.rs index 79bb3c3..7fcb80b 100644 --- a/user/src/bin/adder_mutex_blocking.rs +++ b/user/src/bin/adder_mutex_blocking.rs @@ -6,6 +6,7 @@ extern crate user_lib; extern crate alloc; use alloc::vec::Vec; +use core::ptr::addr_of_mut; use user_lib::{exit, get_time, thread_create, waittid}; 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; 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(); for _ in 0..500 { *t = (*t) * (*t) % 10007; diff --git a/user/src/bin/adder_mutex_spin.rs b/user/src/bin/adder_mutex_spin.rs index 315a338..f5750af 100644 --- a/user/src/bin/adder_mutex_spin.rs +++ b/user/src/bin/adder_mutex_spin.rs @@ -6,6 +6,7 @@ extern crate user_lib; extern crate alloc; use alloc::vec::Vec; +use core::ptr::addr_of_mut; use user_lib::{exit, get_time, thread_create, waittid}; 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; 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(); for _ in 0..500 { *t = (*t) * (*t) % 10007; diff --git a/user/src/bin/adder_peterson_spin.rs b/user/src/bin/adder_peterson_spin.rs index 35fd0d3..1e9af5d 100644 --- a/user/src/bin/adder_peterson_spin.rs +++ b/user/src/bin/adder_peterson_spin.rs @@ -2,13 +2,13 @@ #![no_std] #![no_main] -#![feature(core_intrinsics)] #[macro_use] extern crate user_lib; extern crate alloc; use alloc::vec::Vec; +use core::ptr::{addr_of, addr_of_mut, read_volatile}; use core::sync::atomic::{compiler_fence, Ordering}; 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; 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(); for _ in 0..500 { *t = (*t) * (*t) % 10007; @@ -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 vload!(&FLAG[j]) && vload!(&TURN) == j {} + while read_volatile(addr_of!(FLAG[j])) && read_volatile(addr_of!(TURN)) == j {} } unsafe fn unlock(id: usize) { diff --git a/user/src/bin/adder_peterson_yield.rs b/user/src/bin/adder_peterson_yield.rs index 7b905e3..b25adf6 100644 --- a/user/src/bin/adder_peterson_yield.rs +++ b/user/src/bin/adder_peterson_yield.rs @@ -2,14 +2,16 @@ #![no_std] #![no_main] -#![feature(core_intrinsics)] #[macro_use] extern crate user_lib; extern crate alloc; 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_}; static mut A: usize = 0; @@ -20,7 +22,7 @@ const THREAD_COUNT_DEFAULT: usize = 2; static mut PER_THREAD: usize = 0; 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(); for _ in 0..500 { *t = (*t) * (*t) % 10007; diff --git a/user/src/bin/adder_simple_spin.rs b/user/src/bin/adder_simple_spin.rs index ad5b328..57d9fa5 100644 --- a/user/src/bin/adder_simple_spin.rs +++ b/user/src/bin/adder_simple_spin.rs @@ -1,12 +1,12 @@ #![no_std] #![no_main] -#![feature(core_intrinsics)] #[macro_use] extern crate user_lib; extern crate alloc; use alloc::vec::Vec; +use core::ptr::{addr_of, addr_of_mut, read_volatile}; use user_lib::{exit, get_time, thread_create, waittid}; static mut A: usize = 0; @@ -16,7 +16,7 @@ const THREAD_COUNT_DEFAULT: usize = 16; static mut PER_THREAD: usize = 0; 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(); for _ in 0..500 { *t = (*t) * (*t) % 10007; @@ -25,7 +25,7 @@ unsafe fn critical_section(t: &mut usize) { } unsafe fn lock() { - while vload!(&OCCUPIED) {} + while read_volatile(addr_of!(OCCUPIED)) {} OCCUPIED = true; } diff --git a/user/src/bin/adder_simple_yield.rs b/user/src/bin/adder_simple_yield.rs index 355b401..2de7924 100644 --- a/user/src/bin/adder_simple_yield.rs +++ b/user/src/bin/adder_simple_yield.rs @@ -1,12 +1,12 @@ #![no_std] #![no_main] -#![feature(core_intrinsics)] #[macro_use] extern crate user_lib; extern crate alloc; use alloc::vec::Vec; +use core::ptr::addr_of_mut; use user_lib::{exit, get_time, thread_create, waittid, yield_}; static mut A: usize = 0; @@ -16,7 +16,7 @@ const THREAD_COUNT_DEFAULT: usize = 16; static mut PER_THREAD: usize = 0; 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(); for _ in 0..500 { *t = (*t) * (*t) % 10007; diff --git a/user/src/bin/eisenberg.rs b/user/src/bin/eisenberg.rs index 5f5b309..b16d3a7 100644 --- a/user/src/bin/eisenberg.rs +++ b/user/src/bin/eisenberg.rs @@ -1,6 +1,5 @@ #![no_std] #![no_main] -#![feature(core_intrinsics)] #[macro_use] extern crate user_lib; @@ -8,7 +7,10 @@ extern crate alloc; extern crate core; 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}; const N: usize = 2; @@ -38,19 +40,19 @@ fn critical_test_exit() { 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 */ loop { println!("Thread[{}] try enter", id); - vstore!(&FLAG[id], FlagState::Want); + write_volatile(addr_of_mut!(FLAG[id]), FlagState::Want); loop { /* check if any with higher priority is `Want` or `In` */ let mut prior_thread: Option = None; - let turn = vload!(&TURN); + let turn = read_volatile(addr_of!(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 vload!(&FLAG[i % THREAD_NUM]) != FlagState::Out { + if read_volatile(addr_of!(FLAG[i % THREAD_NUM])) != FlagState::Out { prior_thread = Some(i % THREAD_NUM); break; } @@ -66,13 +68,13 @@ fn eisenberg_enter_critical(id: usize) { sleep(1); } /* 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`*/ 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 && vload!(&FLAG[i]) == FlagState::In { + if i != id && read_volatile(addr_of!(FLAG[i])) == FlagState::In { conflict = true; } } @@ -83,28 +85,28 @@ fn eisenberg_enter_critical(id: usize) { /* no need to sleep */ } /* clain the trun */ - vstore!(&TURN, id); + write_volatile(addr_of_mut!(TURN), 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*/ let mut next = id; let ring_id = id + THREAD_NUM; for i in (id + 1)..ring_id { let idx = i % THREAD_NUM; - if vload!(&FLAG[idx]) == FlagState::Want { + if read_volatile(addr_of!(FLAG[idx])) == FlagState::Want { next = idx; break; } } - vstore!(&TURN, next); + write_volatile(addr_of_mut!(TURN), next); /* All done */ - vstore!(&FLAG[id], FlagState::Out); + write_volatile(addr_of_mut!(FLAG[id]), FlagState::Out); 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); for _ in 0..N { eisenberg_enter_critical(id); diff --git a/user/src/bin/peterson.rs b/user/src/bin/peterson.rs index ee8ff93..c370c87 100644 --- a/user/src/bin/peterson.rs +++ b/user/src/bin/peterson.rs @@ -1,6 +1,5 @@ #![no_std] #![no_main] -#![feature(core_intrinsics)] #[macro_use] extern crate user_lib; @@ -8,6 +7,7 @@ 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; @@ -28,12 +28,12 @@ fn critical_test_exit() { 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); - vstore!(&FLAG[id], true); - vstore!(&TURN, peer_id); + write_volatile(addr_of_mut!(FLAG[id]), true); + write_volatile(addr_of_mut!(TURN), peer_id); 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); sleep(1); // println!("Thread[{}] retry enter", id); @@ -41,12 +41,12 @@ fn peterson_enter_critical(id: usize, peer_id: usize) { // println!("Thread[{}] enter", id); } -fn peterson_exit_critical(id: usize) { - vstore!(&FLAG[id], false); +unsafe fn peterson_exit_critical(id: usize) { + write_volatile(addr_of_mut!(FLAG[id]), false); // println!("Thread[{}] exit", id); } -pub fn thread_fn(id: usize) -> ! { +pub unsafe fn thread_fn(id: usize) -> ! { // println!("Thread[{}] init.", id); let peer_id: usize = id ^ 1; for iter in 0..N { diff --git a/user/src/bin/race_adder_arg.rs b/user/src/bin/race_adder_arg.rs index ba99b62..f33c660 100644 --- a/user/src/bin/race_adder_arg.rs +++ b/user/src/bin/race_adder_arg.rs @@ -7,6 +7,7 @@ extern crate alloc; use crate::alloc::string::ToString; use alloc::vec::Vec; +use core::ptr::addr_of_mut; use user_lib::{exit, get_time, thread_create, waittid}; static mut A: usize = 0; @@ -16,7 +17,7 @@ const THREAD_COUNT: usize = 16; unsafe fn f(count: usize) -> ! { let mut t = 2usize; for _ in 0..PER_THREAD { - let a = &mut A as *mut usize; + let a = addr_of_mut!(A); let cur = a.read_volatile(); for _ in 0..count { t = t * t % 10007; diff --git a/user/src/lib.rs b/user/src/lib.rs index bda0e8b..ca6181f 100644 --- a/user/src/lib.rs +++ b/user/src/lib.rs @@ -2,7 +2,6 @@ #![feature(linkage)] #![feature(panic_info_message)] #![feature(alloc_error_handler)] -#![feature(core_intrinsics)] #[macro_use] pub mod console; From 35948f351cdb396a6427fae54c83e6a296ba6e0b Mon Sep 17 00:00:00 2001 From: Yifan Wu Date: Sun, 21 Jan 2024 22:21:40 +0800 Subject: [PATCH 5/6] config: use MEMORY_END from mod boards #136 --- os/src/boards/qemu.rs | 1 + os/src/config.rs | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/os/src/boards/qemu.rs b/os/src/boards/qemu.rs index 35ac031..5daf541 100644 --- a/os/src/boards/qemu.rs +++ b/os/src/boards/qemu.rs @@ -1,4 +1,5 @@ pub const CLOCK_FREQ: usize = 12500000; +pub const MEMORY_END: usize = 0x8800_0000; pub const MMIO: &[(usize, usize)] = &[ (0x0010_0000, 0x00_2000), // VIRT_TEST/RTC in virt machine diff --git a/os/src/config.rs b/os/src/config.rs index 8f8b709..d9b9b71 100644 --- a/os/src/config.rs +++ b/os/src/config.rs @@ -3,11 +3,10 @@ pub const USER_STACK_SIZE: usize = 4096 * 2; pub const KERNEL_STACK_SIZE: usize = 4096 * 2; pub const KERNEL_HEAP_SIZE: usize = 0x100_0000; -pub const MEMORY_END: usize = 0x88000000; pub const PAGE_SIZE: usize = 0x1000; pub const PAGE_SIZE_BITS: usize = 0xc; pub const TRAMPOLINE: usize = usize::MAX - PAGE_SIZE + 1; pub const TRAP_CONTEXT_BASE: usize = TRAMPOLINE - PAGE_SIZE; -pub use crate::board::{CLOCK_FREQ, MMIO}; +pub use crate::board::{CLOCK_FREQ, MEMORY_END, MMIO}; From a0a1cfb33836187c3aa3026b0c82563c8b052787 Mon Sep 17 00:00:00 2001 From: Yifan Wu Date: Mon, 22 Jan 2024 00:02:05 +0800 Subject: [PATCH 6/6] usertest: Simplify using vload and vstore macro --- user/src/bin/adder_peterson_spin.rs | 4 ++-- user/src/bin/adder_simple_spin.rs | 4 ++-- user/src/bin/eisenberg.rs | 19 +++++++++---------- user/src/bin/peterson.rs | 9 ++++----- user/src/lib.rs | 10 ++++++---- 5 files changed, 23 insertions(+), 23 deletions(-) diff --git a/user/src/bin/adder_peterson_spin.rs b/user/src/bin/adder_peterson_spin.rs index 1e9af5d..44e8096 100644 --- a/user/src/bin/adder_peterson_spin.rs +++ b/user/src/bin/adder_peterson_spin.rs @@ -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) { diff --git a/user/src/bin/adder_simple_spin.rs b/user/src/bin/adder_simple_spin.rs index 57d9fa5..be99d28 100644 --- a/user/src/bin/adder_simple_spin.rs +++ b/user/src/bin/adder_simple_spin.rs @@ -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; } diff --git a/user/src/bin/eisenberg.rs b/user/src/bin/eisenberg.rs index b16d3a7..49a1d45 100644 --- a/user/src/bin/eisenberg.rs +++ b/user/src/bin/eisenberg.rs @@ -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 = 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); } diff --git a/user/src/bin/peterson.rs b/user/src/bin/peterson.rs index c370c87..e03e2a4 100644 --- a/user/src/bin/peterson.rs +++ b/user/src/bin/peterson.rs @@ -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); } diff --git a/user/src/lib.rs b/user/src/lib.rs index ca6181f..8c709fc 100644 --- a/user/src/lib.rs +++ b/user/src/lib.rs @@ -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)) } }; }