mirror of
https://github.com/Icinga/icinga2.git
synced 2025-12-16 10:14:18 +01:00
Introduce DefragAllocator
This commit is contained in:
parent
7a21001d6d
commit
97eda30f86
@ -14,7 +14,7 @@ mkclass_target(sysloglogger.ti sysloglogger-ti.cpp sysloglogger-ti.hpp)
|
||||
|
||||
set(base_SOURCES
|
||||
i2-base.hpp
|
||||
allocator.cpp
|
||||
allocator.cpp allocator.hpp
|
||||
application.cpp application.hpp application-ti.hpp application-version.cpp application-environment.cpp
|
||||
array.cpp array.hpp array-script.cpp
|
||||
atomic.hpp
|
||||
|
||||
@ -2,19 +2,99 @@
|
||||
|
||||
#ifndef _WIN32
|
||||
|
||||
#include "base/allocator.hpp"
|
||||
#include <algorithm>
|
||||
#include <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
#include <dlfcn.h>
|
||||
#include <sys/mman.h>
|
||||
#include <unistd.h>
|
||||
|
||||
using namespace icinga;
|
||||
|
||||
struct DAPage
|
||||
{
|
||||
size_t TotalSize = sizeof(DAPage);
|
||||
DAPage* Next = nullptr;
|
||||
max_align_t* MemoryBegin = nullptr;
|
||||
max_align_t* MemoryEnd = nullptr;
|
||||
max_align_t Memory[1] = {};
|
||||
};
|
||||
|
||||
static thread_local struct {
|
||||
unsigned int InUse = 0;
|
||||
DAPage* TopPage = nullptr;
|
||||
} l_DefragAllocator;
|
||||
|
||||
extern "C" void* malloc(size_t bytes)
|
||||
{
|
||||
static const auto libcMalloc = (void*(*)(size_t))dlsym(RTLD_NEXT, "malloc");
|
||||
return libcMalloc(bytes);
|
||||
static const size_t pageSize = std::max(128L * 1024L, sysconf(_SC_PAGESIZE));
|
||||
|
||||
if (BOOST_LIKELY(!l_DefragAllocator.InUse)) {
|
||||
return libcMalloc(bytes);
|
||||
}
|
||||
|
||||
if (BOOST_UNLIKELY(!bytes)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto chunks ((bytes + sizeof(max_align_t) - 1u) / sizeof(max_align_t));
|
||||
|
||||
if (BOOST_UNLIKELY(!l_DefragAllocator.TopPage || l_DefragAllocator.TopPage->MemoryEnd - l_DefragAllocator.TopPage->MemoryBegin < chunks)) {
|
||||
auto total ((sizeof(DAPage) + sizeof(max_align_t) * (chunks - 1u) + pageSize - 1u) / pageSize * pageSize);
|
||||
|
||||
auto nextPage (mmap(nullptr, total, PROT_READ | PROT_WRITE, MAP_ANONYMOUS
|
||||
#ifdef MAP_HASSEMAPHORE
|
||||
| MAP_HASSEMAPHORE
|
||||
#endif
|
||||
| MAP_PRIVATE, -1, 0));
|
||||
|
||||
if (BOOST_UNLIKELY(nextPage == MAP_FAILED)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto p ((DAPage*)nextPage);
|
||||
|
||||
p->TotalSize = total;
|
||||
p->Next = l_DefragAllocator.TopPage;
|
||||
p->MemoryBegin = p->Memory;
|
||||
p->MemoryEnd = p->MemoryBegin + chunks;
|
||||
|
||||
l_DefragAllocator.TopPage = p;
|
||||
}
|
||||
|
||||
auto memory ((void*)l_DefragAllocator.TopPage->MemoryBegin);
|
||||
|
||||
l_DefragAllocator.TopPage->MemoryBegin += chunks;
|
||||
|
||||
return memory;
|
||||
}
|
||||
|
||||
extern "C" void free(void* memory)
|
||||
{
|
||||
static const auto libcFree = (void(*)(void*))dlsym(RTLD_NEXT, "free");
|
||||
libcFree(memory);
|
||||
|
||||
if (BOOST_LIKELY(!l_DefragAllocator.InUse)) {
|
||||
libcFree(memory);
|
||||
}
|
||||
}
|
||||
|
||||
DefragAllocator::DefragAllocator()
|
||||
{
|
||||
++l_DefragAllocator.InUse;
|
||||
}
|
||||
|
||||
DefragAllocator::~DefragAllocator()
|
||||
{
|
||||
if (!--l_DefragAllocator.InUse) {
|
||||
while (l_DefragAllocator.TopPage) {
|
||||
auto next (l_DefragAllocator.TopPage->Next);
|
||||
|
||||
munmap(l_DefragAllocator.TopPage, l_DefragAllocator.TopPage->TotalSize);
|
||||
l_DefragAllocator.TopPage = next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
||||
24
lib/base/allocator.hpp
Normal file
24
lib/base/allocator.hpp
Normal file
@ -0,0 +1,24 @@
|
||||
/* Icinga 2 | (c) 2023 Icinga GmbH | GPLv2+ */
|
||||
|
||||
#pragma once
|
||||
|
||||
namespace icinga
|
||||
{
|
||||
|
||||
/**
|
||||
* TODO
|
||||
*
|
||||
* @ingroup base
|
||||
*/
|
||||
class DefragAllocator
|
||||
{
|
||||
public:
|
||||
DefragAllocator();
|
||||
DefragAllocator(const DefragAllocator&) = delete;
|
||||
DefragAllocator(DefragAllocator&&) = delete;
|
||||
DefragAllocator& operator=(const DefragAllocator&) = delete;
|
||||
DefragAllocator& operator=(DefragAllocator&&) = delete;
|
||||
~DefragAllocator();
|
||||
};
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user