summaryrefslogtreecommitdiff
path: root/AK
diff options
context:
space:
mode:
authorAli Mohammad Pur <ali.mpfard@gmail.com>2021-09-12 18:11:35 +0430
committerAli Mohammad Pur <Ali.mpfard@gmail.com>2021-09-13 14:38:53 +0430
commita72eea640850d27fa7aa47972ae4aa6f0cd2afcc (patch)
tree7591b61ee15a24289d83cc1a4c348144abab6c93 /AK
parente4b1c0b8b18b9b482676e26c6a68cd84127a69c7 (diff)
downloadserenity-a72eea640850d27fa7aa47972ae4aa6f0cd2afcc.zip
AK: Give BumpAllocator a single-block cache
This avoid excessive mmap/munmap traffic in normal operation.
Diffstat (limited to 'AK')
-rw-r--r--AK/BumpAllocator.h34
1 files changed, 24 insertions, 10 deletions
diff --git a/AK/BumpAllocator.h b/AK/BumpAllocator.h
index d78ed5e9ba..4c77b48386 100644
--- a/AK/BumpAllocator.h
+++ b/AK/BumpAllocator.h
@@ -62,6 +62,13 @@ public:
if (!m_head_chunk)
return;
for_each_chunk([this](auto chunk) {
+ if (!s_unused_allocation_cache) {
+ auto next_chunk = ((ChunkHeader const*)chunk)->next_chunk;
+ if (!next_chunk) {
+ s_unused_allocation_cache = chunk;
+ return;
+ }
+ }
if constexpr (use_mmap) {
munmap((void*)chunk, m_chunk_size);
} else {
@@ -91,18 +98,22 @@ protected:
// dbgln("Allocated {} entries in previous chunk and have {} unusable bytes", m_allocations_in_previous_chunk, m_chunk_size - m_byte_offset_into_current_chunk);
// m_allocations_in_previous_chunk = 0;
void* new_chunk;
- if constexpr (use_mmap) {
+ if (s_unused_allocation_cache) {
+ new_chunk = (void*)exchange(s_unused_allocation_cache, 0);
+ } else {
+ if constexpr (use_mmap) {
#ifdef __serenity__
- new_chunk = serenity_mmap(nullptr, m_chunk_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_RANDOMIZED | MAP_PRIVATE, 0, 0, m_chunk_size, "BumpAllocator Chunk");
+ new_chunk = serenity_mmap(nullptr, m_chunk_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_RANDOMIZED | MAP_PRIVATE, 0, 0, m_chunk_size, "BumpAllocator Chunk");
#else
- new_chunk = mmap(nullptr, m_chunk_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
+ new_chunk = mmap(nullptr, m_chunk_size, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, 0, 0);
#endif
- if (new_chunk == MAP_FAILED)
- return false;
- } else {
- new_chunk = kmalloc(m_chunk_size);
- if (!new_chunk)
- return false;
+ if (new_chunk == MAP_FAILED)
+ return false;
+ } else {
+ new_chunk = kmalloc(m_chunk_size);
+ if (!new_chunk)
+ return false;
+ }
}
auto& new_header = *(ChunkHeader*)new_chunk;
@@ -134,7 +145,7 @@ protected:
FlatPtr m_current_chunk { 0 };
size_t m_byte_offset_into_current_chunk { 0 };
size_t m_chunk_size { 0 };
- // size_t m_allocations_in_previous_chunk { 0 };
+ static FlatPtr s_unused_allocation_cache;
};
template<typename T, bool use_mmap = false, size_t chunk_size = use_mmap ? 4 * MiB : 4 * KiB>
@@ -172,6 +183,9 @@ public:
}
};
+template<bool use_mmap, size_t size>
+inline FlatPtr BumpAllocator<use_mmap, size>::s_unused_allocation_cache { 0 };
+
}
using AK::BumpAllocator;