diff --git a/os/src/drivers/bus/virtio.rs b/os/src/drivers/bus/virtio.rs index 069d47853..6b53973d3 100644 --- a/os/src/drivers/bus/virtio.rs +++ b/os/src/drivers/bus/virtio.rs @@ -1,6 +1,6 @@ use crate::mm::{ frame_alloc_more, frame_dealloc, kernel_token, FrameTracker, PageTable, PhysAddr, PhysPageNum, - StepByOne, VirtAddr, + VirtAddr, }; use crate::sync::UPIntrFreeCell; use alloc::vec::Vec; @@ -30,7 +30,7 @@ impl Hal for VirtioHal { let mut ppn_base: PhysPageNum = pa.into(); for _ in 0..pages { frame_dealloc(ppn_base); - ppn_base.step(); + ppn_base = core::iter::Step::forward(ppn_base, 1); } 0 } diff --git a/os/src/main.rs b/os/src/main.rs index 690e40c0d..3e18aae89 100644 --- a/os/src/main.rs +++ b/os/src/main.rs @@ -1,5 +1,7 @@ #![no_std] #![no_main] +#![feature(step_trait)] +#![feature(new_range_api)] #![feature(panic_info_message)] #![feature(alloc_error_handler)] diff --git a/os/src/mm/address.rs b/os/src/mm/address.rs index df3e130fa..f04ec0f3b 100644 --- a/os/src/mm/address.rs +++ b/os/src/mm/address.rs @@ -190,81 +190,34 @@ impl PhysPageNum { } } -pub trait StepByOne { - fn step(&mut self); -} -impl StepByOne for VirtPageNum { - fn step(&mut self) { - self.0 += 1; - } -} -impl StepByOne for PhysPageNum { - fn step(&mut self) { - self.0 += 1; +impl core::iter::Step for VirtPageNum { + fn steps_between(start: &Self, end: &Self) -> (usize, Option) { + (end.0 - start.0, Some(end.0 - start.0)) } -} -#[derive(Copy, Clone)] -pub struct SimpleRange -where - T: StepByOne + Copy + PartialEq + PartialOrd + Debug, -{ - l: T, - r: T, -} -impl SimpleRange -where - T: StepByOne + Copy + PartialEq + PartialOrd + Debug, -{ - pub fn new(start: T, end: T) -> Self { - assert!(start <= end, "start {:?} > end {:?}!", start, end); - Self { l: start, r: end } - } - pub fn get_start(&self) -> T { - self.l + fn forward_checked(mut start: Self, count: usize) -> Option { + start.0 = start.0.checked_add(count)?; + Some(start) } - pub fn get_end(&self) -> T { - self.r + + fn backward_checked(mut start: Self, count: usize) -> Option { + start.0 = start.0.checked_sub(count)?; + Some(start) } } -impl IntoIterator for SimpleRange -where - T: StepByOne + Copy + PartialEq + PartialOrd + Debug, -{ - type Item = T; - type IntoIter = SimpleRangeIterator; - fn into_iter(self) -> Self::IntoIter { - SimpleRangeIterator::new(self.l, self.r) + +impl core::iter::Step for PhysPageNum { + fn steps_between(start: &Self, end: &Self) -> (usize, Option) { + (end.0 - start.0, Some(end.0 - start.0)) } -} -pub struct SimpleRangeIterator -where - T: StepByOne + Copy + PartialEq + PartialOrd + Debug, -{ - current: T, - end: T, -} -impl SimpleRangeIterator -where - T: StepByOne + Copy + PartialEq + PartialOrd + Debug, -{ - pub fn new(l: T, r: T) -> Self { - Self { current: l, end: r } + + fn forward_checked(mut start: Self, count: usize) -> Option { + start.0 = start.0.checked_add(count)?; + Some(start) } -} -impl Iterator for SimpleRangeIterator -where - T: StepByOne + Copy + PartialEq + PartialOrd + Debug, -{ - type Item = T; - fn next(&mut self) -> Option { - if self.current == self.end { - None - } else { - let t = self.current; - self.current.step(); - Some(t) - } + + fn backward_checked(mut start: Self, count: usize) -> Option { + start.0 = start.0.checked_sub(count)?; + Some(start) } } -pub type VPNRange = SimpleRange; diff --git a/os/src/mm/memory_set.rs b/os/src/mm/memory_set.rs index d607c880b..2116edb60 100644 --- a/os/src/mm/memory_set.rs +++ b/os/src/mm/memory_set.rs @@ -1,7 +1,6 @@ use super::{frame_alloc, FrameTracker}; use super::{PTEFlags, PageTable, PageTableEntry}; use super::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum}; -use super::{StepByOne, VPNRange}; use crate::config::{MEMORY_END, MMIO, PAGE_SIZE, TRAMPOLINE}; use crate::sync::UPIntrFreeCell; use alloc::collections::BTreeMap; @@ -65,7 +64,7 @@ impl MemorySet { .areas .iter_mut() .enumerate() - .find(|(_, area)| area.vpn_range.get_start() == start_vpn) + .find(|(_, area)| area.vpn_range.start == start_vpn) { area.unmap(&mut self.page_table); self.areas.remove(idx); @@ -196,7 +195,7 @@ impl MemorySet { map_perm |= MapPermission::X; } let map_area = MapArea::new(start_va, end_va, MapType::Framed, map_perm); - max_end_vpn = map_area.vpn_range.get_end(); + max_end_vpn = map_area.vpn_range.end; memory_set.push( map_area, Some(&elf.input[ph.offset() as usize..(ph.offset() + ph.file_size()) as usize]), @@ -248,7 +247,7 @@ impl MemorySet { } pub struct MapArea { - vpn_range: VPNRange, + vpn_range: core::range::Range, data_frames: BTreeMap, map_type: MapType, map_perm: MapPermission, @@ -264,7 +263,7 @@ impl MapArea { let start_vpn: VirtPageNum = start_va.floor(); let end_vpn: VirtPageNum = end_va.ceil(); Self { - vpn_range: VPNRange::new(start_vpn, end_vpn), + vpn_range: (start_vpn..end_vpn).into(), data_frames: BTreeMap::new(), map_type, map_perm, @@ -272,7 +271,7 @@ impl MapArea { } pub fn from_another(another: &MapArea) -> Self { Self { - vpn_range: VPNRange::new(another.vpn_range.get_start(), another.vpn_range.get_end()), + vpn_range: another.vpn_range, data_frames: BTreeMap::new(), map_type: another.map_type, map_perm: another.map_perm, @@ -319,7 +318,7 @@ impl MapArea { pub fn copy_data(&mut self, page_table: &PageTable, data: &[u8]) { assert_eq!(self.map_type, MapType::Framed); let mut start: usize = 0; - let mut current_vpn = self.vpn_range.get_start(); + let mut current_vpn = self.vpn_range.start; let len = data.len(); loop { let src = &data[start..len.min(start + PAGE_SIZE)]; @@ -333,7 +332,7 @@ impl MapArea { if start >= len { break; } - current_vpn.step(); + current_vpn = core::iter::Step::forward(current_vpn, 1); } } } diff --git a/os/src/mm/mod.rs b/os/src/mm/mod.rs index 642d0b7d6..67156f1c2 100644 --- a/os/src/mm/mod.rs +++ b/os/src/mm/mod.rs @@ -4,8 +4,7 @@ mod heap_allocator; mod memory_set; mod page_table; -pub use address::VPNRange; -pub use address::{PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum}; +pub use address::{PhysAddr, PhysPageNum, VirtAddr, VirtPageNum}; pub use frame_allocator::{frame_alloc, frame_alloc_more, frame_dealloc, FrameTracker}; pub use memory_set::{kernel_token, MapArea, MapPermission, MapType, MemorySet, KERNEL_SPACE}; use page_table::PTEFlags; diff --git a/os/src/mm/page_table.rs b/os/src/mm/page_table.rs index dfaf4b6cf..7c455eca3 100644 --- a/os/src/mm/page_table.rs +++ b/os/src/mm/page_table.rs @@ -1,4 +1,4 @@ -use super::{frame_alloc, FrameTracker, PhysAddr, PhysPageNum, StepByOne, VirtAddr, VirtPageNum}; +use super::{frame_alloc, FrameTracker, PhysAddr, PhysPageNum, VirtAddr, VirtPageNum}; use alloc::string::String; use alloc::vec; use alloc::vec::Vec; @@ -146,7 +146,7 @@ pub fn translated_byte_buffer(token: usize, ptr: *const u8, len: usize) -> Vec<& let start_va = VirtAddr::from(start); let mut vpn = start_va.floor(); let ppn = page_table.translate(vpn).unwrap().ppn(); - vpn.step(); + vpn = core::iter::Step::forward(vpn, 1); let mut end_va: VirtAddr = vpn.into(); end_va = end_va.min(VirtAddr::from(end)); if end_va.page_offset() == 0 {