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 43e6ff7..bd76171 100644 --- a/src/mem/alloc.h +++ b/src/mem/alloc.h @@ -1114,7 +1114,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 0845d7c..5f21676 100644 --- a/src/mem/slab.h +++ b/src/mem/slab.h @@ -215,7 +215,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; }