mirror of
https://github.com/matrix-construct/construct
synced 2024-06-02 18:18:56 +02:00
ircd::ctx: Add state for stack usage profiling; clarify some interfaces.
This commit is contained in:
parent
f55304e0a1
commit
1059688d02
|
@ -50,6 +50,7 @@ namespace ircd::ctx
|
|||
const uint64_t &id(const ctx &); // Unique ID for context
|
||||
string_view name(const ctx &); // User's optional label for context
|
||||
const size_t &stack_max(const ctx &); // Returns stack size allocated for ctx
|
||||
const size_t &stack_at(const ctx &); // Stack at last sleep (also see this_ctx.h)
|
||||
const int64_t ¬es(const ctx &); // Peeks at internal semaphore count
|
||||
const ulong &cycles(const ctx &); // Accumulated tsc (not counting cur slice)
|
||||
bool interruption(const ctx &); // Context was marked for interruption
|
||||
|
|
|
@ -11,12 +11,6 @@
|
|||
#pragma once
|
||||
#define HAVE_IRCD_CTX_PROF_H
|
||||
|
||||
namespace ircd::ctx
|
||||
{
|
||||
size_t stack_usage_here(const ctx &) __attribute__((noinline));
|
||||
ulong cycles_here(const ctx &);
|
||||
}
|
||||
|
||||
/// Profiling for the context system.
|
||||
///
|
||||
/// These facilities provide tools and statistics. The primary purpose here is
|
||||
|
|
|
@ -30,7 +30,8 @@ inline namespace this_ctx
|
|||
bool interruption_requested(); // interruption(cur())
|
||||
|
||||
struct stack_usage_assertion; // Assert safety factor (see ctx/prof.h)
|
||||
size_t stack_usage_here(); // calculates stack usage at call.
|
||||
size_t stack_at_here() __attribute__((noinline));
|
||||
ulong cycles_here();
|
||||
|
||||
// Return remaining time if notified; or <= 0 if not, and timeout thrown on throw overloads
|
||||
microseconds wait(const microseconds &, const std::nothrow_t &);
|
||||
|
|
45
ircd/ctx.cc
45
ircd/ctx.cc
|
@ -327,6 +327,13 @@ ircd::ctx::notes(const ctx &ctx)
|
|||
return ctx.notes;
|
||||
}
|
||||
|
||||
/// Returns the notification count for `ctx`
|
||||
const size_t &
|
||||
ircd::ctx::stack_at(const ctx &ctx)
|
||||
{
|
||||
return ctx.stack_at;
|
||||
}
|
||||
|
||||
/// Returns the notification count for `ctx`
|
||||
const size_t &
|
||||
ircd::ctx::stack_max(const ctx &ctx)
|
||||
|
@ -432,11 +439,18 @@ ircd::ctx::this_ctx::yield()
|
|||
while(!done);
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::ctx::this_ctx::stack_usage_here()
|
||||
ulong
|
||||
ircd::ctx::this_ctx::cycles_here()
|
||||
{
|
||||
assert(current);
|
||||
return stack_usage_here(cur());
|
||||
return cycles(cur()) + prof::cur_slice_cycles();
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::ctx::this_ctx::stack_at_here()
|
||||
{
|
||||
assert(current);
|
||||
return cur().stack_base - uintptr_t(__builtin_frame_address(0));
|
||||
}
|
||||
|
||||
/// Throws interrupted if the currently running context was interrupted
|
||||
|
@ -521,14 +535,14 @@ noexcept
|
|||
|
||||
ircd::ctx::this_ctx::stack_usage_assertion::stack_usage_assertion()
|
||||
{
|
||||
const auto stack_usage(stack_usage_here());
|
||||
const auto stack_usage(stack_at_here());
|
||||
assert(stack_usage < cur().stack_max * prof::settings.stack_usage_assertion);
|
||||
}
|
||||
|
||||
ircd::ctx::this_ctx::stack_usage_assertion::~stack_usage_assertion()
|
||||
noexcept
|
||||
{
|
||||
const auto stack_usage(stack_usage_here());
|
||||
const auto stack_usage(stack_at_here());
|
||||
assert(stack_usage < cur().stack_max * prof::settings.stack_usage_assertion);
|
||||
}
|
||||
|
||||
|
@ -1041,35 +1055,24 @@ ircd::ctx::prof::check_stack()
|
|||
{
|
||||
auto &c(cur());
|
||||
const double &stack_max(c.stack_max);
|
||||
const auto stack_usage(stack_usage_here(c));
|
||||
const auto &stack_at(stack_at_here());
|
||||
c.stack_at = stack_at;
|
||||
|
||||
if(unlikely(stack_usage > stack_max * settings.stack_usage_warning))
|
||||
if(unlikely(stack_at > stack_max * settings.stack_usage_warning))
|
||||
{
|
||||
log::dwarning
|
||||
{
|
||||
"context stack usage ctx '%s' #%lu used %zu of %zu bytes",
|
||||
name(c),
|
||||
id(c),
|
||||
stack_usage,
|
||||
stack_at,
|
||||
c.stack_max
|
||||
};
|
||||
|
||||
assert(stack_usage < c.stack_max * settings.stack_usage_assertion);
|
||||
assert(stack_at < c.stack_max * settings.stack_usage_assertion);
|
||||
}
|
||||
}
|
||||
|
||||
ulong
|
||||
ircd::ctx::cycles_here(const ctx &ctx)
|
||||
{
|
||||
return cycles(ctx) + (running(ctx)? prof::cur_slice_cycles() : 0UL);
|
||||
}
|
||||
|
||||
size_t
|
||||
ircd::ctx::stack_usage_here(const ctx &ctx)
|
||||
{
|
||||
return ctx.stack_base - uintptr_t(__builtin_frame_address(0));
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// ctx_ole.h
|
||||
|
|
|
@ -25,6 +25,7 @@ struct ircd::ctx::ctx
|
|||
boost::asio::yield_context *yc {nullptr}; // boost interface
|
||||
uintptr_t stack_base {0}; // assigned when spawned
|
||||
size_t stack_max {0}; // User given stack size
|
||||
size_t stack_at {0}; // Updated for profiling at sleep
|
||||
int64_t notes {0}; // norm: 0 = asleep; 1 = awake; inc by others; dec by self
|
||||
ulong cycles {0}; // monotonic counter (rdtsc)
|
||||
continuation *cont {nullptr}; // valid when asleep; invalid when awake
|
||||
|
|
|
@ -766,21 +766,36 @@ console_cmd__ctx__list(opt &out, const string_view &line)
|
|||
<< (interruption(ctx)? 'I' : '-')
|
||||
;
|
||||
|
||||
const auto pct
|
||||
{
|
||||
cycles(ctx) / (long double)ctx::prof::total_slice_cycles()
|
||||
};
|
||||
out << " "
|
||||
<< std::setw(5) << std::right << std::fixed << std::setprecision(2) << (pct * 100)
|
||||
<< "%";
|
||||
|
||||
out << " "
|
||||
out << " "
|
||||
<< std::setw(15) << std::right << cycles(ctx)
|
||||
<< " TSC";
|
||||
<< " ";
|
||||
|
||||
const long double total_cyc(ctx::prof::total_slice_cycles());
|
||||
const auto tsc_pct
|
||||
{
|
||||
total_cyc > 0.0? (cycles(ctx) / total_cyc) : 0.0L
|
||||
};
|
||||
|
||||
out << " "
|
||||
<< std::setw(5) << std::right << std::fixed << std::setprecision(2) << (tsc_pct * 100)
|
||||
<< "% TSC";
|
||||
|
||||
out << " "
|
||||
<< std::setw(7) << std::right << stack_at(ctx)
|
||||
<< " ";
|
||||
|
||||
out << " "
|
||||
<< std::setw(7) << std::right << stack_max(ctx)
|
||||
<< " SS";
|
||||
<< " ";
|
||||
|
||||
const auto stack_pct
|
||||
{
|
||||
stack_at(ctx) / (long double)stack_max(ctx)
|
||||
};
|
||||
|
||||
out << " "
|
||||
<< std::setw(5) << std::right << std::fixed << std::setprecision(2) << (stack_pct * 100)
|
||||
<< "% ST";
|
||||
|
||||
out << " :"
|
||||
<< name(ctx);
|
||||
|
|
Loading…
Reference in a new issue