diff --git a/include/ircd/ctx/prof.h b/include/ircd/ctx/prof.h index af06d5a04..ba19d65cc 100644 --- a/include/ircd/ctx/prof.h +++ b/include/ircd/ctx/prof.h @@ -32,7 +32,7 @@ namespace ircd::ctx::prof enum class event :uint8_t; struct ticker; - uint64_t cycles() noexcept; + ulong cycles() noexcept; string_view reflect(const event &); // totals @@ -92,14 +92,28 @@ struct ircd::ctx::prof::ticker std::array()> event {{0}}; }; -inline uint64_t +/// Calculate the current reference cycle count (TSC) for the current +/// execution epoch/slice. This involves one RDTSC sample which is provided +/// by ircd::prof/ircd::prof::x86 (or for some other platform), and then +/// subtracting away the prior RDTSC sample which the context system makes +/// at the start of each execution slice. +extern inline ulong +__attribute__((flatten, always_inline, gnu_inline, artificial)) ircd::ctx::prof::cur_slice_cycles() noexcept { - return cycles() - cur_slice_start(); + const auto stop(cycles()); + const auto start(cur_slice_start()); + return stop - start; } -extern inline uint64_t +/// Sample the current TSC directly with an rdtsc; this is a convenience +/// wrapper leading to the ircd::prof interface which contains the platform +/// specific methods to efficiently sample a cycle count. +/// +/// Developers are advised to obtain cycle counts from this_ctx::cycles() +/// which accumulates the cycle count for a specific ctx's execution only. +extern inline ulong __attribute__((flatten, always_inline, gnu_inline, artificial)) ircd::ctx::prof::cycles() noexcept diff --git a/include/ircd/ctx/this_ctx.h b/include/ircd/ctx/this_ctx.h index aa653ba92..863524980 100644 --- a/include/ircd/ctx/this_ctx.h +++ b/include/ircd/ctx/this_ctx.h @@ -16,14 +16,12 @@ namespace ircd::ctx { inline namespace this_ctx { struct ctx &cur() noexcept; ///< Assumptional reference to *current - const uint64_t &id(); // Unique ID for cur ctx - string_view name(); // Optional label for cur ctx - + const uint64_t &id() noexcept; // Unique ID for cur ctx + string_view name() noexcept; // Optional label for cur ctx ulong cycles() noexcept; // misc profiling related - bool interruption_requested() noexcept; // interruption(cur()) - void interruption_point(); // throws if interruption_requested() + void interruption_point(); // throws if interruption_requested() void wait(); // Returns when context is woken up. void yield(); // Allow other contexts to run before returning. @@ -131,16 +129,35 @@ ircd::ctx::this_ctx::wait(const duration &d) return duration_cast(ret); } -inline ulong +/// View the name of the currently running context, or "*" if no context is +/// currently running. +inline ircd::string_view +ircd::ctx::this_ctx::name() +noexcept +{ + return current? name(cur()) : "*"_sv; +} + +/// Calculate the current TSC (reference cycle count) accumulated for this +/// context only. This is done by first calculating a cycle count for the +/// current slice/epoch (see: ctx/prof.h) which is where the RDTSC sample +/// occurs. This count is added to an accumulator value saved in the ctx +/// structure. The accumulator value is updated at the end of each execution +/// slice, thus giving us the cycle count for this ctx only, up to this point. +extern inline ulong +__attribute__((flatten, always_inline, gnu_inline, artificial)) ircd::ctx::this_ctx::cycles() noexcept { - return cycles(cur()) + prof::cur_slice_cycles(); + const auto slice(prof::cur_slice_cycles()); + const auto accumulated(cycles(cur())); + return accumulated + slice; } /// Reference to the currently running context. Call if you expect to be in a /// context. Otherwise use the ctx::current pointer. inline ircd::ctx::ctx & +__attribute__((always_inline)) ircd::ctx::this_ctx::cur() noexcept { diff --git a/ircd/ctx.cc b/ircd/ctx.cc index fe37eb726..86d65470a 100644 --- a/ircd/ctx.cc +++ b/ircd/ctx.cc @@ -738,19 +738,12 @@ noexcept /// Returns unique ID of currently running context const uint64_t & ircd::ctx::this_ctx::id() +noexcept { static const uint64_t zero{0}; return current? id(cur()) : zero; } -/// Returns optional developer-given name for currently running context -ircd::string_view -ircd::ctx::this_ctx::name() -{ - static const string_view nada{"*"}; - return current? name(cur()) : nada; -} - // // uinterruptible //