Project 2: Simalloc Help Document
Overview of Implicit Allocator
The implicit allocator:
-
Stores the size of the whole block in bytes in the header.
-
Each header (
BoundaryTag
) is 8 bytes long. -
A block that contains a payload of size
24
will be at least24 + 2 * 8
bytes long. - The phrase ”at least” is because: - The block size might be bigger due to the 16-byte payload alignment requirement (see point 2). - We may use a larger block for a smaller payload when looking for a free block in the heap during allocation.
-
Each header (
-
Aligns payloads to a multiple of 16.
-
This is done by aligning the first block to a multiple of 24.
-
The initial memory layout is like so:
-
After the first call to
extend_heap
, the memory layout is like so: -
Notice the alignment of the first free block. If an allocation were to be placed in that block, the pointer to the payload (which would be just past the header) would have address
0x20
or32
, which is 16-byte aligned. -
Additionally, by ensuring block sizes are multiples of 16, we ensure that the payload of the next block is also aligned to a multiple of 16.
-
Use of the List Struct
The src/introspectable/list.rs
file contains a partial implementation of an intrusive linked list.
The word intrusive means that unlike regular lists where a ListElem
contains the data contained within a node, the node itself contains a ListElem
, which will point to other ListElem
s in the previous and next linked nodes.
Here is a sketch of how you can use the List
:
First, you need to define a struct that embeds a ListElem
.
#[derive(Clone, Copy, Default, Debug, bytemuck::Pod, bytemuck::Zeroable)]
#[repr(C)]
pub struct FreeBlock {
header: BoundaryTag,
elem: ListElem,
}
-
To push a
FreeBlock
to aList
, you need to:-
Get a
TypedPointer<FreeBlock>
. You should already have this if you are looking to add it to a list. -
Get a
TypedPointer<ListElem>
. This can be done by pointer manipulation similar to theBlock::payload
andBlock::from_payload
methods. -
Call
List::push_front
with the memory and pointer from step 2.
-
Get a
-
To get the next
FreeBlock
in the list given afree_block: FreeBlock
, you need to:-
Get a
TypedPointer<ListElem>
throughfree_block.elem.next
. -
Get a
TypedPointer<FreeBlock>
. This can be done by pointer manipulation similar to theBlock::payload
andBlock::from_payload
methods. -
Read the memory using the
TypedPointer<FreeBlock>
.
-
Get a
Realloc Optimizations
When optimizing the realloc
routine, consider the following cases, and how you can reuse the allocation to reallocate in order to save memory and time.