Răsfoiți Sursa

Update the docs to reflect the actual internals

ticki 9 ani în urmă
părinte
comite
8aef24b0fb
1 a modificat fișierele cu 150 adăugiri și 149 ștergeri
  1. 150 149
      src/bookkeeper.rs

+ 150 - 149
src/bookkeeper.rs

@@ -23,7 +23,11 @@ use extra::option::OptionalExt;
 /// Parituclarly, it keeps a list of free blocks, commonly called the "block list". This list is
 /// kept. Entries in the block list can be "empty", meaning that you can overwrite the entry
 /// without breaking consistency.
+///
+/// For details about the internals, see [`BlockList`](./struct.BlockList.html) (requires the docs
+/// to be rendered with private item exposed).
 pub struct Bookkeeper {
+    /// The internal block list.
     block_list: BlockList,
 }
 
@@ -114,155 +118,6 @@ fn canonicalize_brk(size: usize) -> usize {
 ///
 /// Merging is the way the block lists keep these guarentees. Merging works by adding two adjacent
 /// free blocks to one, and then marking the secondary block as occupied.
-///
-/// The mechanism is outlined below:
-///
-/// Allocate.
-/// =========
-///
-/// We start with our initial segment.
-///
-/// ```notrust
-///    Address space
-///   I---------------------------------I
-/// B
-/// l
-/// k
-/// s
-/// ```
-///
-/// We then split it at the aligner, which is used for making sure that the pointer is aligned properly.
-///
-/// ```notrust
-///    Address space
-///   I------I
-/// B   ^    I--------------------------I
-/// l  al
-/// k
-/// s
-/// ```
-///
-/// We then use the remaining block, but leave the excessive space.
-///
-/// ```notrust
-///    Address space
-///   I------I
-/// B                           I--------I
-/// l        \_________________/
-/// k        our allocated block.
-/// s
-/// ```
-///
-/// The pointer to the marked area is then returned.
-///
-/// Deallocate
-/// ==========
-///
-/// ```notrust
-///    Address space
-///   I------I
-/// B                                  I--------I
-/// l        \_________________/
-/// k     the used block we want to deallocate.
-/// s
-/// ```
-///
-/// We start by inserting the block, while keeping the list sorted. See `insertion` for details.
-///
-/// ```notrust
-///    Address space
-///   I------I
-/// B        I-----------------I
-/// l                                  I--------I
-/// k
-/// s
-/// ```
-///
-/// Now the merging phase starts. We first observe that the first and the second block shares the
-/// end and the start respectively, in other words, we can merge these by adding the size together:
-///
-/// ```notrust
-///    Address space
-///   I------------------------I
-/// B                                  I--------I
-/// l
-/// k
-/// s
-/// ```
-///
-/// Insertion
-/// =========
-///
-/// We want to insert the block denoted by the tildes into our list. Perform a binary search to
-/// find where insertion is appropriate.
-///
-/// ```notrust
-///    Address space
-///   I------I
-/// B < here                      I--------I
-/// l                                              I------------I
-/// k
-/// s                                                             I---I
-///                  I~~~~~~~~~~I
-/// ```
-///
-/// If the entry is not empty, we check if the block can be merged to the left (i.e., the previous
-/// block). If not, check if it is possible to the right. If both of these fails, we keep pushing
-/// the blocks to the right to the next entry until a empty entry is reached:
-///
-/// ```notrust
-///    Address space
-///   I------I
-/// B < here                      I--------I <~ this one cannot move down, due to being blocked.
-/// l
-/// k                                              I------------I <~ thus we have moved this one down.
-/// s                                                             I---I
-///              I~~~~~~~~~~I
-/// ```
-///
-/// Repeating yields:
-///
-/// ```notrust
-///    Address space
-///   I------I
-/// B < here
-/// l                             I--------I <~ this one cannot move down, due to being blocked.
-/// k                                              I------------I <~ thus we have moved this one down.
-/// s                                                             I---I
-///              I~~~~~~~~~~I
-/// ```
-///
-/// Now an empty space is left out, meaning that we can insert the block:
-///
-/// ```notrust
-///    Address space
-///   I------I
-/// B            I----------I
-/// l                             I--------I
-/// k                                              I------------I
-/// s                                                             I---I
-/// ```
-///
-/// The insertion is now completed.
-///
-/// Reallocation.
-/// =============
-///
-/// We will first try to perform an in-place reallocation, and if that fails, we will use memmove.
-///
-/// ```notrust
-///    Address space
-///   I------I
-/// B \~~~~~~~~~~~~~~~~~~~~~/
-/// l     needed
-/// k
-/// s
-/// ```
-///
-/// We simply find the block next to our initial block. If this block is free and have sufficient
-/// size, we will simply merge it into our initial block. If these conditions are not met, we have
-/// to deallocate our list, and then allocate a new one, after which we use memmove to copy the
-/// data over to the newly allocated list.
 struct BlockList {
     /// The capacity of the block list.
     cap: usize,
@@ -285,6 +140,44 @@ impl BlockList {
     }
 
     /// *[See `Bookkeeper`'s respective method.](./struct.Bookkeeper.html#method.alloc)*
+    ///
+    /// # Example
+    ///
+    /// We start with our initial segment.
+    ///
+    /// ```notrust
+    ///    Address space
+    ///   I---------------------------------I
+    /// B
+    /// l
+    /// k
+    /// s
+    /// ```
+    ///
+    /// We then split it at the [aligner](./fn.aligner.html), which is used for making sure that
+    /// the pointer is aligned properly.
+    ///
+    /// ```notrust
+    ///    Address space
+    ///   I------I
+    /// B   ^    I--------------------------I
+    /// l  al
+    /// k
+    /// s
+    /// ```
+    ///
+    /// We then use the remaining block, but leave the excessive space.
+    ///
+    /// ```notrust
+    ///    Address space
+    ///   I------I
+    /// B                           I--------I
+    /// l        \_________________/
+    /// k        our allocated block.
+    /// s
+    /// ```
+    ///
+    /// The pointer to the marked area is then returned.
     fn alloc(&mut self, size: usize, align: usize) -> Unique<u8> {
         let mut ins = None;
 
@@ -428,6 +321,27 @@ impl BlockList {
     }
 
     /// *[See `Bookkeeper`'s respective method.](./struct.Bookkeeper.html#method.realloc)*
+    ///
+    /// Example
+    /// =======
+    ///
+    /// We will first try to perform an in-place reallocation, and if that fails, we will use
+    /// memmove.
+    ///
+    /// ```notrust
+    ///    Address space
+    ///   I------I
+    /// B \~~~~~~~~~~~~~~~~~~~~~/
+    /// l     needed
+    /// k
+    /// s
+    /// ```
+    ///
+    /// We simply find the block next to our initial block. If this block is free and have
+    /// sufficient size, we will simply merge it into our initial block, and leave the excessive
+    /// space as free. If these conditions are not met, we have to allocate a new list, and then
+    /// deallocate the old one, after which we use memmove to copy the data over to the newly
+    /// allocated list.
     fn realloc(&mut self, block: Block, new_size: usize, align: usize) -> Unique<u8> {
         let ind = self.find(&block);
 
@@ -485,6 +399,42 @@ impl BlockList {
     }
 
     /// *[See `Bookkeeper`'s respective method.](./struct.Bookkeeper.html#method.free)*
+    ///
+    /// # Example
+    ///
+    /// ```notrust
+    ///    Address space
+    ///   I------I
+    /// B                                  I--------I
+    /// l        \_________________/
+    /// k     the used block we want to deallocate.
+    /// s
+    /// ```
+    ///
+    /// If the blocks are adjacent, we merge them:
+    ///
+    /// ```notrust
+    ///    Address space
+    ///   I------I
+    /// B        I-----------------I
+    /// l                                  I--------I
+    /// k
+    /// s
+    /// ```
+    ///
+    /// This gives us:
+    ///
+    /// ```notrust
+    ///    Address space
+    ///   I------------------------I
+    /// B                                  I--------I
+    /// l
+    /// k
+    /// s
+    /// ```
+    ///
+    /// And we're done. If it cannot be done, we insert the block, while keeping the list sorted.
+    /// See [`insert`](#method.insert) for details.
     fn free(&mut self, block: Block) {
         let ind = self.find(&block);
 
@@ -507,6 +457,57 @@ impl BlockList {
     /// If the space is non-empty, the elements will be pushed filling out the empty gaps to the
     /// right. If all places to the right is occupied, it will reserve additional space to the
     /// block list.
+    ///
+    /// # Example
+    /// We want to insert the block denoted by the tildes into our list. Perform a binary search to
+    /// find where insertion is appropriate.
+    ///
+    /// ```notrust
+    ///    Address space
+    ///   I------I
+    /// B < here                      I--------I
+    /// l                                              I------------I
+    /// k
+    /// s                                                             I---I
+    ///                  I~~~~~~~~~~I
+    /// ```
+    ///
+    /// We keep pushing the blocks to the right to the next entry until a empty entry is reached:
+    ///
+    /// ```notrust
+    ///    Address space
+    ///   I------I
+    /// B < here                      I--------I <~ this one cannot move down, due to being blocked.
+    /// l
+    /// k                                              I------------I <~ thus we have moved this one down.
+    /// s                                                             I---I
+    ///              I~~~~~~~~~~I
+    /// ```
+    ///
+    /// Repeating yields:
+    ///
+    /// ```notrust
+    ///    Address space
+    ///   I------I
+    /// B < here
+    /// l                             I--------I <~ this one cannot move down, due to being blocked.
+    /// k                                              I------------I <~ thus we have moved this one down.
+    /// s                                                             I---I
+    ///              I~~~~~~~~~~I
+    /// ```
+    ///
+    /// Now an empty space is left out, meaning that we can insert the block:
+    ///
+    /// ```notrust
+    ///    Address space
+    ///   I------I
+    /// B            I----------I
+    /// l                             I--------I
+    /// k                                              I------------I
+    /// s                                                             I---I
+    /// ```
+    ///
+    /// The insertion is now completed.
     fn insert(&mut self, ind: usize, block: BlockEntry) {
         let len = self.len;