From 1022c3b6fa7467d70478447535c0aed9f83a313d Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Fri, 21 Jun 2019 12:43:00 +0200 Subject: [PATCH] Remove BTreeMap from example code, list possible types instead --- .../posts/10-heap-allocation/index.md | 36 ++++++++++-------- .../qemu-bump-allocator.png | Bin 12694 -> 9526 bytes 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/blog/content/second-edition/posts/10-heap-allocation/index.md b/blog/content/second-edition/posts/10-heap-allocation/index.md index e2bc998c..4f35f037 100644 --- a/blog/content/second-edition/posts/10-heap-allocation/index.md +++ b/blog/content/second-edition/posts/10-heap-allocation/index.md @@ -664,13 +664,6 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! { } println!("vec at {:p}", vec.as_slice()); - // create a map that maps keys to values - let mut rust_os = BTreeMap::new(); - rust_os.insert("RedoxOS", "https://redox-os.org/"); - rust_os.insert("Tock Embedded Operating System", "https://www.tockos.org/"); - rust_os.insert("Fuchsia (partly)", "https://fuchsia.googlesource.com/fuchsia/"); - println!("Some Rust operating systems and their websites:\n{:#?}", rust_os); - // try to create one billion boxes for _ in 0..1_000_000_000 { let _ = Box::new(1); @@ -682,17 +675,30 @@ fn kernel_main(boot_info: &'static BootInfo) -> ! { } ``` -When we run it now, we see the following: +This code example showcases a few collection types of the `alloc` crate. Of course, there are many more allocation and collection types in that crate that we can now all use in our kernel, including: + +- the reference counted pointers [`Rc`] and [`Arc`] +- the owned string type [`String`] and the [`format!`] macro +- [`LinkedList`] +- the growable ring buffer [`VecDeque`] +- [`BinaryHeap`] +- [`BTreeMap`] and [`BTreeSet`] + +[`Rc`]: https://doc.rust-lang.org/alloc/rc/ +[`Arc`]: https://doc.rust-lang.org/alloc/arc/ +[`String`]: https://doc.rust-lang.org/collections/string/struct.String.html +[`format!`]: https://doc.rust-lang.org/alloc/macro.format.html +[`LinkedList`]: https://doc.rust-lang.org/collections/linked_list/struct.LinkedList.html +[`VecDeque`]: https://doc.rust-lang.org/collections/vec_deque/struct.VecDeque.html +[`BinaryHeap`]: https://doc.rust-lang.org/collections/binary_heap/struct.BinaryHeap.html +[`BTreeMap`]: https://doc.rust-lang.org/collections/btree_map/struct.BTreeMap.html +[`BTreeSet`]: https://doc.rust-lang.org/collections/btree_set/struct.BTreeSet.html + +When we run our project now, we see the following: ![QEMU printing ` heap_value at 0x444444440000 vec at 0x4444444408000 -Some Rust operating systems and their websites: -{ - "Fuchsia (partly)": "https://fuchsia.googlesource.com/fuchsia/", - "RedoxOS": "https://redox-os.org/", - "Tock Embedded Operating System", "https://www.tockos.org/", -} panicked at 'allocation error: Layout { size_: 4, align_: 4 }', src/lib.rs:91:5 ](qemu-bump-allocator.png) @@ -700,7 +706,7 @@ As expected, we see that the `Box` and `Vec` values live on the heap, as indicat [reallocations]: https://doc.rust-lang.org/alloc/vec/struct.Vec.html#capacity-and-reallocation -The `BTreeMap` type works as expected. Our loop that tries to create one billion boxes causes a panic, however. The reason is that the bump allocator never reuses freed memory, so that for each created `Box` a few bytes are leaked. This makes the bump allocator unsuitable for many applications in practice, apart from some very specific use cases. +While the basic `Box` and `Vec` examples work as expected, our loop that tries to create one billion boxes causes a panic. The reason is that the bump allocator never reuses freed memory, so that for each created `Box` a few bytes are leaked. This makes the bump allocator unsuitable for many applications in practice, apart from some very specific use cases. #### When to use a Bump Allocator diff --git a/blog/content/second-edition/posts/10-heap-allocation/qemu-bump-allocator.png b/blog/content/second-edition/posts/10-heap-allocation/qemu-bump-allocator.png index 99fc445ce3db1e458900261fc33999fcb73500f5..71397c2970bb068afcf9a424d6094c46da573e73 100644 GIT binary patch literal 9526 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