0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-02 10:08:56 +02:00

ircd::ctx: Integrate slice cycle counters with ios.

This commit is contained in:
Jason Volk 2020-08-21 04:18:41 -07:00
parent a864cc73b2
commit 07830f1413
4 changed files with 77 additions and 43 deletions

View file

@ -44,7 +44,7 @@ namespace ircd::ctx::prof
const uint64_t &get(const ctx &c, const event &);
// current slice state
const ulong &cur_slice_start() noexcept;
ulong cur_slice_start() noexcept;
ulong cur_slice_cycles() noexcept;
// test accessors

View file

@ -56,6 +56,13 @@ ircd::ctx::ctx::ios_desc
"ircd::ctx::ctx"
};
/// This is a pseudo ircd::ios handler. See ios_desc
decltype(ircd::ctx::ctx::ios_handler)
ircd::ctx::ctx::ios_handler
{
&ios_desc
};
/// Internal context struct ctor
ircd::ctx::ctx::ctx(const string_view &name,
const size_t &stack_max,
@ -103,8 +110,36 @@ ircd::ctx::ctx::spawn(context::function func)
std::bind(&ctx::operator(), this, ph::_1, std::move(func))
};
auto *const parent_context
{
ircd::ctx::current
};
auto *const parent_handler
{
ircd::ios::handler::current
};
mark(prof::event::SPAWN);
boost::asio::spawn(ios::get(), std::move(bound), attrs);
if(!parent_context) try
{
ios::handler::leave(parent_handler);
boost::asio::spawn(ios::get(), std::move(bound), attrs);
ios::handler::enter(parent_handler);
}
catch(...)
{
ios::handler::enter(parent_handler);
throw;
}
else continuation
{
continuation::false_predicate, continuation::noop_interruptor, [&attrs, &bound]
(auto &yield)
{
boost::asio::spawn(ios::get(), std::move(bound), attrs);
}
};
}
/// Base frame for a context.
@ -1538,19 +1573,17 @@ ircd::ctx::debug_stats(const pool &pool)
namespace ircd::ctx::prof
{
thread_local ulong _slice_start; // Current/last time slice started
thread_local ulong _slice_stop; // Last time slice ended
thread_local ticker _total; // Totals kept for all contexts.
thread_local ticker _total; // Totals kept for all contexts.
static void check_stack();
static void check_slice();
static void slice_enter() noexcept;
static void slice_leave() noexcept;
static void slice_enter() noexcept;
static void handle_cur_continue();
static void handle_cur_yield();
static void handle_cur_leave();
static void handle_cur_enter();
static void handle_cur_continue() noexcept;
static void handle_cur_enter() noexcept;
static void inc_ticker(const event &e) noexcept;
}
@ -1642,6 +1675,14 @@ noexcept
void
ircd::ctx::prof::handle_cur_enter()
noexcept
{
slice_enter();
}
void
ircd::ctx::prof::handle_cur_continue()
noexcept
{
slice_enter();
}
@ -1661,50 +1702,36 @@ ircd::ctx::prof::handle_cur_yield()
check_stack();
}
void
ircd::ctx::prof::handle_cur_continue()
{
slice_enter();
}
void
ircd::ctx::prof::slice_enter()
noexcept
{
assert(ctx::ios_desc.stats);
++ctx::ios_desc.stats->calls;
_slice_start = cycles();
assert(_slice_start >= _slice_stop);
ios::handler::enter(&ctx::ios_handler);
}
void
ircd::ctx::prof::slice_leave()
noexcept
{
_slice_stop = cycles();
// NOTE: will fail without constant_tsc;
// NOTE: may fail without nonstop_tsc after OS suspend mode
assert(_slice_stop >= _slice_start);
auto &c(cur());
const auto last_slice
{
_slice_stop - _slice_start
};
ios::handler::leave(&ctx::ios_handler);
static constexpr auto pos
{
size_t(prof::event::CYCLES)
};
_total.event.at(pos) += last_slice;
assert(ctx::ios_desc.stats);
const auto &last_slice
{
ctx::ios_desc.stats->slice_last
};
auto &c(cur());
c.profile.event.at(pos) += last_slice;
assert(c.ios_desc.stats);
c.ios_desc.stats->slice_total += last_slice;
c.ios_desc.stats->slice_last = last_slice;
c.stack.at = stack_at_here();
c.stack.peak = std::max(c.stack.at, c.stack.peak);
_total.event.at(pos) += last_slice;
}
#ifndef NDEBUG
@ -1717,10 +1744,10 @@ ircd::ctx::prof::check_slice()
c.flags & context::SLICE_EXEMPT
};
assert(_slice_stop >= _slice_start);
const auto last_slice
assert(ctx::ios_desc.stats);
const auto &last_slice
{
_slice_stop - _slice_start
ctx::ios_desc.stats->slice_last
};
// Slice warning
@ -1838,11 +1865,11 @@ noexcept
}
[[gnu::hot]]
const ulong &
ulong
ircd::ctx::prof::cur_slice_start()
noexcept
{
return _slice_start;
return ctx::ios_handler.ts;
}
[[gnu::hot]]

View file

@ -32,6 +32,7 @@ struct ircd::ctx::ctx
static uint64_t id_ctr; // monotonic
static ios::descriptor ios_desc;
static ios::handler ios_handler;
uint64_t id {++id_ctr}; // Unique runtime ID
string_view name; // User given name (optional)

View file

@ -207,7 +207,13 @@ noexcept
// needs to be tied off here instead.
if(!ret)
{
stats.slice_last = cycles() - handler->ts;
const auto last_ts
{
std::exchange(handler->ts, cycles())
};
assert(handler->ts >= last_ts);
stats.slice_last = handler->ts - last_ts;
stats.slice_total += stats.slice_last;
assert(handler::current == handler);
@ -228,15 +234,15 @@ noexcept
assert(descriptor.stats);
auto &stats(*descriptor.stats);
const auto slice_stop
const auto slice_start
{
cycles()
std::exchange(handler->ts, cycles())
};
// NOTE: will fail without constant_tsc;
// NOTE: may fail without nonstop_tsc after OS suspend mode
assert(slice_stop >= handler->ts);
stats.slice_last = slice_stop - handler->ts;
assert(handler->ts >= slice_start);
stats.slice_last = handler->ts - slice_start;
stats.slice_total += stats.slice_last;
if constexpr(profile_history)