29#include "ipc/shm/arena_lend/shm_pool.hpp"
31#include <flow/util/thread_lcl.hpp>
32#include <flow/util/util.hpp>
33#include <flow/util/stat/stat_set_list.hpp>
34#include <flow/util/stat/stat_set.hpp>
35#include <boost/container/flat_map.hpp>
36#include <boost/unordered/unordered_flat_map.hpp>
79template<
typename Shm_arena_t,
bool OWNER_ELSE_BORROWER>
278template<
typename Repository_t,
bool LOOKUP_CAN_FAIL,
typename Shm_arena_t>
306 using Map = boost::container::flat_map<void*, Pool_by_base>;
365 static flow::util::Thread_local_state_registry<Thread_local_pool_lookup_rev>
s_registry;
411template<
typename Repository_t,
typename Shm_arena_t>
433 using Map = boost::unordered_flat_map<pool_id_t, void*>;
481 static flow::util::Thread_local_state_registry<Thread_local_pool_lookup_fwd>
s_registry;
495template<
typename Repository_t,
bool LOOKUP_CAN_FAIL,
typename Shm_arena_t>
496flow::util::Thread_local_state_registry<Thread_local_pool_lookup_rev<Repository_t, LOOKUP_CAN_FAIL, Shm_arena_t>>
498 {
nullptr,
"Thread_local_pool_lookup_rev"};
500template<
typename Repository_t,
typename Shm_arena_t>
501flow::util::Thread_local_state_registry<Thread_local_pool_lookup_fwd<Repository_t, Shm_arena_t>>
506template<
typename Repository_t,
bool LOOKUP_CAN_FAIL,
typename Shm_arena_t>
509 using flow::util::stat::fetch_add;
510 using flow::util::stat::update_hi_wmark;
516 Repository::get_instance().tl_copy_rev_pull_pools(&m_pools_sorted_by_base);
520 update_hi_wmark(&stats.m_pool_rev_lookup_tl_cache_count_hi_wmark,
521 fetch_add(&stats.m_pool_rev_lookup_tl_cache_count, 1) + 1);
525template<
typename Repository_t,
bool LOOKUP_CAN_FAIL,
typename Shm_arena_t>
528 using flow::util::stat::fetch_sub;
532 ->m_pool_rev_lookup_tl_cache_count), 1);
536template<
typename Repository_t,
bool LOOKUP_CAN_FAIL,
typename Shm_arena_t>
542 flow::util::Lock_guard<
decltype(m_pools_sorted_by_base_mutex)> lock{m_pools_sorted_by_base_mutex};
551 auto it = m_pools_sorted_by_base.upper_bound(
const_cast<void*
>(address));
553 if constexpr(S_LOOKUP_CAN_FAIL)
555 if (it == m_pools_sorted_by_base.begin())
565 const auto& pool_data = it->second;
566 const auto addr_ptr =
reinterpret_cast<uintptr_t
>(address);
567 const auto pool_base =
reinterpret_cast<uintptr_t
>(it->first);
569 if constexpr(S_LOOKUP_CAN_FAIL)
573 if (addr_ptr >= (pool_base + pool_data.m_sz_or_0))
580 pool_id = pool_data.m_id;
581 pool_offset = addr_ptr - pool_base;
584template<
typename Repository_t,
bool LOOKUP_CAN_FAIL,
typename Shm_arena_t>
592 flow::util::Lock_guard<
decltype(m_pools_sorted_by_base_mutex)> lock{m_pools_sorted_by_base_mutex};
594 m_pools_sorted_by_base = std::move(pools_sorted_by_base);
599template<
typename Repository_t,
typename Shm_arena_t>
602 using flow::util::stat::fetch_add;
603 using flow::util::stat::update_hi_wmark;
609 Repository::get_instance().tl_copy_fwd_pull_pools(&m_pool_bases_by_id);
613 update_hi_wmark(&stats.m_pool_fwd_lookup_tl_cache_count_hi_wmark,
614 fetch_add(&stats.m_pool_fwd_lookup_tl_cache_count, 1) + 1);
618template<
typename Repository_t,
typename Shm_arena_t>
621 using flow::util::stat::fetch_sub;
628template<
typename Repository_t,
typename Shm_arena_t>
632 flow::util::Lock_guard<
decltype(m_pool_bases_by_id_mutex)> lock{m_pool_bases_by_id_mutex};
636 return m_pool_bases_by_id.find(pool_id)->second;
639template<
typename Repository_t,
typename Shm_arena_t>
643 flow::util::Lock_guard<
decltype(m_pool_bases_by_id_mutex)> lock{m_pool_bases_by_id_mutex};
645 const auto it = m_pool_bases_by_id.find(pool_id);
646 return (it == m_pool_bases_by_id.end()) ?
static_cast<void*
>(
nullptr)
650template<
typename Repository_t,
typename Shm_arena_t>
658 flow::util::Lock_guard<
decltype(m_pool_bases_by_id_mutex)> lock{m_pool_bases_by_id_mutex};
660 m_pool_bases_by_id = std::move(pool_bases_by_id);
665template<
typename Shm_arena_t,
bool OWNER_ELSE_BORROWER>
674 return flow::util::stat::Global_stats<Pool_lookup_global_stats, Stats>::get().stats_default();
677template<
typename Shm_arena_t,
bool OWNER_ELSE_BORROWER>
681 return &(flow::util::stat::Global_stats<Pool_lookup_global_stats, Stats>::get().stats_mutable_default());
684template<
typename Shm_arena_t,
bool OWNER_ELSE_BORROWER>
687 flow::util::stat::Global_stats<Pool_lookup_global_stats, Stats>::get().reset();
Global stats singleton for either Owner_pool_lookup_global_stats or Borrower_pool_lookup_global_stats...
static constexpr bool S_OWNER_ELSE_BORROWER
Constant for template parameter.
std::conditional_t< S_OWNER_ELSE_BORROWER, arena_lend::stat::Owner_pool_lookup_global_stats, arena_lend::stat::Borrower_pool_lookup_global_stats > Stats
The actual stat-set type.
static void stats_reset()
Resets stats(). The formal meaning of a reset is discussed in flow::util::stat doc header.
static const Stats & stats()
Returns reference-to-const stat-set, carrying information that is global but per-template-instance-ty...
Shm_arena_t Shm_arena
Short-hand for the template parameter.
static Stats * stats_mutable()
Mutable version of stats(), for stat-updating.
Analogous to Thread_local_pool_lookup_rev but for forward lookup: pool ID -> base vaddr.
Repository_t Repository
Short-hand for the template parameter.
Shm_arena_t Shm_arena
Short-hand for the template parameter.
void * lookup(pool_id_t pool_id) const
Performs the forward lookup: given a pool ID, returns the pool's base vaddr; if pool ID is invalid un...
Map m_pool_bases_by_id
Thread-local copy of the canonical hash map: pool ID -> base vaddr. See Map doc and class doc header.
Thread_local_pool_lookup_fwd()
Analogous to Thread_local_pool_lookup_rev::Thread_local_pool_lookup_rev(). Reminder: Do not call dire...
void * lookup_safe(pool_id_t pool_id) const
Identical to lookup() but returns null if pool_id is not a registered pool (never registered or regis...
boost::unordered_flat_map< pool_id_t, void * > Map
Forward-lookup map type (pool ID -> base vaddr).
void push_pools(Map &&pool_bases_by_id)
Analogous to Thread_local_pool_lookup_rev::push_pools() but replaces the forward-lookup hash map.
static flow::util::Thread_local_state_registry< Thread_local_pool_lookup_fwd > s_registry
Global registry of per-thread *this instances.
Shm_pool::size_t pool_offset_t
Short-hand for pool-offset type (byte offset from pool base).
~Thread_local_pool_lookup_fwd()
Destructor: runs at thread exit.
flow::util::Mutex_non_recursive m_pool_bases_by_id_mutex
Per-thread mutex protecting m_pool_bases_by_id. Contended by at most 2 threads (local lookup versus p...
Thread_local_pool_lookup_rev<R>.s_registry, where R is a distinct pool-repository type,...
Shm_pool::size_t pool_offset_t
Short-hand for pool-offset type (byte offset from pool base).
boost::container::flat_map< void *, Pool_by_base > Map
Reverse-lookup map type (base vaddr -> Pool_by_base).
void lookup(const void *address, pool_id_t &pool_id, pool_offset_t &pool_offset) const
Performs the perf-critical reverse lookup: given a vaddr, determines the containing pool's ID and the...
flow::util::Mutex_non_recursive m_pools_sorted_by_base_mutex
Per-thread mutex protecting m_pools_sorted_by_base. Contended by at most 2 threads (local lookup vers...
static constexpr bool S_LOOKUP_CAN_FAIL
Mirrors the template parameter; true if lookup() can legitimately fail to find the containing pool.
Map m_pools_sorted_by_base
Thread-local copy of the canonical sorted map: pool-base vaddr -> Pool_by_base.
Shm_arena_t Shm_arena
Short-hand for the template parameter.
Thread_local_pool_lookup_rev()
Constructs this thread-local cache by pulling the current canonical pool state from Repository.
void push_pools(Map &&pools_sorted_by_base)
Replaces this thread-local sorted map with a new canonical snapshot.
static flow::util::Thread_local_state_registry< Thread_local_pool_lookup_rev > s_registry
Global registry of per-thread *this instances.
~Thread_local_pool_lookup_rev()
Destructor: runs at thread exit.
Repository_t Repository
Short-hand for the template parameter.
Segregated private stuff for ipc::shm::arena_lend.
uint32_t pool_id_t
Pool ID type.
Value type in the reverse-lookup map: identifies the pool and, when LOOKUP_CAN_FAIL is true for the c...
Shm_pool::size_t m_sz_or_0
Pool size in bytes, or 0 when the lookup context guarantees that every address is in some pool (LOOKU...
pool_id_t m_id
Pool identifier.
Analogous subject matter to Owner_pool_lookup_global_stats but borrower-side.
Similar mission to Owner_pool_stats but covers information that, by nature, is not per-arena but rath...