WIP Two-Level Segregated Fit (TLSF) implementation
Some checks failed
CMake on multiple platforms / build (Release, cl, cl, windows-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, clang, clang++, macos-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, clang, clang++, ubuntu-latest) (push) Has been cancelled
CMake on multiple platforms / build (Release, gcc, g++, ubuntu-latest) (push) Has been cancelled

This commit is contained in:
2026-08-18 00:49:30 -07:00
parent 324fefbcfc
commit 0aa9542afd

View File

@@ -150,23 +150,50 @@ void Heap::removeFreeBlock(TLSFBlock* block)
// Allocate `size` bytes // Allocate `size` bytes
std::byte* Heap::alloc(size_t size) std::byte* Heap::alloc(size_t size)
{ {
if (size < 16) {
size = 16;
}
TLSFIndex* index = (TLSFIndex*)m_region.getAddress(); TLSFIndex* index = (TLSFIndex*)m_region.getAddress();
// size: 0b0000000000010000 (16)
// bit_ceil(size): 0b0000000000010000
// - 1 ... 0b0000000000001111
// ~ ... 0b1111111111110000
// size: 0b0000001110011101 (925) // size: 0b0000001110011101 (925)
// bit_ceil(size): 0b0000010000000000 // bit_ceil(size): 0b0000010000000000
// - 1 ... 0b0000001111111111 // - 1 ... 0b0000001111111111
// ~ ... 0b1111110000000000 // ~ ... 0b1111110000000000
uint64_t possibleFirstLevels = ~(std::bit_ceil(size) - 1); uint64_t possibleFirstLevels = ~(std::bit_floor(size) - 1);
uint64_t freeFirstLevels = index->firstLevelFreeBitMap & possibleFirstLevels; uint64_t freeFirstLevels = index->firstLevelFreeBitMap & possibleFirstLevels;
uint64_t selectedFirstLevel = std::countr_zero(freeFirstLevels); uint64_t selectedFirstLevel = std::countr_zero(freeFirstLevels);
if (selectedFirstLevel < 5) { if (selectedFirstLevel == 64) {
selectedFirstLevel = 0; // No first level with free blocks of sufficient size.
} else { return nullptr;
selectedFirstLevel -= 5;
} }
uint64_t firstLevelBufferMinSize = 1ULL << selectedFirstLevel;
uint64_t secondLevelMask = 0b1111ULL;
if (size > firstLevelBufferMinSize) {
uint64_t delta = size - firstLevelBufferMinSize;
secondLevelMask = (delta >> (selectedFirstLevel - 4)) & 0b1111ULL;
}
uint64_t possibleSecondLevels = secondLevelMask & index->secondLevelFreeBitMap[selectedFirstLevel - 4];
uint64_t selectedSecondLevel = std::countr_zero(possibleSecondLevels);
if (selectedSecondLevel == 64) {
// No free blocks available at this first level.
// Select the next highest available first level.
selectedFirstLevel = std::countr_zero(freeFirstLevels & ~(1ULL << selectedFirstLevel));
if (selectedFirstLevel == 64) {
// No other first level with free blocks of sufficient size.
return nullptr;
}
// Any buffer at the second level will fit this allocation.
selectedSecondLevel = std::countr_zero(index->secondLevelFreeBitMap[selectedFirstLevel - 4]);
}
return nullptr; // not implemented return nullptr; // not implemented