mirror of
https://github.com/matrix-construct/construct
synced 2024-12-25 15:04:10 +01:00
ircd::ctx: Inline various codepaths leading to flags(ctx).
ircd::ctx: Inline cheap prof::get() wrappings.
This commit is contained in:
parent
2ad836ce6d
commit
505fe310a8
4 changed files with 102 additions and 119 deletions
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
69
ircd/ctx.cc
69
ircd/ctx.cc
|
@ -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
|
||||
//
|
||||
|
|
Loading…
Reference in a new issue