mirror of
https://github.com/matrix-construct/construct
synced 2024-11-12 04:51:08 +01:00
ircd::allocator: Distill out GNU malloc featurette from allocator.cc unit.
This commit is contained in:
parent
ea0a1df3a1
commit
6a6c51d359
4 changed files with 180 additions and 217 deletions
|
@ -36,7 +36,7 @@ namespace ircd::allocator
|
||||||
profile operator+(const profile &, const profile &);
|
profile operator+(const profile &, const profile &);
|
||||||
profile operator-(const profile &, const profile &);
|
profile operator-(const profile &, const profile &);
|
||||||
|
|
||||||
bool trim(const size_t &pad = 0); // malloc_trim(3)
|
bool trim(const size_t &pad = 0) noexcept; // malloc_trim(3)
|
||||||
string_view info(const mutable_buffer &);
|
string_view info(const mutable_buffer &);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -111,6 +111,9 @@ struct ircd::allocator::scope
|
||||||
using realloc_closure = std::function<void *(void *const &ptr, const size_t &)>;
|
using realloc_closure = std::function<void *(void *const &ptr, const size_t &)>;
|
||||||
using free_closure = std::function<void (void *const &ptr)>;
|
using free_closure = std::function<void (void *const &ptr)>;
|
||||||
|
|
||||||
|
static void hook_init() noexcept;
|
||||||
|
static void hook_fini() noexcept;
|
||||||
|
|
||||||
static scope *current;
|
static scope *current;
|
||||||
scope *theirs;
|
scope *theirs;
|
||||||
alloc_closure user_alloc;
|
alloc_closure user_alloc;
|
||||||
|
|
|
@ -116,6 +116,7 @@ libircd_la_SOURCES =#
|
||||||
libircd_la_SOURCES += assert.cc
|
libircd_la_SOURCES += assert.cc
|
||||||
libircd_la_SOURCES += info.cc
|
libircd_la_SOURCES += info.cc
|
||||||
libircd_la_SOURCES += allocator.cc
|
libircd_la_SOURCES += allocator.cc
|
||||||
|
libircd_la_SOURCES += allocator_gnu.cc
|
||||||
libircd_la_SOURCES += vg.cc
|
libircd_la_SOURCES += vg.cc
|
||||||
libircd_la_SOURCES += exception.cc
|
libircd_la_SOURCES += exception.cc
|
||||||
libircd_la_SOURCES += util.cc
|
libircd_la_SOURCES += util.cc
|
||||||
|
|
|
@ -8,8 +8,6 @@
|
||||||
// copyright notice and this permission notice is present in all copies. The
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
// full license for this software is available in the LICENSE file.
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
#include <RB_INC_MALLOC_H
|
|
||||||
|
|
||||||
// Uncomment or -D this #define to enable our own crude but simple ability to
|
// Uncomment or -D this #define to enable our own crude but simple ability to
|
||||||
// profile dynamic memory usage. Global `new` and `delete` will be captured
|
// profile dynamic memory usage. Global `new` and `delete` will be captured
|
||||||
// here by this definition file into thread_local counters accessible via
|
// here by this definition file into thread_local counters accessible via
|
||||||
|
@ -18,54 +16,20 @@
|
||||||
//
|
//
|
||||||
// #define RB_PROF_ALLOC
|
// #define RB_PROF_ALLOC
|
||||||
|
|
||||||
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
|
|
||||||
ircd::string_view
|
|
||||||
ircd::allocator::info(const mutable_buffer &buf)
|
|
||||||
{
|
|
||||||
std::stringstream out;
|
|
||||||
pubsetbuf(out, buf);
|
|
||||||
|
|
||||||
const auto ma
|
|
||||||
{
|
|
||||||
::mallinfo()
|
|
||||||
};
|
|
||||||
|
|
||||||
char pbuf[96];
|
|
||||||
out << "arena: " << pretty(pbuf, iec(ma.arena)) << std::endl
|
|
||||||
<< "ordblks: " << ma.ordblks << std::endl
|
|
||||||
<< "smblks: " << ma.smblks << std::endl
|
|
||||||
<< "hblks: " << ma.hblks << std::endl
|
|
||||||
<< "hblkhd: " << pretty(pbuf, iec(ma.hblkhd)) << std::endl
|
|
||||||
<< "usmblks: " << pretty(pbuf, iec(ma.usmblks)) << std::endl
|
|
||||||
<< "fsmblks: " << pretty(pbuf, iec(ma.fsmblks)) << std::endl
|
|
||||||
<< "uordblks: " << pretty(pbuf, iec(ma.uordblks)) << std::endl
|
|
||||||
<< "fordblks: " << pretty(pbuf, iec(ma.fordblks)) << std::endl
|
|
||||||
<< "keepcost: " << pretty(pbuf, iec(ma.keepcost)) << std::endl
|
|
||||||
;
|
|
||||||
|
|
||||||
return view(out, buf);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
ircd::string_view
|
ircd::string_view
|
||||||
|
__attribute__((weak))
|
||||||
ircd::allocator::info(const mutable_buffer &buf)
|
ircd::allocator::info(const mutable_buffer &buf)
|
||||||
{
|
{
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
|
|
||||||
bool
|
|
||||||
ircd::allocator::trim(const size_t &pad)
|
|
||||||
{
|
|
||||||
return malloc_trim(pad);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
bool
|
bool
|
||||||
|
__attribute__((weak))
|
||||||
ircd::allocator::trim(const size_t &pad)
|
ircd::allocator::trim(const size_t &pad)
|
||||||
|
noexcept
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// allocator::state
|
// allocator::state
|
||||||
|
@ -155,24 +119,6 @@ const
|
||||||
// allocator::scope
|
// allocator::scope
|
||||||
//
|
//
|
||||||
|
|
||||||
namespace ircd::allocator
|
|
||||||
{
|
|
||||||
void *(*their_malloc_hook)(size_t, const void *);
|
|
||||||
static void *malloc_hook(size_t, const void *);
|
|
||||||
static void install_malloc_hook();
|
|
||||||
static void uninstall_malloc_hook();
|
|
||||||
|
|
||||||
void *(*their_realloc_hook)(void *, size_t, const void *);
|
|
||||||
static void *realloc_hook(void *, size_t, const void *);
|
|
||||||
static void install_realloc_hook();
|
|
||||||
static void uninstall_realloc_hook();
|
|
||||||
|
|
||||||
void (*their_free_hook)(void *, const void *);
|
|
||||||
static void free_hook(void *, const void *);
|
|
||||||
static void install_free_hook();
|
|
||||||
static void uninstall_free_hook();
|
|
||||||
}
|
|
||||||
|
|
||||||
decltype(ircd::allocator::scope::current)
|
decltype(ircd::allocator::scope::current)
|
||||||
ircd::allocator::scope::current;
|
ircd::allocator::scope::current;
|
||||||
|
|
||||||
|
@ -201,11 +147,7 @@ ircd::allocator::scope::scope(alloc_closure ac,
|
||||||
// our global hook handlers at the first instance ctor and
|
// our global hook handlers at the first instance ctor and
|
||||||
// uninstall it after that first instance dtors.
|
// uninstall it after that first instance dtors.
|
||||||
if(!current)
|
if(!current)
|
||||||
{
|
hook_init();
|
||||||
install_malloc_hook();
|
|
||||||
install_realloc_hook();
|
|
||||||
install_free_hook();
|
|
||||||
}
|
|
||||||
|
|
||||||
current = this;
|
current = this;
|
||||||
}
|
}
|
||||||
|
@ -220,169 +162,22 @@ noexcept
|
||||||
// has destructed (the first to have constructed). We know this when
|
// has destructed (the first to have constructed). We know this when
|
||||||
// current becomes null.
|
// current becomes null.
|
||||||
if(!current)
|
if(!current)
|
||||||
{
|
hook_fini();
|
||||||
uninstall_malloc_hook();
|
|
||||||
uninstall_realloc_hook();
|
|
||||||
uninstall_free_hook();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ircd::allocator::free_hook(void *const ptr,
|
__attribute__((weak))
|
||||||
const void *const caller)
|
ircd::allocator::scope::hook_init()
|
||||||
|
noexcept
|
||||||
{
|
{
|
||||||
// Once we've hooked we put back their hook before calling the user
|
|
||||||
// so they can passthru to the function without hooking themselves.
|
|
||||||
uninstall_free_hook();
|
|
||||||
const unwind rehook_ours
|
|
||||||
{
|
|
||||||
install_free_hook
|
|
||||||
};
|
|
||||||
|
|
||||||
assert(scope::current);
|
|
||||||
if(scope::current->user_free)
|
|
||||||
scope::current->user_free(ptr);
|
|
||||||
else
|
|
||||||
::free(ptr);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void *
|
|
||||||
ircd::allocator::realloc_hook(void *const ptr,
|
|
||||||
size_t size,
|
|
||||||
const void *const caller)
|
|
||||||
{
|
|
||||||
// Once we've hooked we put back their hook before calling the user
|
|
||||||
// so they can passthru to the function without hooking themselves.
|
|
||||||
uninstall_realloc_hook();
|
|
||||||
const unwind rehook_ours
|
|
||||||
{
|
|
||||||
install_realloc_hook
|
|
||||||
};
|
|
||||||
|
|
||||||
assert(scope::current);
|
|
||||||
return scope::current->user_realloc?
|
|
||||||
scope::current->user_realloc(ptr, size):
|
|
||||||
::realloc(ptr, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
void *
|
|
||||||
ircd::allocator::malloc_hook(size_t size,
|
|
||||||
const void *const caller)
|
|
||||||
{
|
|
||||||
// Once we've hooked we put back their hook before calling the user
|
|
||||||
// so they can passthru to the function without hooking themselves.
|
|
||||||
uninstall_malloc_hook();
|
|
||||||
const unwind rehook_ours
|
|
||||||
{
|
|
||||||
install_malloc_hook
|
|
||||||
};
|
|
||||||
|
|
||||||
assert(scope::current);
|
|
||||||
return scope::current->user_alloc?
|
|
||||||
scope::current->user_alloc(size):
|
|
||||||
::malloc(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
void
|
void
|
||||||
ircd::allocator::install_malloc_hook()
|
__attribute__((weak))
|
||||||
{
|
ircd::allocator::scope::hook_fini()
|
||||||
assert(!their_malloc_hook);
|
noexcept
|
||||||
their_malloc_hook = __malloc_hook;
|
|
||||||
__malloc_hook = malloc_hook;
|
|
||||||
}
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#else
|
|
||||||
void
|
|
||||||
ircd::allocator::install_malloc_hook()
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
void
|
|
||||||
ircd::allocator::uninstall_malloc_hook()
|
|
||||||
{
|
|
||||||
__malloc_hook = their_malloc_hook;
|
|
||||||
}
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#else
|
|
||||||
void
|
|
||||||
ircd::allocator::uninstall_malloc_hook()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
void
|
|
||||||
ircd::allocator::install_realloc_hook()
|
|
||||||
{
|
|
||||||
assert(!their_realloc_hook);
|
|
||||||
their_realloc_hook = __realloc_hook;
|
|
||||||
__realloc_hook = realloc_hook;
|
|
||||||
}
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#else
|
|
||||||
void
|
|
||||||
ircd::allocator::install_realloc_hook()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
void
|
|
||||||
ircd::allocator::uninstall_realloc_hook()
|
|
||||||
{
|
|
||||||
__realloc_hook = their_realloc_hook;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
void
|
|
||||||
ircd::allocator::uninstall_realloc_hook()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
void
|
|
||||||
ircd::allocator::install_free_hook()
|
|
||||||
{
|
|
||||||
assert(!their_free_hook);
|
|
||||||
their_free_hook = __free_hook;
|
|
||||||
__free_hook = free_hook;
|
|
||||||
}
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#else
|
|
||||||
void
|
|
||||||
ircd::allocator::install_free_hook()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
|
|
||||||
#pragma GCC diagnostic push
|
|
||||||
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
|
||||||
void
|
|
||||||
ircd::allocator::uninstall_free_hook()
|
|
||||||
{
|
|
||||||
__free_hook = their_free_hook;
|
|
||||||
}
|
|
||||||
#pragma GCC diagnostic pop
|
|
||||||
#else
|
|
||||||
void
|
|
||||||
ircd::allocator::uninstall_free_hook()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// allocator::profile
|
// allocator::profile
|
||||||
|
|
164
ircd/allocator_gnu.cc
Normal file
164
ircd/allocator_gnu.cc
Normal file
|
@ -0,0 +1,164 @@
|
||||||
|
// Matrix Construct
|
||||||
|
//
|
||||||
|
// Copyright (C) Matrix Construct Developers, Authors & Contributors
|
||||||
|
// Copyright (C) 2016-2018 Jason Volk <jason@zemos.net>
|
||||||
|
//
|
||||||
|
// Permission to use, copy, modify, and/or distribute this software for any
|
||||||
|
// purpose with or without fee is hereby granted, provided that the above
|
||||||
|
// copyright notice and this permission notice is present in all copies. The
|
||||||
|
// full license for this software is available in the LICENSE file.
|
||||||
|
|
||||||
|
#include <RB_INC_MALLOC_H
|
||||||
|
|
||||||
|
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H) && defined(IRCD_ALLOCATOR_USE_DEFAULT)
|
||||||
|
#define IRCD_ALLOCATOR_USE_GNU
|
||||||
|
#endif
|
||||||
|
|
||||||
|
namespace ircd::allocator
|
||||||
|
{
|
||||||
|
void *(*their_malloc_hook)(size_t, const void *);
|
||||||
|
static void *malloc_hook(size_t, const void *);
|
||||||
|
static void install_malloc_hook();
|
||||||
|
static void uninstall_malloc_hook();
|
||||||
|
|
||||||
|
void *(*their_realloc_hook)(void *, size_t, const void *);
|
||||||
|
static void *realloc_hook(void *, size_t, const void *);
|
||||||
|
static void install_realloc_hook();
|
||||||
|
static void uninstall_realloc_hook();
|
||||||
|
|
||||||
|
void (*their_free_hook)(void *, const void *);
|
||||||
|
static void free_hook(void *, const void *);
|
||||||
|
static void install_free_hook();
|
||||||
|
static void uninstall_free_hook();
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef IRCD_ALLOCATOR_USE_GNU
|
||||||
|
ircd::string_view
|
||||||
|
ircd::allocator::info(const mutable_buffer &buf)
|
||||||
|
{
|
||||||
|
std::stringstream out;
|
||||||
|
pubsetbuf(out, buf);
|
||||||
|
|
||||||
|
const auto ma
|
||||||
|
{
|
||||||
|
::mallinfo()
|
||||||
|
};
|
||||||
|
|
||||||
|
char pbuf[96];
|
||||||
|
out << "arena: " << pretty(pbuf, iec(ma.arena)) << std::endl
|
||||||
|
<< "ordblks: " << ma.ordblks << std::endl
|
||||||
|
<< "smblks: " << ma.smblks << std::endl
|
||||||
|
<< "hblks: " << ma.hblks << std::endl
|
||||||
|
<< "hblkhd: " << pretty(pbuf, iec(ma.hblkhd)) << std::endl
|
||||||
|
<< "usmblks: " << pretty(pbuf, iec(ma.usmblks)) << std::endl
|
||||||
|
<< "fsmblks: " << pretty(pbuf, iec(ma.fsmblks)) << std::endl
|
||||||
|
<< "uordblks: " << pretty(pbuf, iec(ma.uordblks)) << std::endl
|
||||||
|
<< "fordblks: " << pretty(pbuf, iec(ma.fordblks)) << std::endl
|
||||||
|
<< "keepcost: " << pretty(pbuf, iec(ma.keepcost)) << std::endl
|
||||||
|
;
|
||||||
|
|
||||||
|
return view(out, buf);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IRCD_ALLOCATOR_USE_GNU
|
||||||
|
bool
|
||||||
|
ircd::allocator::trim(const size_t &pad)
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
return malloc_trim(pad);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IRCD_ALLOCATOR_USE_GNU
|
||||||
|
void
|
||||||
|
ircd::allocator::scope::hook_init()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
install_malloc_hook();
|
||||||
|
install_realloc_hook();
|
||||||
|
install_free_hook();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef IRCD_ALLOCATOR_USE_GNU
|
||||||
|
void
|
||||||
|
ircd::allocator::scope::hook_fini()
|
||||||
|
noexcept
|
||||||
|
{
|
||||||
|
uninstall_malloc_hook();
|
||||||
|
uninstall_realloc_hook();
|
||||||
|
uninstall_free_hook();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
void
|
||||||
|
ircd::allocator::install_malloc_hook()
|
||||||
|
{
|
||||||
|
assert(!their_malloc_hook);
|
||||||
|
their_malloc_hook = __malloc_hook;
|
||||||
|
__malloc_hook = malloc_hook;
|
||||||
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
void
|
||||||
|
ircd::allocator::uninstall_malloc_hook()
|
||||||
|
{
|
||||||
|
__malloc_hook = their_malloc_hook;
|
||||||
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
void
|
||||||
|
ircd::allocator::install_realloc_hook()
|
||||||
|
{
|
||||||
|
assert(!their_realloc_hook);
|
||||||
|
their_realloc_hook = __realloc_hook;
|
||||||
|
__realloc_hook = realloc_hook;
|
||||||
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
void
|
||||||
|
ircd::allocator::uninstall_realloc_hook()
|
||||||
|
{
|
||||||
|
__realloc_hook = their_realloc_hook;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
void
|
||||||
|
ircd::allocator::install_free_hook()
|
||||||
|
{
|
||||||
|
assert(!their_free_hook);
|
||||||
|
their_free_hook = __free_hook;
|
||||||
|
__free_hook = free_hook;
|
||||||
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
|
||||||
|
#pragma GCC diagnostic push
|
||||||
|
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
|
||||||
|
void
|
||||||
|
ircd::allocator::uninstall_free_hook()
|
||||||
|
{
|
||||||
|
__free_hook = their_free_hook;
|
||||||
|
}
|
||||||
|
#pragma GCC diagnostic pop
|
||||||
|
#endif
|
Loading…
Reference in a new issue