From 2151601e5a7cf1c429b842017302a1be093d0cc2 Mon Sep 17 00:00:00 2001 From: travis1829 Date: Wed, 31 Mar 2021 06:08:30 +0000 Subject: [PATCH 1/2] Use `const Default` trait in arena. --- kernel-rs/Cargo.lock | 4 ++-- kernel-rs/Cargo.toml | 2 +- kernel-rs/src/arena.rs | 41 ++++++++++++++++++++++++++++++--------- kernel-rs/src/bio.rs | 18 ++++++++--------- kernel-rs/src/file.rs | 15 +++++++------- kernel-rs/src/fs/inode.rs | 14 +++++++------ kernel-rs/src/lib.rs | 2 ++ 7 files changed, 62 insertions(+), 34 deletions(-) diff --git a/kernel-rs/Cargo.lock b/kernel-rs/Cargo.lock index e74cfa5c2..f96d54a29 100644 --- a/kernel-rs/Cargo.lock +++ b/kernel-rs/Cargo.lock @@ -2,9 +2,9 @@ # It is not intended for manual editing. [[package]] name = "array-macro" -version = "2.0.0" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "971f4e6bd8c03058ca7562baf83b44396dbcc65476eba33071700cdc24e9c5eb" +checksum = "4a08c8f180019011a1d94e5eebcbfaa548736815f636fadc10955f1b622b4c71" [[package]] name = "arrayvec" diff --git a/kernel-rs/Cargo.toml b/kernel-rs/Cargo.toml index e36020265..0a42cbe7d 100644 --- a/kernel-rs/Cargo.toml +++ b/kernel-rs/Cargo.toml @@ -26,7 +26,7 @@ scopeguard = { version = "1.1.0", default-features = false } arrayvec = { version = "0.5.2", default-features = false } cstr_core = { version = "0.2.2", default-features = false } spin = { version = "0.7.1", default-features = false } -array-macro = "2.0.0" +array-macro = "2.1.0" static_assertions = "1.1.0" itertools = { version = "0.10.0", default-features = false } pin-project = "1" diff --git a/kernel-rs/src/arena.rs b/kernel-rs/src/arena.rs index cadcb40c3..7b6ac30fa 100644 --- a/kernel-rs/src/arena.rs +++ b/kernel-rs/src/arena.rs @@ -3,6 +3,7 @@ use core::mem::{self, ManuallyDrop}; use core::ops::Deref; use core::pin::Pin; +use array_macro::array; use pin_project::pin_project; use crate::list::*; @@ -124,9 +125,21 @@ pub struct Rc { unsafe impl> Send for Rc {} impl ArrayArena { - // TODO(https://github.com/kaist-cp/rv6/issues/371): unsafe... - pub const fn new(entries: [RcCell; CAPACITY]) -> Self { - Self { entries } + /// Returns an `ArrayArena` of size `CAPACITY` that is wrapped by a `Spinlock` + /// and filled with `D`'s const default value. Note that `D` must `impl const [Default]`. + /// + /// # Examples + /// + /// ```rust,no_run + /// let arr_arena = ArrayArena::::new_locked("arr_arena"); + /// ``` + pub const fn new_locked(name: &'static str) -> Spinlock> { + Spinlock::new( + name, + ArrayArena { + entries: array![_ => RcCell::new(Default::default()); CAPACITY], + }, + ) } } @@ -246,12 +259,22 @@ unsafe impl ListNode for MruEntry { } impl MruArena { - // TODO(https://github.com/kaist-cp/rv6/issues/371): unsafe... - pub const fn new(entries: [MruEntry; CAPACITY]) -> Self { - Self { - entries, - list: unsafe { List::new() }, - } + /// Returns an `MruArena` of size `CAPACITY` that is wrapped by a `Spinlock` + /// and filled with `D`'s const default value. Note that `D` must `impl const [Default]`. + /// + /// # Examples + /// + /// ```rust,no_run + /// let mru_arena = MruArena::::new_locked("mru_arena"); + /// ``` + pub const fn new_locked(name: &'static str) -> Spinlock> { + Spinlock::new( + name, + MruArena { + entries: array![_ => MruEntry::new(Default::default()); CAPACITY], + list: unsafe { List::new() }, + }, + ) } pub fn init(self: Pin<&mut Self>) { diff --git a/kernel-rs/src/bio.rs b/kernel-rs/src/bio.rs index 5073450ec..760de2cc0 100644 --- a/kernel-rs/src/bio.rs +++ b/kernel-rs/src/bio.rs @@ -14,10 +14,8 @@ use core::mem::{self, ManuallyDrop}; use core::ops::{Deref, DerefMut}; -use array_macro::array; - use crate::{ - arena::{Arena, ArenaObject, MruArena, MruEntry, Rc}, + arena::{Arena, ArenaObject, MruArena, Rc}, lock::{Sleeplock, Spinlock}, param::{BSIZE, NBUF}, proc::WaitChannel, @@ -44,6 +42,13 @@ impl BufEntry { } } +#[rustfmt::skip] // Need this to use #![feature(const_trait_impl)] +impl const Default for BufEntry { + fn default() -> Self { + Self::zero() + } +} + impl ArenaObject for BufEntry { fn finalize<'s, A: Arena>(&'s mut self, _guard: &'s mut A::Guard<'_>) { // The buffer contents should have been written. Does nothing. @@ -149,12 +154,7 @@ impl Bcache { /// /// The caller should make sure that `Bcache` never gets moved. pub const unsafe fn zero() -> Self { - unsafe { - Spinlock::new( - "BCACHE", - MruArena::new(array![_ => MruEntry::new(BufEntry::zero()); NBUF]), - ) - } + MruArena::::new_locked("BCACHE") } /// Return a unlocked buf with the contents of the indicated block. diff --git a/kernel-rs/src/file.rs b/kernel-rs/src/file.rs index a8dab911a..0c7c6b50b 100644 --- a/kernel-rs/src/file.rs +++ b/kernel-rs/src/file.rs @@ -2,8 +2,6 @@ use core::{cell::UnsafeCell, cmp, mem, ops::Deref, ops::DerefMut}; -use array_macro::array; - use crate::{ arena::{Arena, ArenaObject, ArrayArena, Rc}, fs::{FileSystem, InodeGuard, RcInode}, @@ -12,7 +10,6 @@ use crate::{ param::{BSIZE, MAXOPBLOCKS, NFILE}, pipe::AllocatedPipe, proc::CurrentProc, - rc_cell::RcCell, vm::UVAddr, }; @@ -201,6 +198,13 @@ impl File { } } +#[rustfmt::skip] // Need this to use #![feature(const_trait_impl)] +impl const Default for File { + fn default() -> Self { + Self::zero() + } +} + impl ArenaObject for File { fn finalize<'s, A: Arena>(&'s mut self, guard: &'s mut A::Guard<'_>) { // SAFETY: `FileTable` does not use `Arena::find_or_alloc`. @@ -235,10 +239,7 @@ impl ArenaObject for File { impl FileTable { pub const fn zero() -> Self { - Spinlock::new( - "FTABLE", - ArrayArena::new(array![_ => RcCell::new(File::zero()); NFILE]), - ) + ArrayArena::::new_locked("FTABLE") } /// Allocate a file structure. diff --git a/kernel-rs/src/fs/inode.rs b/kernel-rs/src/fs/inode.rs index 505a92acb..c57cb2139 100644 --- a/kernel-rs/src/fs/inode.rs +++ b/kernel-rs/src/fs/inode.rs @@ -74,7 +74,6 @@ use core::{ ptr, }; -use array_macro::array; use static_assertions::const_assert; use super::{FileName, IPB, MAXFILE, NDIRECT, NINDIRECT}; @@ -87,7 +86,6 @@ use crate::{ param::ROOTDEV, param::{BSIZE, NINODE}, proc::CurrentProc, - rc_cell::RcCell, stat::Stat, vm::UVAddr, }; @@ -675,6 +673,13 @@ impl InodeGuard<'_> { } } +#[rustfmt::skip] // Need this to use #![feature(const_trait_impl)] +impl const Default for Inode { + fn default() -> Self { + Self::zero() + } +} + impl ArenaObject for Inode { /// Drop a reference to an in-memory inode. /// If that was the last reference, the inode table entry can @@ -810,10 +815,7 @@ impl Inode { impl Itable { pub const fn zero() -> Self { - Spinlock::new( - "ITABLE", - ArrayArena::new(array![_ => RcCell::new(Inode::zero()); NINODE]), - ) + ArrayArena::::new_locked("ITABLE") } /// Find the inode with number inum on device dev diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index b57013df9..1f7509bb4 100644 --- a/kernel-rs/src/lib.rs +++ b/kernel-rs/src/lib.rs @@ -49,6 +49,8 @@ #![feature(array_value_iter)] #![feature(const_fn)] #![feature(const_fn_union)] +#![feature(const_trait_impl)] +#![feature(const_precise_live_drops)] #![feature(maybe_uninit_extra)] #![feature(generic_associated_types)] #![feature(unsafe_block_in_unsafe_fn)] From 6b8c9eb394e3025f00c1506306ad5b85c41d5495 Mon Sep 17 00:00:00 2001 From: travis1829 Date: Wed, 31 Mar 2021 15:15:22 +0000 Subject: [PATCH 2/2] Change `new_locked` -> `new`. --- kernel-rs/src/arena.rs | 42 +++++++++++++++++++-------------------- kernel-rs/src/bio.rs | 4 ++-- kernel-rs/src/file.rs | 4 ++-- kernel-rs/src/fs/inode.rs | 4 ++-- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/kernel-rs/src/arena.rs b/kernel-rs/src/arena.rs index 7b6ac30fa..6f1dd7945 100644 --- a/kernel-rs/src/arena.rs +++ b/kernel-rs/src/arena.rs @@ -125,21 +125,21 @@ pub struct Rc { unsafe impl> Send for Rc {} impl ArrayArena { - /// Returns an `ArrayArena` of size `CAPACITY` that is wrapped by a `Spinlock` - /// and filled with `D`'s const default value. Note that `D` must `impl const [Default]`. + /// Returns an `ArrayArena` of size `CAPACITY` that is filled with `D`'s const default value. + /// Note that `D` must `impl const Default`. /// /// # Examples /// /// ```rust,no_run - /// let arr_arena = ArrayArena::::new_locked("arr_arena"); + /// let arr_arena = ArrayArena::::new(); /// ``` - pub const fn new_locked(name: &'static str) -> Spinlock> { - Spinlock::new( - name, - ArrayArena { - entries: array![_ => RcCell::new(Default::default()); CAPACITY], - }, - ) + // Note: We cannot use the generic `T` in the following function, since we need to only allow + // types that `impl const Default`, not just `impl Default`. + #[allow(clippy::new_ret_no_self)] + pub const fn new() -> ArrayArena { + ArrayArena { + entries: array![_ => RcCell::new(Default::default()); CAPACITY], + } } } @@ -259,22 +259,22 @@ unsafe impl ListNode for MruEntry { } impl MruArena { - /// Returns an `MruArena` of size `CAPACITY` that is wrapped by a `Spinlock` - /// and filled with `D`'s const default value. Note that `D` must `impl const [Default]`. + /// Returns an `MruArena` of size `CAPACITY` that is filled with `D`'s const default value. + /// Note that `D` must `impl const Default`. /// /// # Examples /// /// ```rust,no_run - /// let mru_arena = MruArena::::new_locked("mru_arena"); + /// let mru_arena = MruArena::::new(); /// ``` - pub const fn new_locked(name: &'static str) -> Spinlock> { - Spinlock::new( - name, - MruArena { - entries: array![_ => MruEntry::new(Default::default()); CAPACITY], - list: unsafe { List::new() }, - }, - ) + // Note: We cannot use the generic `T` in the following function, since we need to only allow + // types that `impl const Default`, not just `impl Default`. + #[allow(clippy::new_ret_no_self)] + pub const fn new() -> MruArena { + MruArena { + entries: array![_ => MruEntry::new(Default::default()); CAPACITY], + list: unsafe { List::new() }, + } } pub fn init(self: Pin<&mut Self>) { diff --git a/kernel-rs/src/bio.rs b/kernel-rs/src/bio.rs index 760de2cc0..cc0c52edb 100644 --- a/kernel-rs/src/bio.rs +++ b/kernel-rs/src/bio.rs @@ -42,7 +42,7 @@ impl BufEntry { } } -#[rustfmt::skip] // Need this to use #![feature(const_trait_impl)] +#[rustfmt::skip] // Need this if lower than rustfmt 1.4.34 impl const Default for BufEntry { fn default() -> Self { Self::zero() @@ -154,7 +154,7 @@ impl Bcache { /// /// The caller should make sure that `Bcache` never gets moved. pub const unsafe fn zero() -> Self { - MruArena::::new_locked("BCACHE") + Spinlock::new("BCACHE", MruArena::::new()) } /// Return a unlocked buf with the contents of the indicated block. diff --git a/kernel-rs/src/file.rs b/kernel-rs/src/file.rs index 0c7c6b50b..d48af41b7 100644 --- a/kernel-rs/src/file.rs +++ b/kernel-rs/src/file.rs @@ -198,7 +198,7 @@ impl File { } } -#[rustfmt::skip] // Need this to use #![feature(const_trait_impl)] +#[rustfmt::skip] // Need this if lower than rustfmt 1.4.34 impl const Default for File { fn default() -> Self { Self::zero() @@ -239,7 +239,7 @@ impl ArenaObject for File { impl FileTable { pub const fn zero() -> Self { - ArrayArena::::new_locked("FTABLE") + Spinlock::new("FTABLE", ArrayArena::::new()) } /// Allocate a file structure. diff --git a/kernel-rs/src/fs/inode.rs b/kernel-rs/src/fs/inode.rs index c57cb2139..29041d799 100644 --- a/kernel-rs/src/fs/inode.rs +++ b/kernel-rs/src/fs/inode.rs @@ -673,7 +673,7 @@ impl InodeGuard<'_> { } } -#[rustfmt::skip] // Need this to use #![feature(const_trait_impl)] +#[rustfmt::skip] // Need this if lower than rustfmt 1.4.34 impl const Default for Inode { fn default() -> Self { Self::zero() @@ -815,7 +815,7 @@ impl Inode { impl Itable { pub const fn zero() -> Self { - ArrayArena::::new_locked("ITABLE") + Spinlock::new("ITABLE", ArrayArena::::new()) } /// Find the inode with number inum on device dev