0
0
Fork 0
mirror of https://github.com/matrix-construct/construct synced 2024-06-19 18:38:21 +02:00

ircd::ctx: Inline various codepaths leading to flags(ctx).

ircd::ctx: Inline cheap prof::get() wrappings.
This commit is contained in:
Jason Volk 2020-06-18 03:20:14 -07:00
parent 2ad836ce6d
commit 505fe310a8
4 changed files with 102 additions and 119 deletions

View file

@ -137,6 +137,59 @@ namespace ircd
using ctx::assert_main_thread;
}
/// Marks `ctx` for whether to allow or suppress interruption. Suppression
/// does not ignore an interrupt itself, it only ignores the interruption
/// points. Thus when a suppression ends if the interrupt flag was ever set
/// the next interruption point will throw as expected.
inline void
ircd::ctx::interruptible(ctx &ctx,
const bool &b)
noexcept
{
flags(ctx) ^= (flags(ctx) ^ (ulong(b) - 1)) & context::NOINTERRUPT;
assert(bool(flags(ctx) & context::NOINTERRUPT) == !b);
assert(interruptible(ctx) == b);
}
/// Indicates if `ctx` was terminated; does not clear the flag
inline bool
ircd::ctx::termination(const ctx &c)
noexcept
{
return flags(c) & context::TERMINATED;
}
/// Indicates if `ctx` was interrupted; does not clear the flag
inline bool
ircd::ctx::interruption(const ctx &c)
noexcept
{
return flags(c) & context::INTERRUPTED;
}
inline bool
ircd::ctx::interruptible(const ctx &ctx)
noexcept
{
return ~flags(ctx) & context::NOINTERRUPT;
}
/// Returns the cycle count for `ctx`
inline const ulong &
ircd::ctx::cycles(const ctx &ctx)
noexcept
{
return prof::get(ctx, prof::event::CYCLES);
}
/// Returns the yield count for `ctx`
inline const uint64_t &
ircd::ctx::epoch(const ctx &ctx)
noexcept
{
return prof::get(ctx, prof::event::YIELD);
}
inline void
__attribute__((always_inline))
ircd::ctx::assert_main_thread()

View file

@ -18,8 +18,14 @@ namespace ircd::ctx { inline namespace this_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()
bool interruptible() noexcept;
void interruptible(const bool &, std::nothrow_t) noexcept;
void interruptible(const bool &);
void yield(); // Allow other contexts to run before returning.
}}
@ -43,6 +49,49 @@ noexcept
return current? name(cur()) : "*"_sv;
}
inline void
ircd::ctx::this_ctx::interruptible(const bool &b,
std::nothrow_t)
noexcept
{
interruptible(cur(), b);
}
inline bool
ircd::ctx::this_ctx::interruptible()
noexcept
{
return interruptible(cur());
}
/// Throws interrupted if the currently running context was interrupted
/// and clears the interrupt flag.
inline void
ircd::ctx::this_ctx::interruptible(const bool &b)
{
const bool theirs
{
interruptible(cur())
};
if(unlikely(theirs && !b && interruption_requested()))
interruption_point();
interruptible(cur(), b);
if(unlikely(!theirs && b && interruption_requested()))
interruption_point();
}
/// Returns true if the currently running context was interrupted and clears
/// the interrupt flag.
inline bool
ircd::ctx::this_ctx::interruption_requested()
noexcept
{
return interruption(cur()) || termination(cur());
}
/// 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

View file

@ -11,20 +11,10 @@
#pragma once
#define HAVE_IRCD_CTX_UNINTERRUPTIBLE_H
namespace ircd::ctx
{
bool interruptible(const ctx &) noexcept;
void interruptible(ctx &, const bool &) noexcept;
}
namespace ircd::ctx {
inline namespace this_ctx
{
struct uninterruptible;
bool interruptible() noexcept;
void interruptible(const bool &);
void interruptible(const bool &, std::nothrow_t) noexcept;
}}
/// An instance of uninterruptible will suppress interrupts sent to the
@ -101,43 +91,3 @@ noexcept
{
interruptible(theirs, std::nothrow);
}
//
// interruptible
//
inline void
ircd::ctx::this_ctx::interruptible(const bool &b,
std::nothrow_t)
noexcept
{
interruptible(cur(), b);
}
inline bool
ircd::ctx::this_ctx::interruptible()
noexcept
{
return interruptible(cur());
}
/// Marks `ctx` for whether to allow or suppress interruption. Suppression
/// does not ignore an interrupt itself, it only ignores the interruption
/// points. Thus when a suppression ends if the interrupt flag was ever set
/// the next interruption point will throw as expected.
inline void
ircd::ctx::interruptible(ctx &ctx,
const bool &b)
noexcept
{
flags(ctx) ^= (flags(ctx) ^ (ulong(b) - 1)) & context::NOINTERRUPT;
assert(bool(flags(ctx) & context::NOINTERRUPT) == !b);
assert(interruptible(ctx) == b);
}
inline bool
ircd::ctx::interruptible(const ctx &ctx)
noexcept
{
return ~flags(ctx) & context::NOINTERRUPT;
}

View file

@ -572,33 +572,6 @@ noexcept
return ctx.finished();
}
/// Indicates if `ctx` was terminated; does not clear the flag
[[gnu::hot]]
bool
ircd::ctx::termination(const ctx &c)
noexcept
{
return c.flags & context::TERMINATED;
}
/// Indicates if `ctx` was interrupted; does not clear the flag
[[gnu::hot]]
bool
ircd::ctx::interruption(const ctx &c)
noexcept
{
return c.flags & context::INTERRUPTED;
}
/// Returns the cycle count for `ctx`
[[gnu::hot]]
const ulong &
ircd::ctx::cycles(const ctx &ctx)
noexcept
{
return prof::get(ctx, prof::event::CYCLES);
}
/// Returns the IO priority nice-value
[[gnu::hot]]
const int8_t &
@ -617,15 +590,6 @@ noexcept
return ctx.nice;
}
/// Returns the yield count for `ctx`
[[gnu::hot]]
const uint64_t &
ircd::ctx::epoch(const ctx &ctx)
noexcept
{
return prof::get(ctx, prof::event::YIELD);
}
/// Returns the notification count for `ctx`
[[gnu::hot]]
const int32_t &
@ -789,15 +753,6 @@ ircd::ctx::this_ctx::interruption_point()
return cur().interruption_point();
}
/// Returns true if the currently running context was interrupted and clears
/// the interrupt flag.
bool
ircd::ctx::this_ctx::interruption_requested()
noexcept
{
return interruption(cur()) || termination(cur());
}
/// Returns unique ID of currently running context
[[gnu::hot]]
const uint64_t &
@ -808,30 +763,6 @@ noexcept
return current? id(cur()) : zero;
}
//
// interruptible
//
/// Throws interrupted if the currently running context was interrupted
/// and clears the interrupt flag.
[[gnu::hot]]
void
ircd::ctx::this_ctx::interruptible(const bool &b)
{
const bool theirs
{
interruptible(cur())
};
if(theirs && !b)
interruption_point();
interruptible(cur(), b);
if(!theirs && b)
interruption_point();
}
//
// critical_assertion
//