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

ircd::ctx: Partial inline continuation.

This commit is contained in:
Jason Volk 2019-10-10 18:18:21 -07:00
parent 9bb4936625
commit 7afb295c09
2 changed files with 69 additions and 53 deletions

View file

@ -21,7 +21,6 @@ namespace ircd::ctx
struct continuation;
using yield_context = boost::asio::yield_context;
using yield_closure = std::function<void (yield_context &)>;
using interruptor = std::function<void (ctx *const &)>;
using predicate = std::function<bool ()>;
}
@ -54,21 +53,75 @@ struct ircd::ctx::continuation
static const predicate false_predicate;
static const interruptor noop_interruptor;
ctx *const self;
const predicate *const pred;
const interruptor *const intr;
const void *const frame_address;
const uint uncaught_exceptions;
const void *const return_address;
const interruptor *const intr;
const predicate *const pred;
const size_t uncaught_exceptions;
ctx *const self;
operator const boost::asio::yield_context &() const noexcept;
operator boost::asio::yield_context &() noexcept;
void enter();
void leave() noexcept;
template<class yield_closure>
continuation(const predicate &,
const interruptor &,
const yield_closure &);
yield_closure&&);
continuation(continuation &&) = delete;
continuation(const continuation &) = delete;
continuation &operator=(continuation &&) = delete;
continuation &operator=(const continuation &) = delete;
};
template<class yield_closure>
inline
__attribute__((always_inline))
ircd::ctx::continuation::continuation(const predicate &pred,
const interruptor &intr,
yield_closure&& closure)
:frame_address
{
__builtin_frame_address(0)
}
,return_address
{
__builtin_return_address(0)
}
,intr
{
&intr
}
,pred
{
&pred
}
,uncaught_exceptions
{
exception_handler::uncaught_exceptions(0)
}
,self
{
ircd::ctx::current
}
{
// Run the provided routine which performs the actual context switch.
// Everything happening in this closure is no longer considered part
// of this context, but it is technically operating on this stack.
leave();
std::exception_ptr eptr; try
{
closure(static_cast<yield_context &>(*this));
}
catch(...)
{
eptr = std::current_exception();
}
enter();
if(unlikely(eptr))
std::rethrow_exception(eptr);
}

View file

@ -181,7 +181,7 @@ ircd::ctx::ctx::jump()
continuation
{
continuation::false_predicate, continuation::noop_interruptor, [&target]
(auto &yield)
(auto &yield) noexcept
{
target();
}
@ -232,7 +232,7 @@ ircd::ctx::ctx::wait()
boost::system::error_code ec; continuation
{
predicate, interruptor, [this, &ec]
(auto &yield)
(auto &yield) noexcept
{
alarm.async_wait(yield[ec]);
}
@ -1080,34 +1080,10 @@ ircd::ctx::continuation::noop_interruptor{[]
return;
}};
//
// continuation
//
[[gnu::hot]]
ircd::ctx::continuation::continuation(const predicate &pred,
const interruptor &intr,
const yield_closure &closure)
:self
{
ircd::ctx::current
}
,pred
{
&pred
}
,intr
{
&intr
}
,frame_address
{
__builtin_frame_address(0)
}
,uncaught_exceptions
{
exception_handler::uncaught_exceptions(0)
}
void
ircd::ctx::continuation::leave()
noexcept
{
assert(self != nullptr);
assert(self->notes <= 1);
@ -1150,19 +1126,12 @@ ircd::ctx::continuation::continuation(const predicate &pred,
// restore this register; otherwise it remains null for executions on
// the program's main stack.
ircd::ctx::current = nullptr;
}
// Run the provided routine which performs the actual context switch.
// Everything happening in this closure is no longer considered part
// of this context, but it is technically operating on this stack.
std::exception_ptr eptr; try
{
closure(*self->yc);
}
catch(...)
{
eptr = std::current_exception();
}
[[gnu::hot]]
void
ircd::ctx::continuation::enter()
{
// Restore the current context register.
ircd::ctx::current = self;
@ -1185,13 +1154,8 @@ ircd::ctx::continuation::continuation(const predicate &pred,
self->interruption_point();
__builtin_unreachable();
}
// Check if the operation failed; it's now safe to throw that.
if(unlikely(eptr))
std::rethrow_exception(eptr);
}
[[gnu::hot]]
ircd::ctx::continuation::operator
boost::asio::yield_context &()
noexcept
@ -1201,7 +1165,6 @@ noexcept
return *self->yc;
}
[[gnu::hot]]
ircd::ctx::continuation::operator
const boost::asio::yield_context &()
const noexcept