Skip to content

Commit c225b2b

Browse files
committed
fix after review
1 parent 9975648 commit c225b2b

File tree

3 files changed

+24
-18
lines changed

3 files changed

+24
-18
lines changed

kernel-rs/src/kalloc.rs

+7-6
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
use core::{mem, pin::Pin};
55

66
use pin_project::pin_project;
7-
use static_assertions::const_assert;
87

98
use crate::{
109
list::{List, ListEntry, ListNode},
@@ -56,6 +55,12 @@ unsafe impl ListNode for Run {
5655
/// # Safety
5756
///
5857
/// The address of each `Run` in `runs` can become a `Page` by `Page::from_usize`.
58+
// This implementation defers from xv6. Kmem of xv6 uses intrusive singly linked list, while this
59+
// Kmem uses List, which is a intrusive doubly linked list type of rv6. In a intrusive singly
60+
// linked list, it is impossible to automatically remove an entry from a list when it is dropped.
61+
// Therefore, it is nontrivial to make a general intrusive singly linked list type in a safe way.
62+
// For this reason, we use a doubly linked list instead. It adds runtime overhead, but the overhead
63+
// seems negligible.
5964
#[pin_project]
6065
pub struct Kmem {
6166
#[pin]
@@ -100,11 +105,7 @@ impl Kmem {
100105
// Fill with junk to catch dangling refs.
101106
page.write_bytes(1);
102107

103-
const_assert!(mem::size_of::<Run>() <= PGSIZE);
104-
const_assert!(PGSIZE % mem::align_of::<Run>() == 0);
105-
106-
// SAFETY: the above `const_assert`s.
107-
let run = unsafe { page.as_uninit_mut() };
108+
let run = page.as_uninit_mut();
108109
// SAFETY: `run` will be initialized by the following `init`.
109110
let run = run.write(unsafe { Run::new() });
110111
let mut run = unsafe { Pin::new_unchecked(run) };

kernel-rs/src/page.rs

+14-5
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,20 @@ impl Page {
7373
}
7474
}
7575

76-
/// # Safety
77-
///
78-
/// * `mem::size_of::<T>() <= PGSIZE`
79-
/// * `PGSIZE % mem::align_of::<T>() == 0`
80-
pub unsafe fn as_uninit_mut<T>(&mut self) -> &mut MaybeUninit<T> {
76+
pub fn as_uninit_mut<T>(&mut self) -> &mut MaybeUninit<T> {
77+
// TODO(https://github.com/kaist-cp/rv6/issues/471):
78+
// Use const_assert! (or equivalent) instead. Currently, use of T inside const_assert!
79+
// incurs a compile error: "can't use generic parameters from outer function".
80+
// Also, there's a workaround using feature(const_generics) and
81+
// feature(const_evaluatable_checked). However, using them makes the compiler panic.
82+
// When the compiler becomes updated, we will fix the following lines to use static checks.
83+
assert!(mem::size_of::<T>() <= PGSIZE);
84+
assert_eq!(PGSIZE % mem::align_of::<T>(), 0);
85+
86+
// SAFETY: self.inner is an array of length PGSIZE aligned with PGSIZE bytes.
87+
// The above assertions show that it can contain a value of T. As it contains arbitrary
88+
// data, we cannot treat it as &mut T. Instead, we use &mut MaybeUninit<T>. It's ok because
89+
// T and MaybeUninit<T> have the same size, alignment, and ABI.
8190
unsafe { &mut *(self.inner.as_ptr() as *mut MaybeUninit<T>) }
8291
}
8392
}

kernel-rs/src/pipe.rs

+3-7
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,10 @@ impl Kernel {
136136
pub fn allocate_pipe(&self) -> Result<(RcFile, RcFile), ()> {
137137
let page = self.kmem.alloc().ok_or(())?;
138138
let mut page = scopeguard::guard(page, |page| self.kmem.free(page));
139+
let ptr = page.as_uninit_mut();
139140

140-
const_assert!(mem::size_of::<Pipe>() <= PGSIZE);
141-
const_assert!(PGSIZE % mem::align_of::<Pipe>() == 0);
142-
143-
// SAFETY: the above `const_assert!`s.
144-
let ptr = unsafe { page.as_uninit_mut() };
145-
146-
//TODO(https://github.com/kaist-cp/rv6/issues/367): Since Pipe is a huge struct, need to check whether stack is used to fill `*ptr`.
141+
// TODO(https://github.com/kaist-cp/rv6/issues/367):
142+
// Since Pipe is a huge struct, need to check whether stack is used to fill `*ptr`.
147143
let ptr = NonNull::from(ptr.write(Pipe {
148144
inner: Spinlock::new(
149145
"pipe",

0 commit comments

Comments
 (0)