mirror of
https://github.com/matrix-construct/construct
synced 2024-12-26 15:33:54 +01:00
ircd::ios: Add epoch history in circular buffer for profiling w/ console cmd.
This commit is contained in:
parent
ccbd6c80bb
commit
59197ee2d5
3 changed files with 136 additions and 4 deletions
|
@ -108,7 +108,9 @@ struct ircd::ios::descriptor
|
||||||
std::unique_ptr<struct stats> stats;
|
std::unique_ptr<struct stats> stats;
|
||||||
std::function<void *(handler &, const size_t &)> allocator;
|
std::function<void *(handler &, const size_t &)> allocator;
|
||||||
std::function<void (handler &, void *const &, const size_t &)> deallocator;
|
std::function<void (handler &, void *const &, const size_t &)> deallocator;
|
||||||
bool continuation;
|
std::vector<std::array<uint64_t, 2>> history; // epoch, cycles
|
||||||
|
uint8_t history_pos {0};
|
||||||
|
bool continuation {false};
|
||||||
|
|
||||||
descriptor(const string_view &name,
|
descriptor(const string_view &name,
|
||||||
const decltype(allocator) & = default_allocator,
|
const decltype(allocator) & = default_allocator,
|
||||||
|
|
27
ircd/ios.cc
27
ircd/ios.cc
|
@ -100,6 +100,14 @@ ircd::ios::descriptor::descriptor(const string_view &name,
|
||||||
{
|
{
|
||||||
deallocator?: default_deallocator
|
deallocator?: default_deallocator
|
||||||
}
|
}
|
||||||
|
,history_pos
|
||||||
|
{
|
||||||
|
0
|
||||||
|
}
|
||||||
|
,history
|
||||||
|
(
|
||||||
|
256, {0}
|
||||||
|
)
|
||||||
,continuation
|
,continuation
|
||||||
{
|
{
|
||||||
continuation
|
continuation
|
||||||
|
@ -169,6 +177,11 @@ ircd::ios::descriptor::stats::operator+=(const stats &o)
|
||||||
// handler
|
// handler
|
||||||
//
|
//
|
||||||
|
|
||||||
|
namespace ircd::ios
|
||||||
|
{
|
||||||
|
constexpr bool profile_history {false};
|
||||||
|
}
|
||||||
|
|
||||||
decltype(ircd::ios::handler::current)
|
decltype(ircd::ios::handler::current)
|
||||||
thread_local
|
thread_local
|
||||||
ircd::ios::handler::current;
|
ircd::ios::handler::current;
|
||||||
|
@ -226,6 +239,14 @@ noexcept
|
||||||
stats.slice_last = slice_stop - handler->ts;
|
stats.slice_last = slice_stop - handler->ts;
|
||||||
stats.slice_total += stats.slice_last;
|
stats.slice_total += stats.slice_last;
|
||||||
|
|
||||||
|
if constexpr(profile_history)
|
||||||
|
{
|
||||||
|
assert(descriptor.history_pos < descriptor.history.size());
|
||||||
|
descriptor.history[descriptor.history_pos][0] = handler::epoch;
|
||||||
|
descriptor.history[descriptor.history_pos][1] = stats.slice_last;
|
||||||
|
++descriptor.history_pos;
|
||||||
|
}
|
||||||
|
|
||||||
assert(handler::current == handler);
|
assert(handler::current == handler);
|
||||||
handler::current = nullptr;
|
handler::current = nullptr;
|
||||||
}
|
}
|
||||||
|
@ -236,14 +257,14 @@ ircd::ios::handler::enter(handler *const &handler)
|
||||||
noexcept
|
noexcept
|
||||||
{
|
{
|
||||||
assert(!handler::current);
|
assert(!handler::current);
|
||||||
|
handler::current = handler;
|
||||||
|
++handler::epoch;
|
||||||
|
|
||||||
assert(handler && handler->descriptor);
|
assert(handler && handler->descriptor);
|
||||||
auto &descriptor(*handler->descriptor);
|
auto &descriptor(*handler->descriptor);
|
||||||
|
|
||||||
assert(descriptor.stats);
|
assert(descriptor.stats);
|
||||||
auto &stats(*descriptor.stats);
|
auto &stats(*descriptor.stats);
|
||||||
|
|
||||||
handler::current = handler;
|
|
||||||
++handler::epoch;
|
|
||||||
++stats.calls;
|
++stats.calls;
|
||||||
|
|
||||||
const auto last_ts
|
const auto last_ts
|
||||||
|
|
|
@ -1663,6 +1663,115 @@ console_cmd__ios(opt &out, const string_view &line)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
console_cmd__ios__record(opt &out, const string_view &line)
|
||||||
|
{
|
||||||
|
std::map<uint64_t, std::tuple<uint64_t, const ios::descriptor *>> map;
|
||||||
|
for(const auto *const &descriptor : ios::descriptor::list)
|
||||||
|
{
|
||||||
|
assert(descriptor);
|
||||||
|
const auto &d(*descriptor);
|
||||||
|
|
||||||
|
const auto &history(d.history);
|
||||||
|
const auto &pos(d.history_pos);
|
||||||
|
|
||||||
|
for(size_t i(pos); i < 256; ++i)
|
||||||
|
{
|
||||||
|
if(!history[i][0])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
map.emplace(history[i][0], std::make_tuple(history[i][1], descriptor));
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t i(0); i < pos; ++i)
|
||||||
|
{
|
||||||
|
if(!history[i][0])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
map.emplace(history[i][0], std::make_tuple(history[i][1], descriptor));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint64_t last(0);
|
||||||
|
for(const auto &[epoch, tuple] : map)
|
||||||
|
{
|
||||||
|
const auto &[cyc, desc]
|
||||||
|
{
|
||||||
|
tuple
|
||||||
|
};
|
||||||
|
|
||||||
|
const char ch
|
||||||
|
{
|
||||||
|
epoch == last + 1? '|': 'T'
|
||||||
|
};
|
||||||
|
|
||||||
|
out
|
||||||
|
<< " " << ch
|
||||||
|
<< std::right
|
||||||
|
<< " " << std::setw(12) << epoch
|
||||||
|
<< " " << std::setw(12) << cyc
|
||||||
|
<< " " << std::left << std::setw(36) << desc->name;
|
||||||
|
|
||||||
|
out
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
last = epoch;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
console_cmd__ios__history(opt &out, const string_view &line)
|
||||||
|
{
|
||||||
|
for(const auto *const &descriptor : ios::descriptor::list)
|
||||||
|
{
|
||||||
|
assert(descriptor);
|
||||||
|
const auto &d(*descriptor);
|
||||||
|
|
||||||
|
const auto &history(d.history);
|
||||||
|
const auto &pos(d.history_pos);
|
||||||
|
|
||||||
|
out
|
||||||
|
<< std::left << std::setw(3) << d.id
|
||||||
|
<< " " << std::left << std::setw(48) << d.name
|
||||||
|
<< std::endl;
|
||||||
|
|
||||||
|
size_t k(0);
|
||||||
|
for(size_t i(pos); i < 256; ++i)
|
||||||
|
{
|
||||||
|
if(!history[i][0])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
out
|
||||||
|
<< "[" << std::right << std::setw(9) << history[i][0]
|
||||||
|
<< " |" << std::right << std::setw(9) << history[i][1]
|
||||||
|
<< "] ";
|
||||||
|
|
||||||
|
if(++k % 12 == 0)
|
||||||
|
out << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t i(0); i < pos; ++i)
|
||||||
|
{
|
||||||
|
if(!history[i][0])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
out
|
||||||
|
<< "[" << std::right << std::setw(9) << history[i][0]
|
||||||
|
<< " |" << std::right << std::setw(9) << history[i][1]
|
||||||
|
<< "] ";
|
||||||
|
|
||||||
|
if(++k % 12 == 0)
|
||||||
|
out << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
out << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
console_cmd__ios__depth(opt &out, const string_view &line)
|
console_cmd__ios__depth(opt &out, const string_view &line)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue