From e6abb50f86f70cb9fd59d32a0aa0cd600a221a94 Mon Sep 17 00:00:00 2001 From: Paul Pan Date: Tue, 23 Apr 2024 01:03:04 +0800 Subject: [PATCH] feat: adjust Cell granularity for CapEntry --- kernel/src/objects/cap.rs | 35 ++++++++++++++++------------------- kernel/src/objects/cnode.rs | 22 ++++++++++------------ kernel/src/objects/mod.rs | 28 ++++++++++++++++------------ kernel/src/objects/untyped.rs | 16 ++++++++-------- 4 files changed, 50 insertions(+), 51 deletions(-) diff --git a/kernel/src/objects/cap.rs b/kernel/src/objects/cap.rs index 21d2549..6a505d5 100644 --- a/kernel/src/objects/cap.rs +++ b/kernel/src/objects/cap.rs @@ -29,44 +29,41 @@ impl RawCap { #[derive(Copy, Clone, Default)] pub struct Link { - pub prev: Option>>, - pub next: Option>>, + pub prev: Option>, + pub next: Option>, } -#[derive(Clone, Copy, Default)] pub struct CapEntry { - pub cap: RawCap, - pub link: Link, + pub cap: Cell, + pub link: Cell, } -pub type CapTableEntry = Cell; - impl CapEntry { pub fn new(cap: RawCap) -> Self { Self { - cap: cap, - link: Link::default(), + cap: Cell::new(cap), + link: Cell::new(Link::default()), } } pub fn init(&mut self) { - self.cap = RawCap::default(); - self.link = Link::default(); + self.cap = Cell::new(RawCap::default()); + self.link = Cell::new(Link::default()); } - pub fn prev(&self) -> Option>> { - self.link.prev + pub fn prev(&self) -> Option> { + self.link.get().prev } - pub fn next(&self) -> Option>> { - self.link.next + pub fn next(&self) -> Option> { + self.link.get().next } - pub fn set_prev(&mut self, prev: Option>>) { - self.link.prev = prev; + pub fn set_prev(&mut self, prev: Option>) { + self.link.get_mut().prev = prev; } - pub fn set_next(&mut self, next: Option>>) { - self.link.next = next; + pub fn set_next(&mut self, next: Option>) { + self.link.get_mut().next = next; } } diff --git a/kernel/src/objects/cnode.rs b/kernel/src/objects/cnode.rs index 0999311..7b76b57 100644 --- a/kernel/src/objects/cnode.rs +++ b/kernel/src/objects/cnode.rs @@ -1,7 +1,5 @@ -use core::cell::Cell; - use super::{ - cap::{CapTableEntry, RawCap}, + cap::{CapEntry, RawCap}, Cap, KernelObject, }; use crate::arch::layout::mmap_phys_to_virt; @@ -11,7 +9,7 @@ use vspace::addr::{AddressOps, PhysAddr}; /// CNodeObject is a array of Capabilities (`RawCap`) /// The size of the array is stored in CNodeCap -pub type CNodeObject = [CapTableEntry]; +pub type CNodeObject = [CapEntry]; impl KernelObject for CNodeObject { const OBJ_TYPE: ObjectType = ObjectType::CNode; @@ -48,25 +46,25 @@ impl<'a> CNodeCap<'a> { // init memory let cte = super::cap::CapEntry::new(cap); - CNodeCap::try_from(&Cell::new(cte)) + CNodeCap::try_from(&cte) .unwrap() .as_object_mut() .iter_mut() - .for_each(|cap| cap.get_mut().init()); + .for_each(|cap| cap.init()); cap } fn radix(&self) -> usize { - (self.cte.get().cap.args[0] >> Self::RADIX_OFFSET) & Self::RADIX_MASK + (self.cte.cap.get().args[0] >> Self::RADIX_OFFSET) & Self::RADIX_MASK } fn guard_size(&self) -> usize { - (self.cte.get().cap.args[0] >> Self::GUARD_SIZE_OFFSET) & Self::GUARD_SIZE_MASK + (self.cte.cap.get().args[0] >> Self::GUARD_SIZE_OFFSET) & Self::GUARD_SIZE_MASK } fn guard(&self) -> usize { - self.cte.get().cap.args[1] + self.cte.cap.get().args[1] } /// CNodeObject length @@ -79,19 +77,19 @@ impl<'a> CNodeCap<'a> { fn as_object(&self) -> &CNodeObject { unsafe { - let virt = mmap_phys_to_virt(self.cte.get().cap.ptr); + let virt = mmap_phys_to_virt(self.cte.cap.get().ptr); core::slice::from_raw_parts(virt.as_const_ptr(), self.length()) } } fn as_object_mut(&mut self) -> &mut CNodeObject { unsafe { - let virt = mmap_phys_to_virt(self.cte.get().cap.ptr); + let virt = mmap_phys_to_virt(self.cte.cap.get().ptr); core::slice::from_raw_parts_mut(virt.as_mut_ptr(), self.length()) } } - fn resolve_address_bits(&self, cap_ptr: usize, n_bits: usize) -> Result<&CapTableEntry, CapFault> { + fn resolve_address_bits(&self, cap_ptr: usize, n_bits: usize) -> Result<&CapEntry, CapFault> { let mut bits_remaining = n_bits; let mut slot = self.cte; diff --git a/kernel/src/objects/mod.rs b/kernel/src/objects/mod.rs index 7f1b279..c870308 100644 --- a/kernel/src/objects/mod.rs +++ b/kernel/src/objects/mod.rs @@ -18,7 +18,7 @@ use api::{ cap::ObjectType, error::{SysError, SysResult}, }; -use cap::CapTableEntry; +use cap::CapEntry; use core::{marker::PhantomData, ptr::NonNull}; pub mod cap; @@ -30,15 +30,15 @@ pub mod untyped; /// For the typed objects, we should bound it with an empty traits `KernelObject` /// And for those objects, at least implement `mint` method and `decodeInvocation` (not enforcing in `KernelObject` for complexity) pub struct Cap<'a, T: KernelObject + ?Sized> { - cte: &'a CapTableEntry, + cte: &'a CapEntry, cap_type: PhantomData, } -impl<'a, T: KernelObject + ?Sized> TryFrom<&'a CapTableEntry> for Cap<'a, T> { +impl<'a, T: KernelObject + ?Sized> TryFrom<&'a CapEntry> for Cap<'a, T> { type Error = SysError; - fn try_from(new: &'a CapTableEntry) -> SysResult { - if new.get().cap.cap_type != T::OBJ_TYPE { + fn try_from(new: &'a CapEntry) -> SysResult { + if new.cap.get().cap_type != T::OBJ_TYPE { Err(SysError::CapTypeMismatch) } else { Ok(Self { @@ -50,22 +50,26 @@ impl<'a, T: KernelObject + ?Sized> TryFrom<&'a CapTableEntry> for Cap<'a, T> { } impl<'a, T: KernelObject + ?Sized> Cap<'a, T> { - pub fn append(&mut self, new: &mut CapTableEntry) { - let next = self.cte.get().next(); + pub fn append(&mut self, new: &mut CapEntry) { + let next = self.cte.next(); // update new cap's link - new.get_mut().set_prev(Some(NonNull::from(self.cte))); - new.get_mut().set_next(next); + new.set_prev(Some(NonNull::from(self.cte))); + new.set_next(next); // record new cap's addr let new_addr = Some(NonNull::from(new)); // update next cap's link.prev - next.map(|mut next| unsafe { next.as_mut().get().set_prev(new_addr) }); + if let Some(mut next) = next { + unsafe { next.as_mut().set_prev(new_addr) }; + } // update self's link.next - let mut raw = self.cte.get(); - raw.set_next(new_addr); + self.cte.link.update(|mut link| { + link.next = new_addr; + link + }); } } diff --git a/kernel/src/objects/untyped.rs b/kernel/src/objects/untyped.rs index 9b09fb3..fecca9b 100644 --- a/kernel/src/objects/untyped.rs +++ b/kernel/src/objects/untyped.rs @@ -1,4 +1,4 @@ -use super::cap::{CapEntry, RawCap}; +use super::cap::RawCap; use super::cnode::{CNodeCap, CNodeObject}; use super::null::NullCap; use super::{Cap, KernelObject}; @@ -43,22 +43,22 @@ impl UntypedCap<'_> { } fn free_offset(&self) -> usize { - self.cte.get().cap.args[0] + self.cte.cap.get().args[0] } fn set_free_offset(&mut self, free_offset: usize) { - self.cte.update(|mut c| { - c.cap.args[0] = free_offset; + self.cte.cap.update(|mut c| { + c.args[0] = free_offset; c }); } fn is_device(&self) -> bool { - (self.cte.get().cap.args[1] >> 6) & 1 == 1 + (self.cte.cap.get().args[1] >> 6) & 1 == 1 } fn block_bits(&self) -> usize { - self.cte.get().cap.args[1] & MASK!(6) + self.cte.cap.get().args[1] & MASK!(6) } fn block_size(&self) -> usize { @@ -112,7 +112,7 @@ impl UntypedCap<'_> { // Create new capabilities in slot for (i, slot) in slots.iter_mut().enumerate() { - let addr = self.cte.get().cap.ptr + start_offset + i * obj_size; + let addr = self.cte.cap.get().ptr + start_offset + i * obj_size; let new_cap = match obj_type { ObjectType::Untyped => UntypedCap::mint(0, obj_type.bits(user_obj_bits), self.is_device(), addr), ObjectType::CNode => CNodeCap::mint(user_obj_bits, 0, 0, addr), @@ -120,7 +120,7 @@ impl UntypedCap<'_> { _ => return Err(SysError::InvalidArgument), }; - slot.get_mut().cap = new_cap; + slot.cap.set(new_cap); self.append(slot); }