construct/ircd/allocator_gnu.cc

181 lines
4.7 KiB
C++

// 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
// In case these declarations are missing in <malloc.h>
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
extern "C" void *(*__MALLOC_HOOK_VOLATILE __malloc_hook)(size_t, const void *);
extern "C" void *(*__MALLOC_HOOK_VOLATILE __realloc_hook)(void *, size_t, const void *);
extern "C" void (*__MALLOC_HOOK_VOLATILE __free_hook)(void *, const void *);
#endif
#if defined(__GNU_LIBRARY__) && defined(HAVE_MALLOC_H)
namespace ircd::allocator
{
static decltype(__malloc_hook) their_malloc_hook;
[[gnu::weak]] void *malloc_hook(size_t, const void *);
static void install_malloc_hook();
static void uninstall_malloc_hook();
static decltype(__realloc_hook) their_realloc_hook;
[[gnu::weak]] void *realloc_hook(void *, size_t, const void *);
static void install_realloc_hook();
static void uninstall_realloc_hook();
static decltype(__free_hook) their_free_hook;
[[gnu::weak]] void free_hook(void *, const void *);
static void install_free_hook();
static void uninstall_free_hook();
}
#endif
#ifdef IRCD_ALLOCATOR_USE_GNU
ircd::string_view
ircd::allocator::info(const mutable_buffer &buf,
[[unused]] const string_view &opts)
{
std::stringstream out;
pubsetbuf(out, buf);
const auto ma
{
#if defined(HAVE_MALLINFO2)
::mallinfo2()
#elif defined(HAVE_MALLINFO)
::mallinfo2()
#else
#error "Missing mallinfo(3)."
#endif
};
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