0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-12-26 15:33:54 +01:00

ircd::ctx: Add stack_usage_assertion; move stack_usage_here() into this_ctx::.

This commit is contained in:
Jason Volk 2018-04-27 19:04:31 -07:00
parent 49a2cddc45
commit 09c282fd8e
3 changed files with 45 additions and 8 deletions

View file

@ -14,7 +14,6 @@
namespace ircd::ctx
{
size_t stack_usage_here(const ctx &) __attribute__((noinline));
size_t stack_usage_here();
}
/// Profiling for the context system.

View file

@ -29,6 +29,9 @@ inline namespace this_ctx
void interruption_point(); // throws interrupted if interruption_requested()
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.
// Return remaining time if notified; or <= 0 if not, and timeout thrown on throw overloads
microseconds wait(const microseconds &, const std::nothrow_t &);
template<class E, class duration> nothrow_overload<E, duration> wait(const duration &);
@ -51,6 +54,20 @@ namespace ircd::ctx
extern __thread ctx *current;
}
/// An instance of stack_usage_assertion is placed on a ctx stack where one
/// wants to test the stack usage at both construction and destruction points
/// to ensure it is less than the value set in ctx::prof::settings which is
/// generally some engineering safety factor of 2-3 etc. This should not be
/// entirely relied upon except during debug builds, however we may try to
/// provide an optimized build mode enabling these to account for any possible
/// differences in the stack between the environments.
///
struct ircd::ctx::this_ctx::stack_usage_assertion
{
stack_usage_assertion();
~stack_usage_assertion() noexcept;
};
/// An instance of critical_assertion detects an attempt to context switch.
///
/// For when the developer specifically does not want any yielding in a

View file

@ -490,6 +490,13 @@ ircd::ctx::this_ctx::yield()
while(!done);
}
size_t
ircd::ctx::this_ctx::stack_usage_here()
{
assert(current);
return stack_usage_here(cur());
}
/// Throws interrupted if the currently running context was interrupted
/// and clears the interrupt flag.
void
@ -562,6 +569,27 @@ noexcept
critical_asserted = theirs;
}
//
// stack_usage_assertion
//
ircd::ctx::this_ctx::stack_usage_assertion::stack_usage_assertion()
{
#ifndef NDEBUG
const auto stack_usage(stack_usage_here());
assert(stack_usage < cur().stack_max * prof::settings.stack_usage_assertion);
#endif
}
ircd::ctx::this_ctx::stack_usage_assertion::~stack_usage_assertion()
noexcept
{
#ifdef RB_DEBUG
const auto stack_usage(stack_usage_here());
assert(stack_usage < cur().stack_max * prof::settings.stack_usage_assertion);
#endif
}
///////////////////////////////////////////////////////////////////////////////
//
// ctx/continuation.h
@ -1070,13 +1098,6 @@ ircd::ctx::prof::check_stack()
}
}
size_t
ircd::ctx::stack_usage_here()
{
assert(current);
return stack_usage_here(*current);
}
size_t
ircd::ctx::stack_usage_here(const ctx &ctx)
{