From d1db6d07ad07973bad776e48b4d849c28a5cb580 Mon Sep 17 00:00:00 2001 From: Matthew Parkinson Date: Fri, 5 Jul 2019 17:04:55 +0100 Subject: [PATCH] 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. --- src/ds/dllist.h | 25 +++++++++++++++++++++++++ src/mem/alloc.h | 2 +- src/mem/slab.h | 2 +- 3 files changed, 27 insertions(+), 2 deletions(-) diff --git a/src/ds/dllist.h b/src/ds/dllist.h index bd10aad..1b37a16 100644 --- a/src/ds/dllist.h +++ b/src/ds/dllist.h @@ -63,6 +63,7 @@ namespace snmalloc std::is_same::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; diff --git a/src/mem/alloc.h b/src/mem/alloc.h index 7e5e569..5e35ff2 100644 --- a/src/mem/alloc.h +++ b/src/mem/alloc.h @@ -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( diff --git a/src/mem/slab.h b/src/mem/slab.h index 24c4fe2..66d6d03 100644 --- a/src/mem/slab.h +++ b/src/mem/slab.h @@ -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; }