28#include "ipc/shm/arena_lend/owner_shm_pool_collection.hpp"
32#include "ipc/shm/arena_lend/shm_pool_offset_ptr.hpp"
43#include <flow/log/log.hpp>
44#include <flow/util/util.hpp>
45#include <boost/interprocess/exceptions.hpp>
46#include <unordered_map>
176 public std::enable_shared_from_this<Ipc_arena>
187 template<
typename Po
inted_type>
205 template<
typename Po
inted_type>
282 static std::shared_ptr<Ipc_arena>
create(flow::log::Logger* logger,
283 const std::shared_ptr<Memory_manager>& memory_manager,
396 template<
typename T,
typename... Ctor_args>
783#ifdef IPC_DOXYGEN_ONLY
803 const std::shared_ptr<Memory_manager>& memory_manager,
870 void on_shm_pool_removed(
const std::shared_ptr<Shm_pool>& shm_pool,
bool removed_shared_memory)
override;
902 void*
create_shm_pool(
void* address,
size_t size,
size_t alignment,
bool* zero,
1007 size_t size_b,
bool committed,
arena_id_t arena_id);
1027 const void* address_b,
size_t size_b,
1035 template<
typename Base_t>
1047 using Mutex = flow::util::Mutex_non_recursive;
1049 using Lock = flow::util::Lock_guard<Mutex>;
1137 std::shared_ptr<Shm_pool>& pool,
size_t& pool_offset)
const;
1160 size_t size,
size_t alignment,
1161 bool* zero,
bool* commit,
unsigned arena_id);
1180 size_t size,
bool committed,
unsigned arena_id);
1198 size_t size,
bool committed,
unsigned arena_id);
1219 size_t size,
size_t offset,
1220 size_t length,
unsigned arena_id);
1241 size_t size,
size_t offset,
1242 size_t length,
unsigned arena_id);
1263 size_t size,
size_t offset,
1264 size_t length,
unsigned arena_id);
1287 size_t size,
size_t size_a,
size_t size_b,
1288 bool committed,
unsigned arena_id);
1311 void* address_a,
size_t size_a,
1312 void* address_b,
size_t size_b,
1313 bool committed,
unsigned arena_id);
1504template<
typename T,
typename... Ctor_args>
1511 using Bipc_bad_alloc = ::ipc::bipc::bad_alloc;
1512 using Std_bad_alloc = std::bad_alloc;
1514 constexpr bool HAS_TRIVIAL_DTOR = std::is_trivially_destructible_v<T>;
1516 static_assert(
alignof(T) <= flow::util::max_align_sz(),
1517 "allocate() guarantees only std::max_align_t alignment; over-aligned T is not supported.");
1519 Thread_lcl_obj_db_admin<Ipc_arena>::this_thread_piggy_scan();
1522 void*
const addr =
allocate(
sizeof(T));
1534 const auto obj =
static_cast<T*
>(addr);
1537 if constexpr(HAS_TRIVIAL_DTOR)
1539 flow::util::construct_at(obj, std::forward<Ctor_args>(ctor_args)...);
1544 flow::util::construct_at(obj, std::forward<Ctor_args>(ctor_args)...);
1561 const auto gc_func = [](
void* addr,
Ipc_arena* arena)
1563 if constexpr(!HAS_TRIVIAL_DTOR)
1575 static_cast<T*
>(addr)->~T();
1579 arena->deallocate(addr);
1598 "jemalloc::Ipc_arena::construct():->constructing_obj():likely-aux-pool-creation",
1603 Thread_lcl_obj_db_admin<Ipc_arena>::this_thread_obj_db()
1607 catch (
const Bipc_bad_alloc&)
1616 FLOW_LOG_WARNING(
"In construct<T>() successfully allocated/constructed the T (type "
1617 "[" <<
typeid(T).name() <<
"]), but the cross-process-GC hookup step then "
1618 "threw bipc::bad_alloc (there may be a WARNING with details ahead of this message); "
1619 "throwing as std::bad_alloc. (Probably this thread's per-arena (collection/arena ID "
1620 "[" << get_id() <<
"]) aux-SHM-pool ran out of space which would indicate a massive "
1621 "number of live construct()ed objects; WARNING above may confirm.)");
1623 throw Std_bad_alloc{};
1632 gc_func(addr,
this);
1646 return Handle<T>{obj, Disposer{shared_from_this(), lend_tracker_pool_id, use_ct_idx}};
(Internal-use) Thread_lcl_obj_db_admin<A>::this_thread_obj_db() is the current thread's module that t...
Represents/manages a segregated collection of in-SHM (shared memory) objects and buffers allocated us...
arena_id_t m_arena0
The first (and for now only, in practice) arena-ID in m_arenas. Used for perf between start() and des...
bool compute_pool_and_offset(void *address, size_t size, size_t offset, size_t length, util::String_view use_case, std::shared_ptr< Shm_pool > &pool, size_t &pool_offset) const
Extent hook impl helper for certain extent hooks: given a jemalloc extent at address of size bytes,...
bool add_shm_pool_listener(Owner_shm_pool_listener *listener)
(Internal-use) Adds a listener to get updates on shared memory pools.
void destroy()
Important helper synchronously invoked, in lieu of delete arena, when the create()-returned shared_pt...
arena_id_t create_jemalloc_arena()
start_impl() helper: creates one jemalloc-arena, wired to our extent hooks, and applies the per-arena...
void sample_hi_wmarks()
Internally samples certain stats so as to update _hi_wmarks that are computed at stat-consume time as...
void start_impl(unsigned int n_arenas)
start() helper.
void pool_stats_reset()
Resets pool_stats(). The formal meaning of a reset is discussed in flow::util::stat doc header.
static void this_thread_gc()
Synchronously garbage-collects, in the calling thread, any objects x = A.construct()ed by this thread...
Uniq_arena_id uniq_arena_id() const
Returns the stat::Uniq_arena_id (owner-process PID + collection-ID) identifying *this arena; used by ...
flow::util::Mutex_non_recursive Mutex
Single-reader, single-writer mutex.
Extent_hooks m_extent_hooks_wrapper
The callback functions for jemalloc. Contains the jemalloc extent-hook table + a pointer back to *thi...
std::map< arena_id_t, Memory_manager_stats > m_mem_mgr_base_stats
Per-native-arena reset-state ("base") for memory_manager_stats() / memory_manager_stats_reset(): for ...
bool decommit_memory_pages(void *address, size_t size, size_t offset, size_t length, arena_id_t arena_id)
jemalloc extent hook impl.
Obj_handle< Pointed_type > Handle
First-class handle – a shared_ptr of some kind by definition – to objects construct<>()ed by this are...
static bool merge_memory_pages_handler(extent_hooks_t *extent_hooks, void *address_a, size_t size_a, void *address_b, size_t size_b, bool committed, unsigned arena_id)
jemalloc extent hook impl: forwards to similarly named member function of the proper this (which is s...
std::set< std::shared_ptr< Shm_pool > > m_shm_pools
Collection of created SHM-pools.
std::vector< Shm_pool_info > shm_pool_live_info() const
For informational/stats-adjacent purposes, returns information on currently live SHM-pools within *th...
bool remove_shm_pool(void *address, size_t size, bool committed, arena_id_t arena_id)
jemalloc extent hook impl.
void * allocate(size_t size)
Performs a non-garbage-collected allocation of a buffer in SHM.
Mutex m_shm_pools_and_listeners_mutex
Protects access to m_shm_pools and m_listeners.
void on_shm_pool_removed(const std::shared_ptr< Shm_pool > &shm_pool, bool removed_shared_memory) override
Implements super-class API: forwards to handle_created_shm_pool().
static const Obj_db_aux_pool_global_stats & obj_db_aux_pool_global_stats()
Like owner_pool_lookup_global_stats() but returns the process-global stat-set stat::Obj_db_aux_pool_g...
bool purge_forced_memory_pages(void *address, size_t size, size_t offset, size_t length, arena_id_t arena_id)
jemalloc extent hook impl.
static std::shared_ptr< Ipc_arena > create(flow::log::Logger *logger, const std::shared_ptr< Memory_manager > &memory_manager, Shared_name &&pool_name_base, const util::Permissions &permissions)
Creates an instance of this class, factory-style.
void sharded_stats_reset()
Resets sharded_stats(). The formal meaning of a reset is discussed in flow::util::stat doc header.
static void * create_shm_pool_handler(extent_hooks_t *extent_hooks, void *address, size_t size, size_t alignment, bool *zero, bool *commit, unsigned arena_id)
jemalloc extent hook impl: forwards to similarly named member function of the proper this (which is s...
void * allocate_impl(size_t size)
Helper core of allocate() that, in reaction to jemalloc-allocate failure, simply returns null (no fur...
static std::atomic< collection_id_t > m_collection_id_counter
The monotonically increasing collection (arena ID).
static bool split_memory_pages_handler(extent_hooks_t *extent_hooks, void *address, size_t size, size_t size_a, size_t size_b, bool committed, unsigned arena_id)
jemalloc extent hook impl: forwards to similarly named member function of the proper this (which is s...
Mutex m_sharded_stats_mutex
Protects m_sharded_stats, so that sharded_stats() and sharded_stats_reset() can be thread-safe as adv...
void on_shm_pool_created(const std::shared_ptr< Shm_pool > &shm_pool) override
Implements super-class API.
void memory_manager_snapshot_read(std::vector< Memory_manager_stats > *rows) const
Reads the raw jemalloc-sourced stat-members – the m_vaddr and m_alloc sub-groups – of each (*rows)[id...
bool merge_memory_pages(const void *address_a, size_t size_a, const void *address_b, size_t size_b, bool committed, arena_id_t arena_id)
jemalloc extent hook impl.
uint64_t m_owner_id
Owner (this) process's PID, captured at construction; the first half of uniq_arena_id().
void memory_manager_stats_reset()
Resets memory_manager_stats().
std::set< arena_id_t > m_arenas
The segregated memory areas. Empty until start(); non-empty and unchanging thereafter.
void start()
Creates the jemalloc arena; create() calls it, once, immediately upon construction; and nothing else ...
void memory_manager_vaddr_stats_read(arena_id_t arena_id, Memory_manager_stats::Vaddr *vaddr) const
Helper that for the given jemalloc-arena arena_id reads the values into stat::Memory_manager_stats::V...
std::atomic< bool > m_destroy_started
Start at false; at some point in the destroy() flow becomes true to prevent event listeners from firi...
void this_thread_ensure_tcache_exists() const
Ensures the calling thread has a jemalloc tcache for *this arena, creating it if needed – making subs...
void memory_manager_alloc_stats_read(arena_id_t arena_id, Memory_manager_stats::Alloc *alloc) const
Similar to memory_manager_vaddr_stats_read() but applied to stat::Memory_manager_stats::Alloc group.
const std::shared_ptr< Memory_manager > m_memory_manager
The jemalloc memory manager given to create().
static void global_stats_reset()
Resets owner_pool_lookup_global_stats() and obj_db_aux_pool_global_stats().
static bool commit_memory_pages_handler(extent_hooks_t *extent_hooks, void *address, size_t size, size_t offset, size_t length, unsigned arena_id)
jemalloc extent hook impl: forwards to similarly named member function of the proper this (which is s...
std::set< Owner_shm_pool_listener * > m_listeners
The SHM pool listeners, each to be informed of relevant events (basically: pool(s) added,...
static void remove_shm_pool_handler(extent_hooks_t *extent_hooks, void *address, size_t size, bool committed, unsigned arena_id)
jemalloc extent hook impl: forwards to similarly named member function of the proper this (which is s...
static bool purge_forced_memory_pages_handler(extent_hooks_t *extent_hooks, void *address, size_t size, size_t offset, size_t length, unsigned arena_id)
jemalloc extent hook impl: forwards to similarly named member function of the proper this (which is s...
Sharded_stats m_sharded_stats
The stats for *this arena that are in the stat-collection purview of detail::Thread_lcl_obj_db_admin ...
Ipc_arena(flow::log::Logger *logger, const std::shared_ptr< Memory_manager > &memory_manager, Shared_name &&pool_name_base, const util::Permissions &permissions)
Constructor.
std::vector< Memory_manager_stats > memory_manager_stats()
Returns the memory-manager-level statistics – one stat::Memory_manager_stats per native (jemalloc) ar...
flow::util::Lock_guard< Mutex > Lock
Exclusive lock for the mutex.
arena_id_t get_jemalloc_arena_id() const
Returns the jemalloc-ID for the (only, as of this writing) jemalloc-arena maintained by *this; this i...
bool remove_shm_pool_listener(Owner_shm_pool_listener *listener)
(Internal-use) Removes a listener from getting further updates on shared memory pools.
static const Owner_pool_lookup_global_stats & owner_pool_lookup_global_stats()
Returns the process-global owner-side stat-set stat::Owner_pool_lookup_global_stats,...
Handle< T > construct(Ctor_args &&... ctor_args)
allocate()s sizeof(T) bytes (in SHM), invokes T{...} ctor with the given args, and returns a ref-coun...
static bool optional_remove_shm_pool_handler(extent_hooks_t *extent_hooks, void *address, size_t size, bool committed, unsigned arena_id)
jemalloc extent hook impl: forwards to similarly named member function of the proper this (which is s...
bool split_memory_pages(const void *address, size_t size, size_t size_a, size_t size_b, bool committed, arena_id_t arena_id)
jemalloc extent hook impl.
Pool_stats m_pool_stats
For *this arena, the non-sharded, non-jemalloc-sourced stats, bundled into stat::Pool_stats.
const std::shared_ptr< Memory_manager > & get_jemalloc_memory_manager() const
Returns the memory manager.
void info_dump(Info_dump *target_info_dump)
Fills-out the stats/info contents of the given stat::Arena_info_dump: a printable bundling of stats/i...
void * create_shm_pool(void *address, size_t size, size_t alignment, bool *zero, bool *commit, arena_id_t arena_id)
Creates a shared memory pool (jemalloc extent hook).
void destroy_on_obj_db_forgot_us(const flow::log::Log_context_mt *log_ctx)
destroy() helper; handles the steps that remain once the possibly-async forgetting_shm_arena() finish...
static bool decommit_memory_pages_handler(extent_hooks_t *extent_hooks, void *address, size_t size, size_t offset, size_t length, unsigned arena_id)
jemalloc extent hook impl: forwards to similarly named member function of the proper this (which is s...
const Pool_stats & pool_stats() const
Returns the stat-set stat::Pool_stats for *this arena – the arena's non-sharded SHM-pool stats (obj-D...
void deallocate(void *address) noexcept
Undoes allocate(): deallocates a previously allocated, by this arena, buffer in SHM.
void sharded_stats(Sharded_stats *target_stats)
Outputs the stat-set stat::Sharded_stats for *this arena.
bool commit_memory_pages(void *address, size_t size, size_t offset, size_t length, arena_id_t arena_id)
jemalloc extent hook impl.
bool optional_remove_shm_pool(void *address, size_t size, bool committed, arena_id_t arena_id)
jemalloc extent hook impl.
Shm_pool::pool_id_t pool_id_t
Short-hand for pool ID type.
RAII-style class operating a stack-like notion of the given thread's currently active SHM-aware Arena...
Stateless allocator usable with STL-compliant containers to store (or merely read) them directly in S...
String-wrapping abstraction representing a name uniquely distinguishing a kernel-persistent entity fr...
arena_lend::stat::Sharded_stats Sharded_stats
Short-hand for brevity: Thread_lcl_obj_db_* and buddies make frequent mention of this.
uint32_t pool_id_t
Pool ID type.
uint32_t use_ct_idx_t
Index into a given Lend_tracker_pool's bulk storage of arena-construct()ed (outer a/k/a first-class) ...
@ S_SHM_BIPC_MISC_LIBRARY_ERROR
Low-level boost.ipc.shm: boost.interprocess emitted miscellaneous library exception sans a system cod...
ipc::shm sub-module with the SHM-jemalloc SHM-provider. See ipc::shm doc header for introduction.
unsigned int arena_id_t
Arena ID as dictated by jemalloc.
std::shared_ptr< T > Obj_handle
Determines the shared_ptr variety returned by A::construct() and S::borrow_object() for any arena-len...
bipc::permissions Permissions
Short-hand for Unix (POSIX) permissions class.
void op_with_possible_bipc_exception(flow::log::Logger *logger_ptr, Error_code *err_code, const Error_code &misc_bipc_lib_error, String_view context, const Func &func)
Internal (to ipc) utility that invokes the given function that invokes a boost.interprocess operation...
flow::util::String_view String_view
Short-hand for Flow's String_view.
Internal-use shared_ptr disposer object, attached to every cross-process-lendable object handle retur...
This is the friend facade of Owner_shm_pool_collection that exposes non-public APIs hidden from publi...
Printable (with knobs in contained util::stat::Info_dump_format) bundling of stats/info relevant to (...
Sub-group: raw allocation activity – cumulative counts of memory-manager allocate/deallocate operatio...
Sub-group: the arena's virtual-address-space / page-state footprint – how much memory it currently ho...
The memory-manager-level statistics for a single native allocator-arena (for SHM-jemalloc: one jemall...
Similar mission to Obj_db_aux_pool_stats but covers information that, by nature, is not per-arena but...
Similar mission to Owner_pool_stats but covers information that, by nature, is not per-arena but rath...
Bundles together per-arena Owner_pool_stats and Obj_db_aux_pool_stats, so they can be accessed via on...
Obj_db_aux_pool_stats m_obj_db_aux_pool
Sub-struct with individual stats; see type's doc header.
A bundle of several individually-documented stat-sets – object construct/dispose/live and zombie-reap...
This info-struct contains basic properties of a SHM-pool (in a SHM-arena).
IDs an arena, as a GAUGE in contexts like Shm_pool_info and per-arena Borrower_pool_stats,...