// Matrix Construct // // Copyright (C) Matrix Construct Developers, Authors & Contributors // Copyright (C) 2016-2018 Jason Volk // // 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 #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