Skip to content

Loading…

Don't derive Copy/Clone for Frame so we can be sure that it's free #52

Merged
merged 1 commit into from

1 participant

@phil-opp
Owner

If a Frame would be clonable or even Copy, the frame could be freed (e.g. passed to deallocate_frame) and used thereafter. Or it could be freed multiple times.

@phil-opp Don't derive Copy/Clone for Frame so we can be sure that it's free
If a Frame would be clonable or even Copy, the frame could be freed (e.g. passed to deallocate_frame) and used thereafter. Or it could be freed multiple times.
a8600a0
@phil-opp phil-opp merged commit cefe95d into master

2 checks passed

Details continuous-integration/travis-ci/pr The Travis CI build passed
Details continuous-integration/travis-ci/push The Travis CI build passed
@phil-opp phil-opp deleted the remove_copy_for_frame branch
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Nov 19, 2015
  1. Don't derive Copy/Clone for Frame so we can be sure that it's free

    committed
    If a Frame would be clonable or even Copy, the frame could be freed (e.g. passed to deallocate_frame) and used thereafter. Or it could be freed multiple times.
This page is out of date. Refresh to see the latest.
Showing with 12 additions and 5 deletions.
  1. +8 −3 posts/2015-11-15-allocating-frames.md
  2. +3 −1 src/memory/area_frame_allocator.rs
  3. +1 −1 src/memory/mod.rs
View
11 posts/2015-11-15-allocating-frames.md
@@ -203,12 +203,15 @@ So let's start implementing our memory map based frame allocator.
First we create a memory module with a `Frame` type (`src/memory/mod.rs`):
```rust
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Frame {
number: usize,
}
```
-(Don't forget to add the `mod memory` line to `src/lib.rs`.) Instead of e.g. the start address, we just store the frame number. We use `usize` here since the number of frames depends on the memory size. The long `derive` line makes frames printable, clonable, and comparable.
+(Don't forget to add the `mod memory` line to `src/lib.rs`.) Instead of e.g. the start address, we just store the frame number. We use `usize` here since the number of frames depends on the memory size. The long `derive` line makes frames printable and comparable.
+
+_Update_: In a previous version, the `Clone` and `Copy` traits were derived, too. [This was removed][PR 52] to make the allocator interface safer.
+[PR 52]: https://github.com/phil-opp/blog_os/pull/52
To make it easy to get the corresponding frame for a physical address, we add a `containing_address` method:
@@ -256,7 +259,9 @@ To implement the `FrameAllocator` trait, we need to implement the `allocate_fram
```rust
fn allocate_frame(&mut self) -> Option<Frame> {
if let Some(area) = self.current_area {
- let frame = self.next_free_frame;
+ // "clone" the frame to return it if it's free. Frame doesn't
+ // implement Clone, but we can construct an identical frame.
+ let frame = Frame{ number: self.next_free_frame.number };
// the last frame of the current area
let current_area_last_frame = {
View
4 src/memory/area_frame_allocator.rs
@@ -51,7 +51,9 @@ impl AreaFrameAllocator {
impl FrameAllocator for AreaFrameAllocator {
fn allocate_frame(&mut self) -> Option<Frame> {
if let Some(area) = self.current_area {
- let frame = self.next_free_frame;
+ // "clone" the frame to return it if it's free. Frame doesn't
+ // implement Clone, but we can construct an identical frame.
+ let frame = Frame{ number: self.next_free_frame.number };
// the last frame of the current area
let current_area_last_frame = {
View
2 src/memory/mod.rs
@@ -4,7 +4,7 @@ mod area_frame_allocator;
pub const PAGE_SIZE: usize = 4096;
-#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)]
pub struct Frame {
number: usize,
}
Something went wrong with that request. Please try again.