ircd::ios: Consolidate dispatch/post/defer interfaces; minor fixes.

This commit is contained in:
Jason Volk 2020-12-20 05:13:18 -08:00
parent 099c7754ff
commit 07ec766ff9
16 changed files with 224 additions and 280 deletions

View File

@ -158,8 +158,18 @@ try
if(!next_command())
break;
if(quit_when_done)
ircd::post{ircd::quit};
if(unlikely(quit_when_done))
{
static ircd::ios::descriptor descriptor
{
"construct.console.quit"
};
ircd::dispatch
{
descriptor, ios::defer, ircd::quit
};
}
return;
}

View File

@ -195,9 +195,14 @@ noexcept try
return;
};
ircd::post
static ircd::ios::descriptor descriptor
{
ircd::quit
"construct.smoketest"
};
ircd::dispatch
{
descriptor, ircd::ios::defer, ircd::quit
};
}
};

View File

@ -111,7 +111,7 @@ construct::signals::set_handle()
{
static ircd::ios::descriptor desc
{
"construct::signals"
"construct.signals"
};
auto handler

View File

@ -53,9 +53,9 @@ namespace ircd
inline void
ircd::ctx::this_ctx::yield()
{
ircd::post
ios::dispatch
{
courtesy_yield_desc, ios::synchronous
courtesy_yield_desc, ios::defer, ios::yield
};
}

View File

@ -13,43 +13,26 @@
namespace ircd::ios
{
IRCD_OVERLOAD(synchronous)
struct dispatch;
struct defer;
struct post;
IRCD_OVERLOAD(defer)
IRCD_OVERLOAD(yield)
}
namespace ircd
{
using ios::dispatch;
using ios::defer;
using ios::post;
}
struct ircd::ios::dispatch
{
dispatch(descriptor &, std::function<void ()>);
dispatch(descriptor &, synchronous_t, const std::function<void ()> &);
dispatch(descriptor &, synchronous_t);
dispatch(std::function<void ()>);
dispatch(synchronous_t, const std::function<void ()> &);
};
struct ircd::ios::defer
{
defer(descriptor &, std::function<void ()>);
defer(descriptor &, synchronous_t, const std::function<void ()> &);
defer(descriptor &, synchronous_t);
defer(std::function<void ()>);
defer(synchronous_t, const std::function<void ()> &);
};
dispatch(descriptor &, yield_t, const std::function<void ()> &);
struct ircd::ios::post
{
post(descriptor &, std::function<void ()>);
post(descriptor &, synchronous_t, const std::function<void ()> &);
post(descriptor &, synchronous_t);
post(std::function<void ()>);
post(synchronous_t, const std::function<void ()> &);
dispatch(descriptor &, defer_t, std::function<void ()>);
dispatch(descriptor &, defer_t, yield_t, const std::function<void ()> &);
dispatch(descriptor &, defer_t, yield_t);
};

View File

@ -49,8 +49,8 @@ namespace ircd::ios::profile
#include "descriptor.h"
#include "handler.h"
#include "asio.h"
#include "dispatch.h"
#include "empt.h"
#include "dispatch.h"
#include "epoll.h"
inline const uint64_t &

View File

@ -23,6 +23,7 @@ struct ircd::server::peer
struct err;
static constexpr const size_t &LINK_MAX{16};
static ios::descriptor close_desc;
static conf::item<bool> enable_ipv6;
static conf::item<size_t> link_min_default;
static conf::item<size_t> link_max_default;

View File

@ -530,6 +530,18 @@ noexcept
return ctx.note();
}
namespace ircd::ctx
{
[[gnu::visibility("hidden")]]
extern ios::descriptor signal_desc;
}
decltype(ircd::ctx::signal_desc)
ircd::ctx::signal_desc
{
"ircd.ctx.signal"
};
/// Executes `func` sometime between executions of `ctx` with thread-safety
/// so `func` and `ctx` are never executed concurrently no matter how many
/// threads the io_service has available to execute events on.
@ -537,7 +549,10 @@ void
ircd::ctx::signal(ctx &ctx,
std::function<void ()> func)
{
ircd::dispatch(std::move(func));
ios::dispatch
{
signal_desc, ios::defer, std::move(func)
};
}
/// Marks `ctx` for termination. Terminate is similar to interrupt() but the
@ -721,7 +736,10 @@ noexcept
decltype(ircd::ctx::this_ctx::courtesy_yield_desc)
ircd::ctx::this_ctx::courtesy_yield_desc
{
"ircd.ctx.courtesy_yield"
"ircd.ctx.courtesy_yield",
nullptr,
nullptr,
true,
};
// set by the continuation object and the base frame.
@ -1241,11 +1259,17 @@ ircd::ctx::context::context(const string_view &name,
// parent is not itself a context as yielding is not possible anyway.
assert(c->flags & POST || ircd::ctx::current);
if(c->flags & POST)
ios::post(spawn_desc[0], std::move(spawn));
ios::dispatch
{
spawn_desc[0], ios::defer, std::move(spawn)
};
// (experimental) Branch to spawn via defer mechanism.
else if(c->flags & DEFER)
ios::defer(spawn_desc[1], ios::synchronous, std::move(spawn));
ios::dispatch
{
spawn_desc[1], ios::defer, ios::yield, std::move(spawn)
};
// Branch to spawn via dispatch mechanism. This context will yield while
// the spawning takes place on this stack. This is the closest to a direct
@ -1254,7 +1278,10 @@ ircd::ctx::context::context(const string_view &name,
// switch. Note: This is also the default method when no flags are given
// and this parent is another context.
else if(c->flags & DISPATCH || (true))
ios::dispatch(spawn_desc[2], ios::synchronous, std::move(spawn));
ios::dispatch
{
spawn_desc[2], ios::yield, std::move(spawn)
};
}
ircd::ctx::context::context(context &&other)

View File

@ -982,9 +982,9 @@ ircd::fs::aio::system::submit(request &request)
std::bind(&system::chase, this)
};
ircd::defer
ios::dispatch
{
chase_descriptor, std::move(handler)
chase_descriptor, ios::defer, std::move(handler)
};
}

