llvm-mos / llvm-mos-sdk

SDK for developing with the llvm-mos compiler
https://www.llvm-mos.org
Other
270 stars 56 forks source link

Rewrite malloc #292

Closed mysterymath closed 8 months ago

mysterymath commented 8 months ago

This uses Knuth boundary tags to allow constant-time coalescing. The allocator remains first fit, but with this implementation, all of the O(n) loops have been removed except for the scan for first fit, which can exit early.

The free list has been altered to search for chunks in FIFO order; from Wilson's survey, this is an excellent strategy compared to other simple approaches, since it maximizes the amount of time a chunk is available to be coalesced. This minimizes fragmentation, which increases the expected speed of the first fit scan.

A typical boundary tag implementation requires a boolean tag on each chunk indicating whether the previous chunk is free. We do this the usual way: chunks are aligned to 2, and the prev_free tag is the LSB of the size.

The minimum allocation size remains 8 bytes. Two bytes are used per allocated chunk for the size and prev_free bit, and one byte of padding is used at the end for odd sized requests. Other than this, there is now no additional wasted space to maintain the free list, since the list is now maintained entirely using the free portions of the heap.

The cost is a modestly increased implementation size. This also includes an implementation of aligned_alloc. But broadly, this is more in line with what's expected from a modern malloc implementation. The main improvement possible at this point would be to achieve constant time allocations using size-segregated free lists, but this would need actual measurement.