diff --git a/core/mempool.cc b/core/mempool.cc index 417e932f02833dfd3cfce252108cb0ae6fd12b6c..638ee4d57cc4ea1449e8761e41ac707f303df6b4 100644 --- a/core/mempool.cc +++ b/core/mempool.cc @@ -228,23 +228,33 @@ void pool::add_page() }); } +inline bool pool::have_full_pages() +{ + return !_free->empty() && _free->back().nalloc == 0; +} + void pool::free_same_cpu(free_object* obj, unsigned cpu_id) { void* object = static_cast<void*>(obj); trace_pool_free_same_cpu(this, object); page_header* header = to_header(obj); - if (!--header->nalloc) { + if (!--header->nalloc && have_full_pages()) { if (header->local_free) { _free->erase(_free->iterator_to(*header)); } - // FIXME: add hysteresis sched::preempt_enable(); untracked_free_page(header); sched::preempt_disable(); } else { if (!header->local_free) { - _free->push_front(*header); + if (header->nalloc) { + _free->push_front(*header); + } else { + // keep full pages on the back, so they're not fragmented + // early, and so we find them easily in have_full_pages() + _free->push_back(*header); + } } obj->next = header->local_free; header->local_free = obj; diff --git a/include/mempool.hh b/include/mempool.hh index fc3b45f43e881b4033879b9c82d1897541080f76..7badf79d71c3888f6fc3bbce0c8dfd9cbac9bf71 100644 --- a/include/mempool.hh +++ b/include/mempool.hh @@ -39,6 +39,7 @@ private: struct page_header; struct free_object; private: + bool have_full_pages(); void add_page(); static page_header* to_header(free_object* object);