Skip to content

Commit 5fd3288

Browse files
authored
Modify heuristic for adding new slabs. (#429)
If there is only one slab remaining, then we probabalisticly allocator a new one. If a slab is barely in use, then this could cause us to effectively double the number of slabs in use. This commit checks if the remaining slab has enough remaining elements to provide randomisation.
1 parent c299826 commit 5fd3288

File tree

3 files changed

+31
-4
lines changed

3 files changed

+31
-4
lines changed

src/ds/seqset.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,5 +159,13 @@ namespace snmalloc
159159
v.end = &(item->next);
160160
}
161161
}
162+
163+
/**
164+
* Peek at next element in the set.
165+
*/
166+
SNMALLOC_FAST_PATH const T* peek()
167+
{
168+
return v.head;
169+
}
162170
};
163171
} // namespace snmalloc

src/mem/corealloc.h

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -689,11 +689,16 @@ namespace snmalloc
689689
{
690690
#ifdef SNMALLOC_CHECK_CLIENT
691691
// Occassionally don't use the last list.
692-
if (
693-
SNMALLOC_UNLIKELY(alloc_classes[sizeclass].length == 1) &&
694-
(entropy.next_bit() == 0))
692+
if (SNMALLOC_UNLIKELY(alloc_classes[sizeclass].length == 1))
695693
{
696-
return small_alloc_slow<zero_mem>(sizeclass, fast_free_list);
694+
// If the slab has a lot of free space, then we shouldn't allocate a
695+
// new slab.
696+
auto min = alloc_classes[sizeclass]
697+
.available.peek()
698+
->free_queue.min_list_length();
699+
if ((min * 2) < threshold_for_waking_slab(sizeclass))
700+
if (entropy.next_bit() == 0)
701+
return small_alloc_slow<zero_mem>(sizeclass, fast_free_list);
697702
}
698703
#endif
699704

src/mem/freelist.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -740,6 +740,20 @@ namespace snmalloc
740740
UNUSED(domesticate);
741741
#endif
742742
}
743+
744+
/**
745+
* Returns length of the shorter free list.
746+
*
747+
* This method is only usable if the free list is adding randomisation
748+
* as that is when it has two lists.
749+
*/
750+
template<bool RANDOM_ = RANDOM>
751+
[[nodiscard]] std::enable_if_t<RANDOM_, size_t> min_list_length() const
752+
{
753+
static_assert(RANDOM_ == RANDOM, "Don't set SFINAE parameter!");
754+
755+
return length[0] < length[1] ? length[0] : length[1];
756+
}
743757
};
744758
} // namespace freelist
745759
} // namespace snmalloc

0 commit comments

Comments
 (0)