123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162 |
- use core::{
- cmp::Ordering,
- fmt::{self, Debug, Formatter},
- ops::{Add, RangeBounds, Sub},
- };
- #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
- pub struct VAddr(pub usize);
- #[derive(Clone, Copy)]
- pub struct VRange {
- start: VAddr,
- end: VAddr,
- }
- const USER_SPACE_MEMORY_TOP: VAddr = VAddr(0x8000_0000_0000);
- impl VAddr {
- pub fn floor(&self) -> Self {
- VAddr(self.0 & !0xfff)
- }
- pub fn ceil(&self) -> Self {
- VAddr((self.0 + 0xfff) & !0xfff)
- }
- pub fn is_user(&self) -> bool {
- self.0 != 0 && self < &USER_SPACE_MEMORY_TOP
- }
- }
- impl Sub for VAddr {
- type Output = usize;
- fn sub(self, rhs: Self) -> Self::Output {
- self.0 - rhs.0
- }
- }
- impl Add<usize> for VAddr {
- type Output = Self;
- fn add(self, rhs: usize) -> Self::Output {
- VAddr(self.0 + rhs)
- }
- }
- impl Sub<usize> for VAddr {
- type Output = Self;
- fn sub(self, rhs: usize) -> Self::Output {
- VAddr(self.0 - rhs)
- }
- }
- impl Debug for VAddr {
- fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
- write!(f, "V{:#x}", self.0)
- }
- }
- impl Debug for VRange {
- fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
- write!(f, "[{:?}, {:?})", self.start, self.end)
- }
- }
- impl Eq for VRange {}
- impl PartialOrd for VRange {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- Some(self.cmp(other))
- }
- }
- impl PartialEq for VRange {
- fn eq(&self, other: &Self) -> bool {
- self.cmp(other) == Ordering::Equal
- }
- }
- /// Any two ranges that have one of them containing the other are considered equal.
- impl Ord for VRange {
- fn cmp(&self, other: &Self) -> Ordering {
- if self.start == other.start {
- return Ordering::Equal;
- }
- if self.end == other.end {
- if self.start == self.end {
- return Ordering::Greater;
- }
- if other.start == other.end {
- return Ordering::Less;
- }
- return Ordering::Equal;
- }
- if self.start < other.start {
- if other.end < self.end {
- return Ordering::Equal;
- } else {
- return Ordering::Less;
- }
- }
- if other.start < self.start {
- if self.end < other.end {
- return Ordering::Equal;
- } else {
- return Ordering::Greater;
- }
- }
- unreachable!()
- }
- }
- impl From<VAddr> for VRange {
- fn from(addr: VAddr) -> Self {
- VRange::new(addr, addr)
- }
- }
- impl VRange {
- pub fn new(start: VAddr, end: VAddr) -> Self {
- assert!(start <= end);
- VRange { start, end }
- }
- pub fn is_overlapped(&self, other: &Self) -> bool {
- self == other
- }
- pub fn is_user(&self) -> bool {
- self.start < USER_SPACE_MEMORY_TOP && self.end <= USER_SPACE_MEMORY_TOP
- }
- pub fn start(&self) -> VAddr {
- self.start
- }
- pub fn end(&self) -> VAddr {
- self.end
- }
- pub fn len(&self) -> usize {
- self.end.0 - self.start.0
- }
- pub fn shrink(&self, count: usize) -> Self {
- assert!(count <= self.len());
- VRange::new(self.start, self.end - count)
- }
- pub fn grow(&self, count: usize) -> Self {
- VRange::new(self.start, self.end + count)
- }
- pub fn into_range(self) -> impl RangeBounds<Self> {
- VRange::from(self.start())..VRange::from(self.end())
- }
- }
|