From b207b9e909c05e10d770c7cabe27440cd176e8e7 Mon Sep 17 00:00:00 2001 From: Jason Volk Date: Fri, 22 Sep 2017 13:57:43 -0700 Subject: [PATCH] ircd: Rename ircd::scope to ircd::unwind. --- charybdis/console.cc | 2 +- include/ircd/ctx/dock.h | 12 +++--- include/ircd/ctx/queue.h | 6 +-- include/ircd/ctx/view.h | 2 +- include/ircd/js/context.h | 2 +- include/ircd/util.h | 79 +++++++++++++++++++++++++-------------- ircd/ctx.cc | 8 ++-- ircd/http.cc | 4 +- ircd/ircd.cc | 2 +- ircd/js.cc | 4 +- ircd/logger.cc | 2 +- ircd/mods.cc | 2 +- 12 files changed, 74 insertions(+), 51 deletions(-) diff --git a/charybdis/console.cc b/charybdis/console.cc index 44759b9ea..56996b3c6 100644 --- a/charybdis/console.cc +++ b/charybdis/console.cc @@ -135,7 +135,7 @@ try { using namespace ircd; - const scope atexit([] + const unwind atexit([] { console_active = false; console_in = nullptr; diff --git a/include/ircd/ctx/dock.h b/include/ircd/ctx/dock.h index f7547aa28..975777834 100644 --- a/include/ircd/ctx/dock.h +++ b/include/ircd/ctx/dock.h @@ -118,7 +118,7 @@ noexcept inline void ircd::ctx::dock::wait() { - const scope remove + const unwind remove { std::bind(&dock::remove_self, this) }; @@ -134,7 +134,7 @@ ircd::ctx::dock::wait(predicate&& pred) if(pred()) return; - const scope remove + const unwind remove { std::bind(&dock::remove_self, this) }; @@ -152,7 +152,7 @@ ircd::ctx::dock::wait_for(const duration &dur) { static const duration zero(0); - const scope remove + const unwind remove { std::bind(&dock::remove_self, this) }; @@ -173,7 +173,7 @@ ircd::ctx::dock::wait_for(const duration &dur, if(pred()) return true; - const scope remove + const unwind remove { std::bind(&dock::remove_self, this) }; @@ -195,7 +195,7 @@ template ircd::ctx::cv_status ircd::ctx::dock::wait_until(time_point&& tp) { - const scope remove + const unwind remove { std::bind(&dock::remove_self, this) }; @@ -214,7 +214,7 @@ ircd::ctx::dock::wait_until(time_point&& tp, if(pred()) return true; - const scope remove + const unwind remove { std::bind(&dock::remove_self, this) }; diff --git a/include/ircd/ctx/queue.h b/include/ircd/ctx/queue.h index 870b23be6..476924373 100644 --- a/include/ircd/ctx/queue.h +++ b/include/ircd/ctx/queue.h @@ -93,7 +93,7 @@ ircd::ctx::queue::pop() return !q.empty(); }); - const scope pop([this] + const unwind pop([this] { q.pop(); }); @@ -115,7 +115,7 @@ ircd::ctx::queue::pop_for(const duration &dur) if(status == cv_status::timeout) throw timeout(); - const scope pop([this] + const unwind pop([this] { q.pop(); }); @@ -137,7 +137,7 @@ ircd::ctx::queue::pop_until(time_point&& tp) if(status == cv_status::timeout) throw timeout(); - const scope pop([this] + const unwind pop([this] { q.pop(); }); diff --git a/include/ircd/ctx/view.h b/include/ircd/ctx/view.h index 4a9f3df02..db94039a2 100644 --- a/include/ircd/ctx/view.h +++ b/include/ircd/ctx/view.h @@ -80,7 +80,7 @@ template void ircd::ctx::view::notify(T &t) { - const scope afterward{[this] + const unwind afterward{[this] { assert(a.empty()); this->t = nullptr; diff --git a/include/ircd/js/context.h b/include/ircd/js/context.h index 2aa8c7b8b..6c762d15c 100644 --- a/include/ircd/js/context.h +++ b/include/ircd/js/context.h @@ -184,7 +184,7 @@ run(F&& function) assert(!pending_exception(*cx)); enter(*cx); - const scope out([] + const unwind out([] { leave(*cx); }); diff --git a/include/ircd/util.h b/include/ircd/util.h index 99d6ccbb9..38c81a410 100644 --- a/include/ircd/util.h +++ b/include/ircd/util.h @@ -79,7 +79,14 @@ enum class init_priority #define IRCD_INIT_PRIORITY(name) \ __attribute__((init_priority(int(ircd::init_priority::name)))) -struct scope + +/// +/// Fundamental scope-unwind utilities establishing actions during destruction +/// + +/// Unconditionally executes the provided code when the object goes out of scope. +/// +struct unwind { struct nominal; struct exceptional; @@ -87,48 +94,64 @@ struct scope const std::function func; template - scope(F &&func): func(std::forward(func)) {} - scope() = default; - scope(const scope &) = delete; - scope &operator=(const scope &) = delete; - ~scope() noexcept + unwind(F &&func) + :func{std::forward(func)} + {} + + unwind(const unwind &) = delete; + unwind &operator=(const unwind &) = delete; + ~unwind() noexcept { func(); } }; -struct scope::nominal -:scope +/// Executes function only if the unwind takes place without active exception +/// +/// The function is expected to be executed and the likely() should pipeline +/// that branch and make this device cheaper to use under normal circumstances. +/// +struct unwind::nominal { + const std::function func; + template nominal(F &&func) - :scope - { - [func(std::forward(func))] - { - if(likely(!std::uncaught_exception())) - func(); - } - }{} + :func{std::forward(func)} + {} - nominal() = default; + ~nominal() noexcept + { + if(likely(!std::uncaught_exception())) + func(); + } + + nominal(const nominal &) = delete; }; -struct scope::exceptional -:scope +/// Executes function only if unwind is taking place because exception thrown +/// +/// The unlikely() intends for the cost of a branch misprediction to be paid +/// for fetching and executing this function. This is because we strive to +/// optimize the pipeline for the nominal path, making this device as cheap +/// as possible to use. +/// +struct unwind::exceptional { + const std::function func; + template exceptional(F &&func) - :scope - { - [func(std::forward(func))] - { - if(unlikely(std::uncaught_exception())) - func(); - } - }{} + :func{std::forward(func)} + {} - exceptional() = default; + ~exceptional() noexcept + { + if(unlikely(std::uncaught_exception())) + func(); + } + + exceptional(const exceptional &) = delete; }; diff --git a/ircd/ctx.cc b/ircd/ctx.cc index 4016c6994..177c9224f 100644 --- a/ircd/ctx.cc +++ b/ircd/ctx.cc @@ -101,7 +101,7 @@ noexcept ircd::ctx::current = this; mark(prof::event::CUR_ENTER); - const scope atexit([this] + const unwind atexit([this] { mark(prof::event::CUR_LEAVE); @@ -428,7 +428,7 @@ ircd::ctx::context::context(const char *const &name, }); // The current context must be reasserted if spawn returns here - const scope recurrent([current(ircd::ctx::current)] + const unwind recurrent([current(ircd::ctx::current)] { ircd::ctx::current = current; }); @@ -584,7 +584,7 @@ ircd::ctx::pool::main() try { ++available; - const scope avail([this] + const unwind avail([this] { --available; }); @@ -610,7 +610,7 @@ try }); --available; - const scope avail([this] + const unwind avail([this] { ++available; }); diff --git a/ircd/http.cc b/ircd/http.cc index d03cdbb88..a8c2c58ec 100644 --- a/ircd/http.cc +++ b/ircd/http.cc @@ -260,7 +260,7 @@ try { const head h{pc, headers_closure}; const char *const content_mark(pc.parsed); - const scope discard_unused_content{[&pc, &h, &content_mark] + const unwind discard_unused_content{[&pc, &h, &content_mark] { const size_t consumed(pc.parsed - content_mark); const size_t remain(h.content_length - consumed); @@ -369,7 +369,7 @@ ircd::http::response::response(parse::capstan &pc, { const head h{pc, headers_closure}; const char *const content_mark(pc.parsed); - const scope discard_unused_content{[&pc, &h, &content_mark] + const unwind discard_unused_content{[&pc, &h, &content_mark] { const size_t consumed(pc.parsed - content_mark); const size_t remain(h.content_length - consumed); diff --git a/ircd/ircd.cc b/ircd/ircd.cc index 4ef45ab90..c1336a4b9 100644 --- a/ircd/ircd.cc +++ b/ircd/ircd.cc @@ -99,7 +99,7 @@ ircd::main() try { log::debug("IRCd entered main context."); - const scope main_exit(&main_exiting); // The user is notified when this function ends + const unwind main_exit(&main_exiting); // The user is notified when this function ends // These objects are the init()'s and fini()'s for each subsystem. Appearing here ties their life // to the main context. Initialization can also occur in ircd::init() or static initialization diff --git a/ircd/js.cc b/ircd/js.cc index cb928ae01..18e3e3b7f 100644 --- a/ircd/js.cc +++ b/ircd/js.cc @@ -72,7 +72,7 @@ ircd::js::init::init() "SpiderMonkey", version(ver::IMPLEMENTATION)); - const scope exit([this] + const unwind exit([this] { // Ensure ~init() is always safe to call at any intermediate state if(std::current_exception()) @@ -3348,7 +3348,7 @@ noexcept // After the interrupt is handled the phase indicates entry back to JS, // IRQ is left indicating JS in case we don't trigger the next interrupt. - const scope interrupt_return([&c, &state] + const unwind interrupt_return([&c, &state] { state.phase = phase::ENTER; state.irq = irq::JS; diff --git a/ircd/logger.cc b/ircd/logger.cc index 9c1770f9f..02a80028b 100644 --- a/ircd/logger.cc +++ b/ircd/logger.cc @@ -274,7 +274,7 @@ ircd::log::slog(const facility &fac, if(!file[fac].is_open() && !console_out[fac] && !console_err[fac]) return; - const scope always_newline([&fac] + const unwind always_newline([&fac] { suffix(fac); }); diff --git a/ircd/mods.cc b/ircd/mods.cc index 7e1878476..c822b5e6d 100644 --- a/ircd/mods.cc +++ b/ircd/mods.cc @@ -650,7 +650,7 @@ try } }); - const scope reset{[this, &theirs] + const unwind reset{[this, &theirs] { assert(loading.top() == this); loading.pop();