- At boot, the kernel gets the memory area, reclaims what can be reclaimed, and passes that data to a function initializing the page frame (pf) allocator. The initializer calculates the number of page frames per area and sets a struct member that holds the index of the page at the start of the greatest free page frame extent in the area to 0.
- When malloc is called (or realloc, calloc, etc...), it looks through each memory area (there are only 6 on my bare metal machine) and decides on the first one with free space. It then allocates the correct amount of memory starting from the index of the greatest free page frame extent in the area. It increments that index by the number of pages requested. This obviously doesn't get the accurate value, but it's close enough until we run out of memory.
- If no memory areas can spare the requested space, a full recalculation to get the actual index is performed. This doesn't have to be performed very often at all, and with some optimization I think I can get it to be reasonably fast.
- Freeing memory is done by consulting an allocation header at the start of the allocated memory, and then doing simple subtraction on the index.
Code: Select all
Assume one memory area. The marker 'A' shows what the allocator thinks the index of the start
of the maximum consecutive page range is.
After initialization:
|-------------------------------------------------------|
| Free Memory |
|-------------------------------------------------------|
^
A
After some malloc(n)s:
|-------------------------------------------------------|
| Data | Data | Data | Data | Data | Free Memory |
|-------------------------------------------------------|
^
A
After freeing all most of the existing allocations.
|-------------------------------------------------------|
| Data | Free Memory | Data | Free Memory |
|-------------------------------------------------------|
^
A
Note how the marker is out of date, there is a larger amount of free memory behind it. Imagine this
continues, but in the future, allocation fails because the marker has reached the end. This
triggers a recalculation to see if the problem can be fixed. The result is this:
|-------------------------------------------------------|
| Data | Free Memory | Data | Free Memory |
|-------------------------------------------------------|
^
A
More allocations can now be preformed.
It seems weird I haven't come across this approach. Is it inherently flawed? The closest thing I could find is the watermark allocator, but this is obviously different and respects page frame boundaries.