Skip to content

Commit

Permalink
Add Pipe::Drop.
Browse files Browse the repository at this point in the history
  • Loading branch information
travis1829 committed Jan 27, 2021
1 parent 5bbd4f0 commit b765f2f
Show file tree
Hide file tree
Showing 3 changed files with 23 additions and 19 deletions.
2 changes: 1 addition & 1 deletion kernel-rs/src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ impl ArenaObject for File {
A::reacquire_after(guard, || {
let typ = mem::replace(&mut self.typ, FileType::None);
match typ {
FileType::Pipe { mut pipe } => unsafe { pipe.close(self.writable) },
FileType::Pipe { pipe } => pipe.close(self.writable),
FileType::Inode { ip, .. } | FileType::Device { ip, .. } => {
// TODO(rv6)
// The inode ip will be dropped by drop(ip). Deallocation
Expand Down
2 changes: 0 additions & 2 deletions kernel-rs/src/kernel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,6 @@ pub struct Kernel {

/// Memory for virtio descriptors `&c` for queue 0.
///
/// This is a global instead of allocated because it must be multiple contiguous pages, which
/// `kernel().alloc()` doesn't support, and page aligned.
// TODO(efenniht): I moved out pages from Disk. Did I changed semantics (pointer indirection?)
virtqueue: [RawPage; 2],

Expand Down
38 changes: 22 additions & 16 deletions kernel-rs/src/pipe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ impl Pipe {
}
}

unsafe fn close(&self, writable: bool) -> bool {
pub fn close(&self, writable: bool) {
let mut inner = self.inner.lock();

if writable {
Expand All @@ -94,22 +94,24 @@ impl Pipe {
inner.readopen = false;
self.write_waitchannel.wakeup();
}
}

fn closed(&self) -> bool {
let inner = self.inner.lock();

// Return whether pipe would be freed or not
// Return whether pipe would be freed or not.
!inner.readopen && !inner.writeopen
}
}

// TODO: Remove Copy and Clone
#[derive(Copy, Clone)]
pub struct AllocatedPipe {
ptr: *mut Pipe,
pipe: &'static Pipe,
}

impl Deref for AllocatedPipe {
type Target = Pipe;
fn deref(&self) -> &Self::Target {
unsafe { &*self.ptr }
self.pipe
}
}

Expand All @@ -118,7 +120,7 @@ impl AllocatedPipe {
let page = kernel().alloc().ok_or(())?;
let ptr = page.into_usize() as *mut Pipe;

// `Pipe` must be align with `Page`
// `Pipe` must be aligned with `Page`.
const_assert!(mem::size_of::<Pipe>() <= PGSIZE);

//TODO(rv6): Since Pipe is a huge struct, need to check whether stack is used to fill `*ptr`
Expand All @@ -145,25 +147,29 @@ impl AllocatedPipe {
};
let f0 = kernel()
.ftable
.alloc_file(FileType::Pipe { pipe: Self { ptr } }, true, false)
// Safe since we already wrote a new `Pipe` to `ptr` using `ptr::write()`.
.alloc_file(FileType::Pipe { pipe: unsafe { Self { pipe: &*ptr } } }, true, false)
// It is safe because ptr is an address of page, which obtained by alloc()
.map_err(|_| kernel().free(unsafe { Page::from_usize(ptr as _) }))?;
let f1 = kernel()
.ftable
.alloc_file(FileType::Pipe { pipe: Self { ptr } }, false, true)
// Safe since we already wrote a new `Pipe` to `ptr` using `ptr::write()`.
.alloc_file(FileType::Pipe { pipe: unsafe { Self { pipe: &*ptr } } }, false, true)
// It is safe because ptr is an address of page, which obtained by alloc()
.map_err(|_| kernel().free(unsafe { Page::from_usize(ptr as _) }))?;

Ok((f0, f1))
}
}

// TODO: use `Drop` instead of `close`
// TODO: use `self` instead of `&mut self`
// `&mut self` is used because `Drop` of `File` uses AllocatedPipe inside File.
// https://github.com/kaist-cp/rv6/pull/211#discussion_r491671723
pub unsafe fn close(&mut self, writable: bool) {
if (*self.ptr).close(writable) {
kernel().free(Page::from_usize(self.ptr as *mut Pipe as _));
impl Drop for AllocatedPipe {
fn drop(&mut self) {
if self.pipe.closed() {
unsafe {
// Safe since this `self.pipe` is stored at a page
// that was allocated through `kernel().alloc()`.
kernel().free(Page::from_usize(self.pipe as *const Pipe as _));
}
}
}
}
Expand Down

0 comments on commit b765f2f

Please sign in to comment.