Flow-IPC 3.0.0
Flow-IPC project: Full implementation reference.
stat_info_dump.cpp
Go to the documentation of this file.
1/* Flow-IPC: SHM-jemalloc
2 * Copyright (c) 2023 Akamai Technologies, Inc.; and other contributors.
3 * Each commit is copyright by its respective author or author's employer.
4 *
5 * Licensed under the MIT License:
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a copy
8 * of this software and associated documentation files (the "Software"), to deal
9 * in the Software without restriction, including without limitation the rights
10 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 * copies of the Software, and to permit persons to whom the Software is
12 * furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included in
15 * all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 * THE SOFTWARE. */
24
25/// @file
26
28#include "ipc/util/util_fwd.hpp"
29#include <flow/util/string_view.hpp>
30#include <flow/util/stat/stat_set.hpp>
31
33{
34
35// Implementations.
36
37std::ostream& operator<<(std::ostream& os, const Arena_info_dump& val)
38{
40 using flow::util::stat::print;
41
42 String_view ln; // Separator when next thing has no conceptual indent-level.
43 String_view ln_ln; // Separator when next thing has 1 conceptual indent-level.
44 bool verbose;
45 val.m_fmt.m_multiline ? (os << "- ", ln = "\n- ", ln_ln = "\n - ", verbose = val.m_fmt.m_verbose)
46 : (ln = (ln_ln = " | "), verbose = false);
47 // As advertised (can't print jemalloc-stats-dump without lots of newlines).
48
49 if (verbose && (!val.m_mem_mgr_stats_dump.empty())) // (`verbose` implies multiline.)
50 {
51 os << "jemalloc_dump/GLOBAL: DUMP_START[[[\n" << val.m_mem_mgr_stats_dump // By contract: newline-terminated.
52 << "]]]END_DUMP" << ln;
53 }
54 else // if (!verbose) || (for whatever reason no dump saved)
55 {
56 os << "jemalloc_dump/GLOBAL: [non-verbose/skipped]" << ln;
57 }
58 // else { Just skip it. `verbose` affect nothing else. }
59
60 /* (Subtlety: the "/arena" snippet is a nod to the fact that there are potentially multiple jemalloc-arenas
61 * in an Ipc_arena. (As of this writing there is exactly 1, but this could -- probably will -- sometime change.)
62 * Nevertheless we don't use "conceptual indentation" (ln_ln) for it. It's a subjective feel thing; these
63 * stats are pretty central (and indenting always-1 thing looks a bit meh).
64 * @todo Once there are indeed potentially >1 jemalloc-arenas in an Ipc_arena, revisit this; see how it looks/feels.
65 * Reconsider the "/arena" snippet too; possibly handle the whole thing, cosmetics-wise, as we handle
66 * live_pools below.) */
67 for (const auto& mem_mgr_stats : val.m_mem_mgr_stats)
68 {
69 // @todo Add idx printout like below, when in reality `m_mem_mgr_stats.size() > 1` becomes a thing.
70 os << "mem_mgr/arena: [" << print(mem_mgr_stats) << ']' << ln; // mem_mgr_stats includes jemalloc-arena-ID.
71 }
72
73 os << "sharded: [" << print(val.m_sharded_stats) << ']' << ln
74 << "pool: [" << print(val.m_pool_stats) << ']' << ln
75 << "obj_db_aux_pool/GLOBAL: [" << print(val.m_obj_db_aux_pool_global_stats) << ']' << ln
76 << "owner_pool_lookup/GLOBAL: [" << print(val.m_owner_pool_lookup_global_stats) << ']' << ln;
77
78 const auto& shm_pool_info_vec = val.m_shm_pool_live_info;
79 if (shm_pool_info_vec.empty())
80 {
81 os << "live_pools: [none]"; // No trailing newlines (as advertised).
82 }
83 else
84 {
85 os << "live_pools->" << ln_ln;
86
87 size_t idx = 0;
88 const auto n_pools = shm_pool_info_vec.size();
89 for (const auto& info : shm_pool_info_vec)
90 {
91 os << "pool[" << (++idx) << '/' << n_pools << "]: [" << print(info) << ']';
92 if (idx != n_pools)
93 {
94 os << ln_ln;
95 }
96 }
97 }
98
99 return os;
100} // operator<<(ostream&, Arena_info_dump)
101
102std::ostream& operator<<(std::ostream& os, const Shm_session_info_dump& val)
103{
104 using util::String_view;
105 using flow::util::stat::print;
106
107 String_view ln, ln_ln;
108 val.m_fmt.m_multiline ? (os << "- ", ln = "\n- ", ln_ln = "\n - ")
109 : (ln = (ln_ln = " | "));
110
111 os << "borrower_pool: [" << print(val.m_borrower_pool_stats) << ']' << ln
112 << "borrower_pool/total/GLOBAL: [" << print(val.m_borrower_pool_stats_process_wide_total) << ']' << ln;
113
114 const auto& brw_pool_stats_vec = val.m_borrower_pool_stats_process_wide_per_arena;
115 if (brw_pool_stats_vec.empty())
116 {
117 os << "borrower_pool/by_arena/GLOBAL: [none]" << ln;
118 }
119 else
120 {
121 os << "borrower_pool/by_arena/GLOBAL->" << ln_ln;
122
123 size_t idx = 0;
124 const auto n_arenas = brw_pool_stats_vec.size();
125 for (const auto& stats : brw_pool_stats_vec)
126 {
127 ++idx;
128 os << "arena[" << idx << '/' << n_arenas << "]: [" << print(stats) << ']';
129
130 if (idx == n_arenas)
131 {
133 if (n_omitted == 0)
134 {
135 os << ln;
136 }
137 else
138 {
139 os << ln_ln
140 << "+omitted[" << n_omitted << ']' << ln;
141 }
142 } // if (idx == n_arenas)
143 else
144 {
145 os << ln_ln;
146 }
147 }
148 } // else // if (!brw_pool_stats_vec.empty())
149
150 os << "borrower_pool_lookup/GLOBAL: [" << print(val.m_borrower_pool_lookup_global_stats) << ']' << ln;
151
152 const auto& shm_pool_info_vec = val.m_borrowed_shm_pool_live_info;
153 if (shm_pool_info_vec.empty())
154 {
155 os << "borrowed_pools: [none]"; // No trailing newlines (as advertised).
156 }
157 else
158 {
159 os << "borrowed_pools->" << ln_ln;
160
161 size_t idx = 0;
162 const auto n_pools = shm_pool_info_vec.size();
163 for (const auto& info : shm_pool_info_vec)
164 {
165 os << "pool[" << (++idx) << '/' << n_pools << "]: [" << print(info) << ']';
166 if (idx != n_pools)
167 {
168 os << ln_ln;
169 }
170 }
171 }
172
173 return os;
174} // operator<<(ostream&, Shm_session_info_dump)
175
176} // namespace ipc::shm::arena_lend::jemalloc::stat
Stats-related sub-namespace for SHM-jemalloc, for general organization (and ADL segregation if needed...
std::ostream & operator<<(std::ostream &os, const Arena_info_dump &val)
Prints string representation of the given Arena_info_dump to the given ostream.
flow::util::String_view String_view
Short-hand for Flow's String_view.
Definition: util_fwd.hpp:112
Printable (with knobs in contained util::stat::Info_dump_format) bundling of stats/info relevant to (...
std::vector< arena_lend::stat::Shm_pool_info > m_shm_pool_live_info
Target Ipc_arena's info from: Ipc_arena::shm_pool_live_info().
arena_lend::stat::Obj_db_aux_pool_global_stats m_obj_db_aux_pool_global_stats
Global stats from: static Ipc_arena::obj_db_aux_pool_global_stats().
util::stat::Info_dump_format m_fmt
Print-format knobs in effect at ostream << *this time.
arena_lend::stat::Owner_pool_lookup_global_stats m_owner_pool_lookup_global_stats
Global stats from: static Ipc_arena::owner_pool_lookup_global_stats().
std::vector< arena_lend::stat::Memory_manager_stats > m_mem_mgr_stats
Target Ipc_arena's stats from: Ipc_arena::memory_manager_stats().
arena_lend::stat::Sharded_stats m_sharded_stats
Target Ipc_arena's stats from: Ipc_arena::sharded_stats().
std::string m_mem_mgr_stats_dump
If unavailable then empty; otherwise the newline-terminated output of Memory_manager::stats_dump_to_o...
arena_lend::stat::Pool_stats m_pool_stats
Target Ipc_arena's stats from: Ipc_arena::pool_stats().
Printable (with knobs in contained util::stat::Info_dump_format) bundling of stats/info relevant to (...
size_t m_borrower_pool_stats_process_wide_per_arena_n_omitted
If m_fmt.m_verbose == false at Shm_session::info_dump() time, this is the # (possibly zero) of entrie...
arena_lend::stat::Borrower_pool_stats m_borrower_pool_stats_process_wide_total
Global stats from: static Shm_session::borrower_pool_stats_process_wide(): return value.
arena_lend::stat::Borrower_pool_stats m_borrower_pool_stats
Target Shm_session's stats from: Shm_session::borrower_pool_stats().
std::vector< arena_lend::stat::Borrower_pool_stats > m_borrower_pool_stats_process_wide_per_arena
Global stats from: static Shm_session::borrower_pool_stats_process_wide(): the per-arena out-arg.
util::stat::Info_dump_format m_fmt
Print-format knobs in effect at ostream << *this time.
std::vector< arena_lend::stat::Shm_pool_info > m_borrowed_shm_pool_live_info
Global info from: static Shm_session::shm_pool_live_info().
arena_lend::stat::Borrower_pool_lookup_global_stats m_borrower_pool_lookup_global_stats
Global stats from: static Shm_session::borrower_pool_lookup_global_stats().
bool m_verbose
If true: Print everything you've got; if false: refrain from producing multi-page output if possible.
Definition: util.hpp:56
bool m_multiline
If true: Use newlines where appropriate for readability (except at the very end of the output); if fa...
Definition: util.hpp:81