From 07ec766ff929d9b082f915d81223148cac52d550 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Sun, 20 Dec 2020 05:13:18 -0800 Subject: [PATCH] ircd::ios: Consolidate dispatch/post/defer interfaces; minor fixes. --- construct/console.cc | 14 ++- construct/construct.cc | 9 +- construct/signals.cc | 2 +- include/ircd/ctx/this_ctx.h | 4 +- include/ircd/ios/dispatch.h | 35 ++---- include/ircd/ios/ios.h | 2 +- include/ircd/server/peer.h | 1 + ircd/ctx.cc | 37 ++++++- ircd/fs_aio.cc | 4 +- ircd/ios.cc | 212 +++++++----------------------------- ircd/logger.cc | 4 +- ircd/net.cc | 4 +- ircd/server.cc | 19 +++- ircd/util.cc | 9 +- modules/console.cc | 140 +++++++++++++++--------- modules/m_control.cc | 8 +- 16 files changed, 224 insertions(+), 280 deletions(-) diff --git a/construct/console.cc b/construct/console.cc index 990209a6a..a84d60b66 100644 --- a/construct/console.cc +++ b/construct/console.cc @@ -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; } diff --git a/construct/construct.cc b/construct/construct.cc index 55057fc8b..3113b0f1d 100644 --- a/construct/construct.cc +++ b/construct/construct.cc @@ -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 }; } }; diff --git a/construct/signals.cc b/construct/signals.cc index 82b023b45..43f77aef5 100644 --- a/construct/signals.cc +++ b/construct/signals.cc @@ -111,7 +111,7 @@ construct::signals::set_handle() { static ircd::ios::descriptor desc { - "construct::signals" + "construct.signals" }; auto handler diff --git a/include/ircd/ctx/this_ctx.h b/include/ircd/ctx/this_ctx.h index 40cd79e72..9c8d8a77b 100644 --- a/include/ircd/ctx/this_ctx.h +++ b/include/ircd/ctx/this_ctx.h @@ -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 }; } diff --git a/include/ircd/ios/dispatch.h b/include/ircd/ios/dispatch.h index 961202e70..4caa2372e 100644 --- a/include/ircd/ios/dispatch.h +++ b/include/ircd/ios/dispatch.h @@ -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); - dispatch(descriptor &, synchronous_t, const std::function &); - dispatch(descriptor &, synchronous_t); - dispatch(std::function); - dispatch(synchronous_t, const std::function &); -}; -struct ircd::ios::defer -{ - defer(descriptor &, std::function); - defer(descriptor &, synchronous_t, const std::function &); - defer(descriptor &, synchronous_t); - defer(std::function); - defer(synchronous_t, const std::function &); -}; + dispatch(descriptor &, yield_t, const std::function &); -struct ircd::ios::post -{ - post(descriptor &, std::function); - post(descriptor &, synchronous_t, const std::function &); - post(descriptor &, synchronous_t); - post(std::function); - post(synchronous_t, const std::function &); + dispatch(descriptor &, defer_t, std::function); + + dispatch(descriptor &, defer_t, yield_t, const std::function &); + + dispatch(descriptor &, defer_t, yield_t); }; diff --git a/include/ircd/ios/ios.h b/include/ircd/ios/ios.h index 095c3bf55..48c1b667b 100644 --- a/include/ircd/ios/ios.h +++ b/include/ircd/ios/ios.h @@ -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 & diff --git a/include/ircd/server/peer.h b/include/ircd/server/peer.h index 9f0ebdff6..cb9b3a17b 100644 --- a/include/ircd/server/peer.h +++ b/include/ircd/server/peer.h @@ -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 enable_ipv6; static conf::item link_min_default; static conf::item link_max_default; diff --git a/ircd/ctx.cc b/ircd/ctx.cc index 2d22b7e4b..de06bdeeb 100644 --- a/ircd/ctx.cc +++ b/ircd/ctx.cc @@ -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 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) diff --git a/ircd/fs_aio.cc b/ircd/fs_aio.cc index e90fb416c..a50ffd072 100644 --- a/ircd/fs_aio.cc +++ b/ircd/fs_aio.cc @@ -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) }; } diff --git a/ircd/ios.cc b/ircd/ios.cc index bec3b0dba..b7d456d82 100644 --- a/ircd/ios.cc +++ b/ircd/ios.cc @@ -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 function) -:dispatch -{ - dispatch_desc, std::move(function) -} -{ -} - -ircd::ios::dispatch::dispatch(synchronous_t, - const std::function &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 &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 function) +{ + boost::asio::post(get(), handle(descriptor, std::move(function))); +} + +ircd::ios::dispatch::dispatch(descriptor &descriptor, + yield_t, const std::function &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 function) -:defer -{ - defer_desc, std::move(function) -} -{ -} - -ircd::ios::defer::defer(synchronous_t, - const std::function &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 &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 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 function) -:post -{ - post_desc, std::move(function) -} -{ -} - -ircd::ios::post::post(synchronous_t, - const std::function &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 &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 function) -{ - boost::asio::post(get(), handle(descriptor, std::move(function))); -} diff --git a/ircd/logger.cc b/ircd/logger.cc index 941e31c04..a4a6e8cb4 100644 --- a/ircd/logger.cc +++ b/ircd/logger.cc @@ -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, diff --git a/ircd/net.cc b/ircd/net.cc index 261b55d6b..0e8b44680 100644 --- a/ircd/net.cc +++ b/ircd/net.cc @@ -1543,10 +1543,10 @@ try static const ilist 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; } diff --git a/ircd/server.cc b/ircd/server.cc index 309abd1c7..6da314143 100644 --- a/ircd/server.cc +++ b/ircd/server.cc @@ -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; } diff --git a/ircd/util.cc b/ircd/util.cc index fdb9631fe..287738934 100644 --- a/ircd/util.cc +++ b/ircd/util.cc @@ -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) }; } diff --git a/modules/console.cc b/modules/console.cc index 606d7cd5b..6243a70ac 100644 --- a/modules/console.cc +++ b/modules/console.cc @@ -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 diff --git a/modules/m_control.cc b/modules/m_control.cc index 3dff2c86c..2ff4d5e70 100644 --- a/modules/m_control.cc +++ b/modules/m_control.cc @@ -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(); }