0
0
Fork 0
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:
Jason Volk 2018-05-05 22:58:25 -07:00
parent f55304e0a1
commit 1059688d02
6 changed files with 54 additions and 39 deletions

View file

@ -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 &notes(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

View file

@ -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

View file

@ -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 &);

View file

@ -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

View file

@ -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

View file

@ -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);