diff --git a/include/ircd/ctx/ole.h b/include/ircd/ctx/ole.h index 2d2469514..d11738e34 100644 --- a/include/ircd/ctx/ole.h +++ b/include/ircd/ctx/ole.h @@ -20,8 +20,11 @@ namespace ircd::ctx::ole { struct init; + struct opts; + struct control; + using closure = std::function; - void offload(const std::function &); + void offload(const opts &, const closure &); } namespace ircd::ctx @@ -29,6 +32,18 @@ namespace ircd::ctx using ole::offload; } +struct ircd::ctx::ole::opts +{ + /// Optionally give this offload task a name for any tasklist. + string_view name; + + /// The function will be executed on each thread. + size_t concurrency {1}; + + /// Queuing priority; in the form of a nice value. + int8_t prio {0}; +}; + struct ircd::ctx::ole::init { init(); diff --git a/ircd/ctx_ole.cc b/ircd/ctx_ole.cc index 11ecda832..a728a9bb7 100644 --- a/ircd/ctx_ole.cc +++ b/ircd/ctx_ole.cc @@ -13,8 +13,6 @@ namespace ircd::ctx::ole { - using closure = std::function; - extern conf::item thread_max; std::mutex mutex; @@ -54,8 +52,11 @@ noexcept } void -ircd::ctx::ole::offload(const std::function &func) +ircd::ctx::ole::offload(const opts &opts, + const closure &func) { + assert(opts.concurrency == 1); // not yet implemented + bool done(false); auto *const context(current); const auto kick([&context, &done] @@ -85,6 +86,10 @@ ircd::ctx::ole::offload(const std::function &func) // to another thread. This context must stay right here and not disappear // until the other thread signals back. Note that the destructor is // capable of throwing an interrupt that was received during this scope. + // + // Don't throw any exception if there is a pending interrupt for this ctx. + // Two exceptions will be thrown in that case and if there's an interrupt + // we don't care about eptr anyway. const uninterruptible uninterruptible; push(std::move(closure)); do @@ -93,13 +98,12 @@ ircd::ctx::ole::offload(const std::function &func) } while(!done); - // Don't throw any exception if there is a pending interrupt for this ctx. - // Two exceptions will be thrown in that case and if there's an interrupt - // we don't care about eptr anyway. - if(eptr && likely(!interruption_requested())) + if(unlikely(interruption_requested())) + return; + + if(eptr) std::rethrow_exception(eptr); } - void ircd::ctx::ole::push(closure &&func) {