diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 1001eac0e25ed0f9aaa66b1f0a834774364c8419..566199a5833532227224f7e1bf07bf56d0c4da87 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -163,6 +163,10 @@ clang-tidy: variables: EMPER_WAKEUP_SEMAPHORE_IMPLEMENTATION: "locked" +.set-affinity-on-block: + variables: + EMPER_SET_AFFINITY_ON_BLOCK: 'true' + test-gcc: extends: - .test @@ -258,3 +262,8 @@ test-locked-wakeup-semaphore: extends: - .test - .locked-wakeup-semaphore + +test-set-affinity-on-block: + extends: + - .test + - .set-affinity-on-block diff --git a/emper/Blockable.hpp b/emper/Blockable.hpp index 90a51a9332478848636b9fdb1c3d0890cce5cf49..403a1c56bc81bf351ad584f9f0eb14d09d46ea5b 100644 --- a/emper/Blockable.hpp +++ b/emper/Blockable.hpp @@ -24,8 +24,31 @@ class Blockable : public Logger<logSubsystem> { workeraffinity_t* affinity = nullptr; + // It would be OK to not initialize this member since it is only set + // and read after affinity has been set to a non nullptr + // value. However, if we do not set it, then clang-tidy complains + // about clang-analyzer-optin.cplusplus.UninitializedObject. + workeraffinity_t affinity_buffer = Fiber::NOT_AFFINE; + Blockable(Runtime& runtime) : runtime(runtime), contextManager(runtime.getContextManager()) {} + void maybeSetAffinity() { + if constexpr (!emper::SET_AFFINITY_ON_BLOCK) return; + + // TODO: At some point we may want to have something like + // Runtime::isAffinityCapable() and return here if it is + // not. Although I am not sure if it is worth the overhead. + + auto* currentFiber = Context::getCurrentFiber(); + auto* affinity = currentFiber->getAffinityBuffer(); + if (affinity) { + this->affinity = affinity; + } else { + affinity_buffer = Runtime::getWorkerId(); + this->affinity = &affinity_buffer; + } + } + // Older clang-tidy versions show a // performance-unnecessary-value-param, newer versions do not show // this error if std::move() is used (as we do). @@ -36,6 +59,8 @@ class Blockable : public Logger<logSubsystem> { LOGD("block() blockedContext is " << Context::getCurrentContext()); + maybeSetAffinity(); + if constexpr (emper::BLOCKED_CONTEXT_SET) { blockedContexts.insert(Context::getCurrentContext()); } diff --git a/emper/Context.hpp b/emper/Context.hpp index a010c897ee5e023cbf16daa2198483be8488383d..9f1a9436d4171de854fb8794b8b28c598ef680c2 100644 --- a/emper/Context.hpp +++ b/emper/Context.hpp @@ -78,12 +78,6 @@ class ALIGN_TO_CACHE_LINE Context : Logger<LogSubsystem::C> { currentContext->currentFiber = fiber; } - static auto getCurrentFiber() -> Fiber* { - assert(currentContext); - - return currentContext->currentFiber; - } - public: // cppcheck-suppress noExplicitConstructor selfInitialization Context(func_t mainFunction) @@ -126,6 +120,12 @@ class ALIGN_TO_CACHE_LINE Context : Logger<LogSubsystem::C> { // VALGRIND_STACK_DEREGISTER(valgrindStackId); } + static auto getCurrentFiber() -> Fiber* { + assert(currentContext); + + return currentContext->currentFiber; + } + inline void setEmptyHook() { startAndResumeHook = []() {}; } diff --git a/emper/Emper.hpp b/emper/Emper.hpp index 9c7e0664fa62e4adf249adfdfb2a0ae9392799ec..30d9dfca2416fddae8aa088730d5a70108d6d45f 100644 --- a/emper/Emper.hpp +++ b/emper/Emper.hpp @@ -113,4 +113,13 @@ enum class IoCompleterBehavior { static const enum IoCompleterBehavior IO_COMPLETER_BEHAVIOR = IoCompleterBehavior::EMPER_IO_COMPLETER_BEHAVIOR; + +static const bool SET_AFFINITY_ON_BLOCK = +#ifdef EMPER_SET_AFFINITY_ON_BLOCK + true +#else + false +#endif + ; + } // namespace emper diff --git a/emper/Fiber.hpp b/emper/Fiber.hpp index 01b6fba88c8408c3a1a40b9e149853c972a6947e..7caf6080b50f17aa05747465529f03e829356992 100644 --- a/emper/Fiber.hpp +++ b/emper/Fiber.hpp @@ -95,6 +95,8 @@ class ALIGN_TO_CACHE_LINE Fiber : public Logger<LogSubsystem::F> { return --referenceCounter; } + template <LogSubsystem> + friend class Blockable; friend class adt::MpscQueue<Fiber>; friend class Scheduler; friend class Dispatcher; diff --git a/meson_options.txt b/meson_options.txt index ac1f842cd90c82f09a9b80c5cd3538b34b724f9b..7f6f6c98ea6889cac8e462fa7b525ead26ea3d8f 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -129,3 +129,9 @@ option( choices: ['schedule', 'maybe_wakeup'], value: 'schedule', ) +option( + 'set_affinity_on_block', + type: 'boolean', + value: false, + description: 'Set the affinity when blocking', +)