0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-27 07:54:05 +01:00

ircd::ctx: Rework the prof stack to make a public test interface.

This commit is contained in:
Jason Volk 2018-12-17 15:24:41 -08:00
parent 1e1c9c6a1e
commit 4686139f8e
2 changed files with 96 additions and 33 deletions

View file

@ -39,6 +39,13 @@ namespace ircd::ctx::prof
const ulong &cur_slice_start(); const ulong &cur_slice_start();
ulong cur_slice_cycles(); ulong cur_slice_cycles();
// test accessors
bool slice_exceeded_warning(const ulong &cycles);
bool slice_exceeded_assertion(const ulong &cycles);
bool slice_exceeded_interrupt(const ulong &cycles);
bool stack_exceeded_warning(const size_t &size);
bool stack_exceeded_assertion(const size_t &size);
// called at the appropriate point to mark the event (internal use). // called at the appropriate point to mark the event (internal use).
void mark(const event &); void mark(const event &);
} }

View file

@ -1292,12 +1292,15 @@ ircd::ctx::debug_stats(const pool &pool)
namespace ircd::ctx::prof namespace ircd::ctx::prof
{ {
ulong _slice_start; // Time slice state ulong _slice_start; // Current/last time slice started
ulong _slice_stop; // Last time slice ended
ulong _slice_total; // Monotonic accumulator ulong _slice_total; // Monotonic accumulator
void check_stack(); void check_stack();
void check_slice(); void check_slice();
void slice_start();
void slice_enter();
void slice_leave();
void handle_cur_continue(); void handle_cur_continue();
void handle_cur_yield(); void handle_cur_yield();
@ -1388,21 +1391,20 @@ ircd::ctx::prof::total_slice_cycles()
void void
ircd::ctx::prof::handle_cur_enter() ircd::ctx::prof::handle_cur_enter()
{ {
slice_start(); slice_enter();
} }
void void
ircd::ctx::prof::handle_cur_leave() ircd::ctx::prof::handle_cur_leave()
{ {
slice_leave();
check_slice(); check_slice();
} }
void void
ircd::ctx::prof::handle_cur_yield() ircd::ctx::prof::handle_cur_yield()
{ {
auto &c(cur()); slice_leave();
c.profile.yields++;
check_slice(); check_slice();
check_stack(); check_stack();
} }
@ -1410,15 +1412,29 @@ ircd::ctx::prof::handle_cur_yield()
void void
ircd::ctx::prof::handle_cur_continue() ircd::ctx::prof::handle_cur_continue()
{ {
slice_start(); slice_enter();
} }
void void
ircd::ctx::prof::slice_start() ircd::ctx::prof::slice_enter()
{ {
_slice_start = rdtsc(); _slice_start = rdtsc();
} }
void
ircd::ctx::prof::slice_leave()
{
_slice_stop = rdtsc();
auto &c(cur());
assert(_slice_stop >= _slice_start);
const auto last_slice(_slice_stop - _slice_start);
c.stack.at = stack_at_here();
c.profile.cycles += last_slice;
_slice_total += last_slice;
c.profile.yields++;
}
void void
ircd::ctx::prof::check_slice() ircd::ctx::prof::check_slice()
{ {
@ -1428,38 +1444,36 @@ ircd::ctx::prof::check_slice()
c.flags & context::SLICE_EXEMPT c.flags & context::SLICE_EXEMPT
}; };
const auto &last_cycles assert(_slice_stop >= _slice_start);
const auto last_slice
{ {
cur_slice_cycles() _slice_stop - _slice_start
}; };
c.profile.cycles += last_cycles; // Slice warning
_slice_total += last_cycles; if(unlikely(slice_exceeded_warning(last_slice) && !slice_exempt))
const ulong &slice_warning(settings::slice_warning);
if(unlikely(slice_warning > 0 && last_cycles >= slice_warning && !slice_exempt))
log::dwarning log::dwarning
{ {
"context '%s' id:%lu watchdog: timeslice excessive; lim:%lu last:%lu pct:%.2lf", "context '%s' id:%lu watchdog: timeslice excessive; lim:%lu last:%lu pct:%.2lf",
name(c), name(c),
id(c), id(c),
slice_warning, ulong(settings::slice_warning),
last_cycles, last_slice,
((double(last_cycles) / double(slice_warning)) * 100.0) ((double(last_slice) / double(ulong(settings::slice_warning))) * 100.0)
}; };
const ulong &slice_assertion(settings::slice_assertion); // Slice assertion
assert(slice_assertion == 0 || last_cycles < slice_assertion || slice_exempt); assert(!slice_exceeded_assertion(last_slice) || slice_exempt);
const ulong &slice_interrupt(settings::slice_interrupt); // Slice interrupt
if(unlikely(slice_interrupt > 0 && last_cycles >= slice_interrupt && !slice_exempt)) if(unlikely(slice_exceeded_interrupt(last_slice) && !slice_exempt))
throw interrupted throw interrupted
{ {
"context '%s' id:%lu watchdog interrupt; lim:%lu last:%lu total:%lu", "context '%s' id:%lu watchdog interrupt; lim:%lu last:%lu total:%lu",
name(c), name(c),
id(c), id(c),
slice_interrupt, ulong(settings::slice_interrupt),
last_cycles, last_slice,
cycles(c), cycles(c),
}; };
} }
@ -1473,13 +1487,13 @@ ircd::ctx::prof::check_stack()
c.flags & context::STACK_EXEMPT c.flags & context::STACK_EXEMPT
}; };
const double &stack_max(c.stack.max); const auto &stack_at
const auto &stack_at(stack_at_here());
c.stack.at = stack_at;
const double &stack_usage_assertion(settings::stack_usage_assertion);
if(unlikely(!stack_exempt && stack_at > stack_max * stack_usage_assertion))
{ {
c.stack.at
};
// Stack warning
if(unlikely(!stack_exempt && stack_exceeded_warning(stack_at)))
log::dwarning log::dwarning
{ {
"context '%s' id:%lu watchdog: stack used %zu of %zu bytes", "context '%s' id:%lu watchdog: stack used %zu of %zu bytes",
@ -1489,9 +1503,51 @@ ircd::ctx::prof::check_stack()
c.stack.max c.stack.max
}; };
const double &stack_usage_assertion(settings::stack_usage_assertion); // Stack assertion
assert(stack_at < c.stack.max * double(settings::stack_usage_assertion)); assert(stack_exempt || !stack_exceeded_assertion(stack_at));
} }
bool
ircd::ctx::prof::stack_exceeded_assertion(const size_t &stack_at)
{
const auto &c(cur());
const auto &stack_max(c.stack.max);
const double &stack_usage_assertion(settings::stack_usage_assertion);
return stack_usage_assertion > 0.0?
stack_at >= c.stack.max * settings::stack_usage_assertion:
false;
}
bool
ircd::ctx::prof::stack_exceeded_warning(const size_t &stack_at)
{
const auto &c(cur());
const auto &stack_max(c.stack.max);
const double &stack_usage_warning(settings::stack_usage_warning);
return stack_usage_warning > 0.0?
stack_at >= c.stack.max * stack_usage_warning:
false;
}
bool
ircd::ctx::prof::slice_exceeded_interrupt(const ulong &cycles)
{
const ulong &threshold(settings::slice_interrupt);
return threshold > 0 && cycles >= threshold;
}
bool
ircd::ctx::prof::slice_exceeded_assertion(const ulong &cycles)
{
const ulong &threshold(settings::slice_assertion);
return threshold > 0 && cycles >= threshold;
}
bool
ircd::ctx::prof::slice_exceeded_warning(const ulong &cycles)
{
const ulong &threshold(settings::slice_warning);
return threshold > 0 && cycles >= threshold;
} }
#ifdef HAVE_X86INTRIN_H #ifdef HAVE_X86INTRIN_H