View File

@ -548,40 +548,12 @@ noexcept
// dispatch
//
namespace ircd::ios
{
extern descriptor dispatch_desc;
}
decltype(ircd::ios::dispatch_desc)
ircd::ios::dispatch_desc
{
"ircd.ios.dispatch"
};
[[gnu::hot]]
ircd::ios::dispatch::dispatch(std::function<void ()> function)
:dispatch
{
dispatch_desc, std::move(function)
}
{
}
ircd::ios::dispatch::dispatch(synchronous_t,
const std::function<void ()> &function)
:dispatch
{
dispatch_desc, synchronous, std::move(function)
}
{
}
ircd::ios::dispatch::dispatch(descriptor &descriptor,
synchronous_t)
defer_t,
yield_t)
:dispatch
{
descriptor, synchronous, []
descriptor, defer, yield, []
{
}
}
@ -589,7 +561,41 @@ ircd::ios::dispatch::dispatch(descriptor &descriptor,
}
ircd::ios::dispatch::dispatch(descriptor &descriptor,
synchronous_t,
defer_t,
yield_t,
const std::function<void ()> &function)
{
const ctx::uninterruptible::nothrow ui;
ctx::latch latch{1};
dispatch
{
descriptor, defer, [&function, &latch]
{
const unwind uw
{
[&latch]
{
latch.count_down();
}
};
function();
}
};
latch.wait();
}
[[gnu::hot]]
ircd::ios::dispatch::dispatch(descriptor &descriptor,
defer_t,
std::function<void ()> function)
{
boost::asio::post(get(), handle(descriptor, std::move(function)));
}
ircd::ios::dispatch::dispatch(descriptor &descriptor,
yield_t,
const std::function<void ()> &function)
{
assert(function);
@ -635,145 +641,3 @@ ircd::ios::dispatch::dispatch(descriptor &descriptor,
assert(!ctx::current && handler::current == parent);
}
//
// defer
//
namespace ircd::ios
{
extern descriptor defer_desc;
}
decltype(ircd::ios::defer_desc)
ircd::ios::defer_desc
{
"ircd.ios.defer",
};
[[gnu::hot]]
ircd::ios::defer::defer(std::function<void ()> function)
:defer
{
defer_desc, std::move(function)
}
{
}
ircd::ios::defer::defer(synchronous_t,
const std::function<void ()> &function)
:defer
{
defer_desc, synchronous, function
}
{
}
ircd::ios::defer::defer(descriptor &descriptor,
synchronous_t)
:defer
{
descriptor, synchronous, []
{
}
}
{
}
ircd::ios::defer::defer(descriptor &descriptor,
synchronous_t,
const std::function<void ()> &function)
{
const ctx::uninterruptible::nothrow ui;
ctx::latch latch(1);
defer(descriptor, [&function, &latch]
{
const unwind uw{[&latch]
{
latch.count_down();
}};
function();
});
latch.wait();
}
[[gnu::hot]]
ircd::ios::defer::defer(descriptor &descriptor,
std::function<void ()> function)
{
boost::asio::defer(get(), handle(descriptor, std::move(function)));
}
//
// post
//
namespace ircd::ios
{
extern descriptor post_desc;
}
decltype(ircd::ios::post_desc)
ircd::ios::post_desc
{
"ircd.ios.post"
};
[[gnu::hot]]
ircd::ios::post::post(std::function<void ()> function)
:post
{
post_desc, std::move(function)
}
{
}
ircd::ios::post::post(synchronous_t,
const std::function<void ()> &function)
:post
{
post_desc, synchronous, function
}
{
}
ircd::ios::post::post(descriptor &descriptor,
synchronous_t)
:post
{
descriptor, synchronous, []
{
}
}
{
}
ircd::ios::post::post(descriptor &descriptor,
synchronous_t,
const std::function<void ()> &function)
{
const ctx::uninterruptible::nothrow ui;
ctx::latch latch(1);
post(descriptor, [&function, &latch]
{
const unwind uw{[&latch]
{
latch.count_down();
}};
function();
});
latch.wait();
}
[[gnu::hot]]
ircd::ios::post::post(descriptor &descriptor,
std::function<void ()> function)
{
boost::asio::post(get(), handle(descriptor, std::move(function)));
}

View File

@ -458,7 +458,7 @@ ircd::log::vlog_threadsafe(const log &log,
// The pointer to the logger is copied to the main thread.
auto *const logp{&log};
ircd::post(descriptor, [lev, str(std::move(str)), logp]
ircd::dispatch{descriptor, ios::defer, [lev, str(std::move(str)), logp]
{
// If that named logger was destroyed while this closure was
// travelling to the main thread then we just discard this message.
@ -469,7 +469,7 @@ ircd::log::vlog_threadsafe(const log &log,
{
return copy(out, string_view{str});
});
});
}};
}
ircd::log::vlog::vlog(const log &log,

View File

@ -1543,10 +1543,10 @@ try
static const ilist<mutable_buffer> bufs{buf};
if(SSL_peek(ssl.native_handle(), buf, sizeof(buf)) > 0)
{
ircd::post(desc_wait[1], [handle(std::move(handle))]
ircd::dispatch{desc_wait[1], ios::defer, [handle(std::move(handle))]
{
handle(error_code{});
});
}};
return;
}

