Skip to content

Commit c27ea93

Browse files
authored
Use our new RangeInclusive type for PageRange/FrameRange (theseus-os#979)
See 7be4829 for more details on this `RangeInclusive` type.
1 parent 7be4829 commit c27ea93

File tree

8 files changed

+35
-40
lines changed

8 files changed

+35
-40
lines changed

Cargo.lock

Lines changed: 6 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -634,6 +634,7 @@ doc:
634634
--package owned_borrowed_trait \
635635
--package percent-encoding \
636636
--package port_io \
637+
--package range_inclusive \
637638
--package stdio \
638639
--package str_ref
639640
## Now, build the docs for all of Theseus's main kernel crates.

book/src/subsystems/memory.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,8 +45,8 @@ Intrinsically, `Page`s have no relation to `PhysicalAddress`es, and similarly, `
4545

4646

4747
For convenience, Theseus provides dedicated "range" types to represent a contiguous range of virtual `Page`s or physical `Frame`s.
48-
They are inclusive ranges on both sides; see Rust's built-in [`RangeInclusive`] type for more information.
49-
These types implement the standard Rust [`Iterator`] trait, allowing for easy iteration over all pages or frames in a range.
48+
They are inclusive ranges on both sides; see our custom [`RangeInclusive`] type that replaces Rust's built-in `core::ops::RangeInclusive` type for more information.
49+
These types implement the standard Rust [`IntoIterator`] trait, allowing for easy iteration over all pages or frames in a range.
5050

5151
Theseus employs macros to generate the implementation of the above basic types,
5252
as they are symmetric across the virtual memory and physical memory categories.
@@ -103,7 +103,7 @@ That is a powerful guarantee that allows us to build stronger isolation and safe
103103
[`page_allocator`]: https://theseus-os.github.io/Theseus/doc/page_allocator/index.html
104104
[`frame_allocator`]: https://theseus-os.github.io/Theseus/doc/frame_allocator/index.html
105105
[`Iterator`]: https://doc.rust-lang.org/std/iter/trait.Iterator.html
106-
[`RangeInclusive`]: https://doc.rust-lang.org/std/ops/struct.RangeInclusive.html
106+
[`RangeInclusive`]: https://theseus-os.github.io/Theseus/doc/range_inclusive/index.html
107107

108108
[page allocator]: https://theseus-os.github.io/Theseus/doc/page_allocator/index.html
109109
[frame allocator]: https://theseus-os.github.io/Theseus/doc/frame_allocator/index.html

kernel/frame_allocator/Cargo.toml

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,15 @@ authors = ["Kevin Boos <[email protected]>"]
33
name = "frame_allocator"
44
description = "The allocator for physical memory frames."
55
version = "0.1.0"
6+
edition = "2021"
67

78
[dependencies]
9+
log = "0.4.8"
810
spin = "0.9.4"
911
intrusive-collections = "0.9.0"
1012
static_assertions = "1.1.0"
1113

12-
[dependencies.log]
13-
version = "0.4.8"
14+
range_inclusive = { path = "../../libs/range_inclusive" }
1415

15-
[dependencies.kernel_config]
16-
path = "../kernel_config"
17-
18-
[dependencies.memory_structs]
19-
path = "../memory_structs"
20-
21-
[lib]
22-
crate-type = ["rlib"]
16+
kernel_config = { path = "../kernel_config" }
17+
memory_structs = { path = "../memory_structs" }

kernel/frame_allocator/src/lib.rs

Lines changed: 14 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,17 +18,10 @@
1818
//! We don't need to do so until we actually run out of address space or until
1919
//! a requested address is in a chunk that needs to be merged.
2020
21-
#![allow(clippy::blocks_in_if_conditions)]
2221
#![no_std]
22+
#![allow(clippy::blocks_in_if_conditions)]
2323

2424
extern crate alloc;
25-
#[macro_use] extern crate log;
26-
extern crate kernel_config;
27-
extern crate memory_structs;
28-
extern crate spin;
29-
#[macro_use] extern crate static_assertions;
30-
extern crate intrusive_collections;
31-
3225
#[cfg(test)]
3326
mod test;
3427

@@ -37,11 +30,14 @@ mod static_array_rb_tree;
3730

3831

3932
use core::{borrow::Borrow, cmp::{Ordering, min, max}, fmt, ops::{Deref, DerefMut}, marker::PhantomData};
33+
use intrusive_collections::Bound;
4034
use kernel_config::memory::*;
35+
use log::{error, warn, debug, trace};
4136
use memory_structs::{PhysicalAddress, Frame, FrameRange};
37+
use range_inclusive::RangeInclusiveIterator;
4238
use spin::Mutex;
43-
use intrusive_collections::Bound;
4439
use static_array_rb_tree::*;
40+
use static_assertions::assert_not_impl_any;
4541

4642
const FRAME_SIZE: usize = PAGE_SIZE;
4743
const MIN_FRAME: Frame = Frame::containing_address(PhysicalAddress::zero());
@@ -494,31 +490,29 @@ impl<'f> IntoIterator for &'f AllocatedFrames {
494490
fn into_iter(self) -> Self::IntoIter {
495491
AllocatedFramesIter {
496492
_owner: self,
497-
range: self.frames.clone(),
493+
range_iter: self.frames.iter(),
498494
}
499495
}
500496
}
501497

502498
/// An iterator over each [`AllocatedFrame`] in a range of [`AllocatedFrames`].
503-
///
499+
///
504500
/// We must implement our own iterator type here in order to tie the lifetime `'f`
505501
/// of a returned `AllocatedFrame<'f>` type to the lifetime of its containing `AllocatedFrames`.
506502
/// This is because the underlying type of `AllocatedFrames` is a [`FrameRange`],
507-
/// which itself is a [`core::ops::RangeInclusive`] of [`Frame`]s, and unfortunately the
508-
/// `RangeInclusive` type doesn't implement an immutable iterator.
509-
///
510-
/// Iterating through a `RangeInclusive` actually modifies its own internal range,
511-
/// so we must avoid doing that because it would break the semantics of a `FrameRange`.
512-
/// In fact, this is why [`FrameRange`] only implements `IntoIterator` but
513-
/// does not implement [`Iterator`] itself.
503+
/// which itself is a [`RangeInclusive`] of [`Frame`]s.
504+
/// Currently, the [`RangeInclusiveIterator`] type creates a clone of the original
505+
/// [`RangeInclusive`] instances rather than borrowing a reference to it.
506+
///
507+
/// [`RangeInclusive`]: range_inclusive::RangeInclusive
514508
pub struct AllocatedFramesIter<'f> {
515509
_owner: &'f AllocatedFrames,
516-
range: FrameRange,
510+
range_iter: RangeInclusiveIterator<Frame>,
517511
}
518512
impl<'f> Iterator for AllocatedFramesIter<'f> {
519513
type Item = AllocatedFrame<'f>;
520514
fn next(&mut self) -> Option<Self::Item> {
521-
self.range.next().map(|frame|
515+
self.range_iter.next().map(|frame|
522516
AllocatedFrame {
523517
frame, _phantom: PhantomData,
524518
}

kernel/frame_allocator/src/static_array_rb_tree.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ impl<T: Ord + 'static> StaticArrayRBTree<T> {
100100
return Ok(ValueRefMut::Array(elem));
101101
}
102102
}
103-
error!("Out of space in StaticArrayRBTree's inner array, failed to insert value.");
103+
log::error!("Out of space in StaticArrayRBTree's inner array, failed to insert value.");
104104
Err(value)
105105
}
106106
Inner::RBTree(tree) => {

kernel/memory_structs/Cargo.toml

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,4 @@ derive_more = "0.99.0"
1111
paste = "1.0.5"
1212

1313
kernel_config = { path = "../kernel_config" }
14-
15-
[lib]
16-
crate-type = ["rlib"]
14+
range_inclusive = { path = "../../libs/range_inclusive" }

kernel/memory_structs/src/lib.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,13 @@ use core::{
1212
cmp::{min, max},
1313
fmt,
1414
iter::Step,
15-
ops::{Add, AddAssign, Deref, DerefMut, RangeInclusive, Sub, SubAssign}
15+
ops::{Add, AddAssign, Deref, DerefMut, Sub, SubAssign}
1616
};
1717
use kernel_config::memory::{MAX_PAGE_NUMBER, PAGE_SIZE};
1818
use zerocopy::FromBytes;
1919
use paste::paste;
2020
use derive_more::*;
21+
use range_inclusive::{RangeInclusive, RangeInclusiveIterator};
2122

2223
/// A macro for defining `VirtualAddress` and `PhysicalAddress` structs
2324
/// and implementing their common traits, which are generally identical.
@@ -488,9 +489,9 @@ macro_rules! implement_page_frame_range {
488489
}
489490
impl IntoIterator for $TypeName {
490491
type Item = $chunk;
491-
type IntoIter = RangeInclusive<$chunk>;
492+
type IntoIter = RangeInclusiveIterator<$chunk>;
492493
fn into_iter(self) -> Self::IntoIter {
493-
self.0
494+
self.0.iter()
494495
}
495496
}
496497

0 commit comments

Comments
 (0)