31#include <flow/util/thread_lcl.hpp>
32#include <flow/util/util.hpp>
33#include <flow/util/stat/stat_set.hpp>
34#include <flow/util/stat/stat_set_list.hpp>
35#include <flow/util/util_fwd.hpp>
36#include <boost/unordered/unordered_flat_map.hpp>
37#include <boost/thread/tss.hpp>
38#include <boost/move/unique_ptr.hpp>
39#include <boost/range/join.hpp>
40#include <boost/range/iterator_range.hpp>
41#include <boost/range/adaptor/filtered.hpp>
42#include <boost/range/adaptor/transformed.hpp>
43#include <boost/range/adaptor/map.hpp>
44#include <boost/range/algorithm/for_each.hpp>
109template<
typename Shm_arena_t>
120 using Own = boost::movelib::unique_ptr<T>;
171 template<
typename Task>
219 mutable flow::util::Mutex_non_recursive
m_mutex;
253template<
typename Shm_arena>
256 sharded_stats_impl<true>(shm_arena, target_stats);
259template<
typename Shm_arena>
262 sharded_stats_impl<false>(shm_arena, target_stats);
265template<
bool CONSUME_ELSE_RESET,
typename Shm_arena>
268 using flow::util::stat::stats_aggregate_shards;
269 using flow::util::stat::stats_reset_shard_aggregate;
270 using flow::util::Lock_guard;
271 using flow::util::Mutex_recursive;
272 namespace range = boost::range;
273 using boost::adaptors::map_keys;
274 using boost::adaptors::filtered;
275 using boost::adaptors::transformed;
328 const auto collection_id = shm_arena.get_id();
368 const auto admin_to_shard_ptr = [collection_id](Admin* admin) -> Shard*
387 return admin->stats_update_pre_consumption(collection_id);
391 const auto client_to_shard_ptr = [collection_id](Client* client) -> Shard*
396 Lock_guard<
decltype(client->m_per_arena_stats_shards_mutex)> lock{client->m_per_arena_stats_shards_mutex};
397 const auto it_collection_id_and_stats = map.find(collection_id);
398 return (it_collection_id_and_stats == map.end()) ?
static_cast<Shard*
>(
nullptr)
399 : it_collection_id_and_stats->second.get();
406 const auto shard_ptr_to_shard_ref = [](
const auto& shard_ptr) -> Shard& {
return *shard_ptr; };
409 const auto shard_ptr_non_null = [](Shard* shard_ptr) ->
auto {
return bool(shard_ptr); };
425 Admin::s_state.m_obj_db_registry.while_locked([&](
const auto& admin_state_and_mdt_map)
427 Client::s_state.m_obj_db_registry.while_locked([&](
const auto& client_state_and_mdt_map)
429 Fin_shards::get_instance().stats_while_locked(collection_id,
430 [&](Shard* fin_fold_shard_or_null)
432 const auto admin_client_finalized_shards
435 (admin_state_and_mdt_map | map_keys
436 | transformed(admin_to_shard_ptr) | filtered(shard_ptr_non_null)
437 | transformed(shard_ptr_to_shard_ref),
438 client_state_and_mdt_map | map_keys
439 | transformed(client_to_shard_ptr) | filtered(shard_ptr_non_null)
440 | transformed(shard_ptr_to_shard_ref)),
441 boost::make_iterator_range(&fin_fold_shard_or_null, &fin_fold_shard_or_null + 1)
442 | filtered(shard_ptr_non_null) | transformed(shard_ptr_to_shard_ref));
454 const auto& begin = admin_client_finalized_shards.begin();
455 const auto& end = admin_client_finalized_shards.end();
456 if constexpr(CONSUME_ELSE_RESET)
460 Shard fresh_stats_from_0_shards;
465 fresh_stats_from_0_shards.m_owner_obj.m_n_shards = 0;
466 stats_aggregate_shards<Shard>(target_stats, begin, begin, &fresh_stats_from_0_shards);
470 stats_aggregate_shards<Shard>(target_stats, begin, end,
nullptr);
475 Shard fresh_stats_from_0_shards;
476 fresh_stats_from_0_shards.m_owner_obj.m_n_shards = 0;
477 stats_reset_shard_aggregate(target_stats, begin, end, fresh_stats_from_0_shards);
486template<
typename Shm_arena_t>
487Finalized_shards<Shm_arena_t>&
491 return *s_fin_shards;
575template<
typename Shm_arena_t>
578template<
typename Shm_arena_t>
579template<
typename Task>
582 using flow::util::Lock_guard;
584 Lock_guard<
decltype(m_mutex)> lock{m_mutex};
585 const auto it_collection_id_and_fold_shard = m_per_arena_stats_shards.find(collection_id);
586 task((it_collection_id_and_fold_shard == m_per_arena_stats_shards.end())
588 : it_collection_id_and_fold_shard->second.get());
591template<
typename Shm_arena_t>
594 using flow::util::Lock_guard;
595 using flow::util::stat::stats_assign;
596 using flow::util::stat::stats_aggregate_one;
598 Lock_guard<
decltype(m_mutex)> lock{m_mutex};
599 auto& fold_shard = m_per_arena_stats_shards[collection_id];
605 stats_assign(fold_shard.get(), stats_shard);
610 stats_aggregate_one(fold_shard.get(), stats_shard);
613template<
typename Shm_arena_t>
616 using flow::util::Lock_guard;
618 Lock_guard<
decltype(m_mutex)> lock{m_mutex};
619 m_per_arena_stats_shards.erase(collection_id);
(Internal-use) Thread_lcl_obj_db_admin<A>::this_thread_obj_db() is the current thread's module that t...
(Internal-use) Where a Thread_lcl_obj_db_admin cannot handle lend-object and dispose-object tracking,...
(Internal-use) Singleton (per-Shm_arena type <=> per-arena-lending SHM-provider – like SHM-jemalloc) ...
boost::movelib::unique_ptr< T > Own
Short-hand for single-ownership pointer (unique_ptr of some sort).
Finalized_shards()
Constructor. Zero-arg due to singleton pattern.
void stats_insert(collection_id_t collection_id, const Sharded_stats &stats_shard)
Folds (field-wise-sums, a-la flow::util::stat::stats_aggregate_one()) the given stats shard into the ...
boost::unordered_flat_map< collection_id_t, Own< Sharded_stats > > m_per_arena_stats_shards
Stores, per arena, the arena's accumulated finalized shard: the fold – field-wise sum,...
Shm_arena_t Shm_arena
Short-hand for template parameter type.
void stats_erase(collection_id_t collection_id)
Deletes the accumulated finalized shard (all stats_insert()ed contributions) pertaining to the given ...
static Finalized_shards & get_instance()
Returns the process-wide singleton instance of this class.
flow::util::Mutex_non_recursive m_mutex
Protects m_per_arena_stats_shards;.
void stats_while_locked(collection_id_t collection_id, const Task &task)
Provides access – thread-safely – to the arena's accumulated finalized shard: the fold (field-wise su...
Stats-related sub-namespace, for ADL segregation and general organization.
flow::util::Mutex_recursive & thread_end_gap_mutex()
(Helper for sharded_stats_impl() and Thread_lcl_obj_db_admin/client) Process-global,...
void sharded_stats_impl(const Shm_arena &shm_arena, Sharded_stats *target_stats)
Helper: implements sharded_stats() or sharded_stats_reset().
arena_lend::stat::Sharded_stats Sharded_stats
Short-hand for brevity: Thread_lcl_obj_db_* and buddies make frequent mention of this.
void sharded_stats(const Shm_arena &shm_arena, Sharded_stats *target_stats)
Assembles and outputs the current stats tracked by the obj-DB module (as anchored by Thread_lcl_obj_d...
void sharded_stats_reset(const Shm_arena &shm_arena, Sharded_stats *target_stats)
Resets Sharded_stats; companion to sharded_stats().
uint32_t collection_id_t
Identifier type for a shared memory pool collection.
flow::async::Task Task
Short-hand for polymorphic function (a-la std::function<>) that takes no arguments and returns nothin...
A bundle of several individually-documented stat-sets – object construct/dispose/live and zombie-reap...