diff --git a/kernel-rs/Cargo.lock b/kernel-rs/Cargo.lock index e74cfa5c..f96d54a2 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 e3602026..0a42cbe7 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 cadcb40c..6f1dd794 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 filled with `D`'s const default value. + /// Note that `D` must `impl const Default`. + /// + /// # Examples + /// + /// ```rust,no_run + /// let arr_arena = ArrayArena::::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() -> ArrayArena { + ArrayArena { + entries: array![_ => RcCell::new(Default::default()); CAPACITY], + } } } @@ -246,10 +259,20 @@ 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, + /// 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(); + /// ``` + // 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() }, } } diff --git a/kernel-rs/src/bio.rs b/kernel-rs/src/bio.rs index 5073450e..cc0c52ed 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 if lower than rustfmt 1.4.34 +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]), - ) - } + 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 a8dab911..d48af41b 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 if lower than rustfmt 1.4.34 +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]), - ) + 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 505a92ac..29041d79 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 if lower than rustfmt 1.4.34 +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]), - ) + Spinlock::new("ITABLE", ArrayArena::::new()) } /// Find the inode with number inum on device dev diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index b57013df..1f7509bb 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)]