View File

@ -696,6 +696,16 @@ decltype(ircd::server::peers)
ircd::server::peers
{};
//
// server::peer
//
decltype(ircd::server::peer::close_desc)
ircd::server::peer::close_desc
{
"ircd.server.peer.close"
};
decltype(ircd::server::peer::enable_ipv6)
ircd::server::peer::enable_ipv6
{
@ -1244,10 +1254,13 @@ noexcept try
if(err_has())
{
// The peer can't be closed quite yet b/c the tag hasn't finished.
defer{[this]
ircd::dispatch
{
close();
}};
close_desc, ios::defer, [this]
{
close();
}
};
return;
}

View File

@ -445,9 +445,14 @@ ircd::util::a2u(const mutable_buffer &out,
ircd::util::unwind_defer::~unwind_defer()
noexcept
{
ircd::defer
static ios::descriptor descriptor
{
std::move(func)
"ircd.unwind"
};
ircd::dispatch
{
descriptor, ios::defer, std::move(func)
};
}

View File

@ -1814,12 +1814,30 @@ console_cmd__ios__history(opt &out, const string_view &line)
bool
console_cmd__ios__depth(opt &out, const string_view &line)
{
static ios::descriptor dispatch_desc
{
"ircd.console.depth.dispatch",
};
static ios::descriptor post_desc
{
"ircd.console.depth.post",
};
static ios::descriptor defer_desc
{
"ircd.console.latency.defer",
nullptr,
nullptr,
true,
};
uint64_t returned, executed, started;
// ios::dispatch
{
started = ios::epoch();
ios::dispatch(ios::synchronous, [&executed]
ios::dispatch(dispatch_desc, ios::yield, [&executed]
{
executed = ios::epoch();
});
@ -1833,27 +1851,10 @@ console_cmd__ios__depth(opt &out, const string_view &line)
<< "disp rtt: " << (returned - started) << std::endl
<< std::endl;
// ios::defer
{
started = ios::epoch();
ios::defer(ios::synchronous, [&executed]
{
executed = ios::epoch();
});
returned = ios::epoch();
}
out
<< "defer send: " << (executed - started) << std::endl
<< "defer recv: " << (returned - executed) << std::endl
<< "defer rtt: " << (returned - started) << std::endl
<< std::endl;
// ios::post
{
started = ios::epoch();
ios::post(ios::synchronous, [&executed]
ios::dispatch(post_desc, ios::defer, ios::yield, [&executed]
{
executed = ios::epoch();
});
@ -1867,6 +1868,23 @@ console_cmd__ios__depth(opt &out, const string_view &line)
<< "post rtt: " << (returned - started) << std::endl
<< std::endl;
// ios::defer
{
started = ios::epoch();
ios::dispatch(defer_desc, ios::defer, ios::yield, [&executed]
{
executed = ios::epoch();
});
returned = ios::epoch();
}
out
<< "defer send: " << (executed - started) << std::endl
<< "defer recv: " << (returned - executed) << std::endl
<< "defer rtt: " << (returned - started) << std::endl
<< std::endl;
return true;
}
@ -1874,7 +1892,25 @@ console_cmd__ios__depth(opt &out, const string_view &line)
bool
console_cmd__ios__latency(opt &out, const string_view &line)
{
volatile long long returned, executed, started;
static ios::descriptor dispatch_desc
{
"ircd.console.latency.dispatch"
};
static ios::descriptor post_desc
{
"ircd.console.latency.post"
};
static ios::descriptor defer_desc
{
"ircd.console.latency.defer",
nullptr,
nullptr,
true,
};
long long returned, executed, started;
// control
{
@ -1910,7 +1946,7 @@ console_cmd__ios__latency(opt &out, const string_view &line)
started = prof::cycles();
asm volatile ("lfence");
ios::dispatch(ios::synchronous, [&executed]
ios::dispatch(dispatch_desc, ios::yield, [&executed]
{
__sync_synchronize();
asm volatile ("lfence");
@ -1930,36 +1966,6 @@ console_cmd__ios__latency(opt &out, const string_view &line)
<< "disp rtt: " << (returned - started) << std::endl
<< std::endl;
//
// ios::defer
//
{
__sync_synchronize();
asm volatile ("lfence");
started = prof::cycles();
asm volatile ("lfence");
ios::defer(ios::synchronous, [&executed]
{
__sync_synchronize();
asm volatile ("lfence");
executed = prof::cycles();
asm volatile ("lfence");
});
__sync_synchronize();
asm volatile ("lfence");
returned = prof::cycles();
asm volatile ("lfence");
}
out
<< "defer send: " << (executed - started) << std::endl
<< "defer recv: " << (returned - executed) << std::endl
<< "defer rtt: " << (returned - started) << std::endl
<< std::endl;
//
// ios::post
//
@ -1970,7 +1976,7 @@ console_cmd__ios__latency(opt &out, const string_view &line)
started = prof::cycles();
asm volatile ("lfence");
ios::post(ios::synchronous, [&executed]
ios::dispatch(post_desc, ios::defer, ios::yield, [&executed]
{
__sync_synchronize();
asm volatile ("lfence");
@ -1990,6 +1996,36 @@ console_cmd__ios__latency(opt &out, const string_view &line)
<< "post rtt: " << (returned - started) << std::endl
<< std::endl;
//
// ios::defer
//
{
__sync_synchronize();
asm volatile ("lfence");
started = prof::cycles();
asm volatile ("lfence");
ios::dispatch(defer_desc, ios::defer, ios::yield, [&executed]
{
__sync_synchronize();
asm volatile ("lfence");
executed = prof::cycles();
asm volatile ("lfence");
});
__sync_synchronize();
asm volatile ("lfence");
returned = prof::cycles();
asm volatile ("lfence");
}
out
<< "defer send: " << (executed - started) << std::endl
<< "defer recv: " << (returned - executed) << std::endl
<< "defer rtt: " << (returned - started) << std::endl
<< std::endl;
return true;
}
#endif

View File

@ -34,13 +34,13 @@ _cmd__die(const m::event &event,
{
static ios::descriptor descriptor
{
"s_control die"
"ircd.m.control.die"
};
ircd::post(descriptor, []
ircd::dispatch
{
ircd::quit();
});
descriptor, ios::defer, ircd::quit
};
ctx::yield();
}