Use a queue of slabs for free lists
This commit changes the strategy for finding a free list from a stack to a queue. This tends to avoid the slow path considerably more. It has some memory overheads. TOOD: We should move the bump allocation data out of the metaslab and into the allocator. At the moment, the slab contains the bump allocation data, we should move this into the allocator, as it only ever has one slab it is bump allocating from per sizeclass.
This commit is contained in:
@@ -63,6 +63,7 @@ namespace snmalloc
|
||||
std::is_same<decltype(T::next), T*>::value, "T->next must be a T*");
|
||||
|
||||
T* head = Terminator();
|
||||
T* tail = Terminator();
|
||||
|
||||
public:
|
||||
bool is_empty()
|
||||
@@ -96,6 +97,8 @@ namespace snmalloc
|
||||
|
||||
if (head != Terminator())
|
||||
head->prev = item;
|
||||
else
|
||||
tail = item;
|
||||
|
||||
head = item;
|
||||
#ifndef NDEBUG
|
||||
@@ -103,6 +106,26 @@ namespace snmalloc
|
||||
#endif
|
||||
}
|
||||
|
||||
void insert_back(T* item)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
debug_check_not_contains(item);
|
||||
#endif
|
||||
|
||||
item->prev = tail;
|
||||
item->next = Terminator();
|
||||
|
||||
if (tail != Terminator())
|
||||
tail->next = item;
|
||||
else
|
||||
head = item;
|
||||
|
||||
tail = item;
|
||||
#ifndef NDEBUG
|
||||
debug_check();
|
||||
#endif
|
||||
}
|
||||
|
||||
void remove(T* item)
|
||||
{
|
||||
#ifndef NDEBUG
|
||||
@@ -111,6 +134,8 @@ namespace snmalloc
|
||||
|
||||
if (item->next != Terminator())
|
||||
item->next->prev = item->prev;
|
||||
else
|
||||
tail = item->prev;
|
||||
|
||||
if (item->prev != Terminator())
|
||||
item->prev->next = item->next;
|
||||
|
||||
@@ -1073,7 +1073,7 @@ namespace snmalloc
|
||||
if ((allow_reserve == NoReserve) && (slab == nullptr))
|
||||
return nullptr;
|
||||
|
||||
sl.insert(slab->get_link());
|
||||
sl.insert_back(slab->get_link());
|
||||
}
|
||||
auto& ffl = small_fast_free_lists[sizeclass];
|
||||
return slab->alloc<zero_mem>(
|
||||
|
||||
@@ -213,7 +213,7 @@ namespace snmalloc
|
||||
meta.link = index;
|
||||
|
||||
// Push on the list of slabs for this sizeclass.
|
||||
sl->insert(meta.get_link(this));
|
||||
sl->insert_back(meta.get_link(this));
|
||||
meta.debug_slab_invariant(is_short(), this);
|
||||
return Superslab::NoSlabReturn;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user