diff --git a/emper/io/IoContext.cpp b/emper/io/IoContext.cpp index b34c5e128d01b665817879b22b18c7a4261c56d4..83ab7001cea8358dbd3afc683c35fc6b1b81a2c0 100644 --- a/emper/io/IoContext.cpp +++ b/emper/io/IoContext.cpp @@ -211,24 +211,26 @@ reap_cqes: LOGD("Reaping completions for worker " << std::to_string(worker->getWorkerId())); std::array<struct io_uring_cqe *, CQE_BATCH_COUNT> cqes; - // Someone else is currently reaping completions - if constexpr (callerEnvironment == CallerEnvironment::EMPER) { - if (unlikely(!cq_lock.try_lock())) { - LOGD("worker unsuccessful try_lock"); - return 0; - } - } else { - // We can not reap completions of this IoContext to not race - // with the sleeping worker. - if (waitInflight.load(std::memory_order_acquire)) { - LOGD("Not reaping worker " << std::to_string(worker->getWorkerId()) - << " since this worker is already waiting for its CQEs"); - return 0; - } + if constexpr (needsCqLock) { + // Someone else is currently reaping completions + if constexpr (callerEnvironment == CallerEnvironment::EMPER) { + if (unlikely(!cq_lock.try_lock())) { + LOGD("worker unsuccessful try_lock"); + return 0; + } + } else { + // We can not reap completions of this IoContext to not race + // with the sleeping worker. + if (waitInflight.load(std::memory_order_acquire)) { + LOGD("Not reaping worker " << std::to_string(worker->getWorkerId()) + << " since this worker is already waiting for its CQEs"); + return 0; + } - if (!cq_lock.try_lock_or_increment()) { - LOGD("Global completer unsuccessful try_lock_or_increment"); - return 0; + if (!cq_lock.try_lock_or_increment()) { + LOGD("Global completer unsuccessful try_lock_or_increment"); + return 0; + } } } @@ -245,7 +247,10 @@ reap_cqes: io_uring_cq_advance(&ring, count); - uint32_t globalCompleterAttempts = cq_lock.unlock(); + uint32_t globalCompleterAttempts; + if constexpr (needsCqLock) { + globalCompleterAttempts = cq_lock.unlock(); + } LOGD("got " << count << " cqes from worker " << worker->getWorkerId() << "'s io_uring"); @@ -336,7 +341,7 @@ reap_cqes: } // check if lost wakeup was possible - if constexpr (callerEnvironment == CallerEnvironment::EMPER) { + if constexpr (needsCqLock && callerEnvironment == CallerEnvironment::EMPER) { bool reReap = false; // TODO: How sure are we that this is unlikely? if (unlikely(globalCompleterAttempts > maxRaceFreeCompleterAttempts)) { diff --git a/emper/io/IoContext.hpp b/emper/io/IoContext.hpp index 841246ecc732fdff1c173e9ef0626bedacc8553a..f849bb6f50540cfbdf30c455095df932c5057381 100644 --- a/emper/io/IoContext.hpp +++ b/emper/io/IoContext.hpp @@ -68,6 +68,8 @@ class IoContext : public Logger<LogSubsystem::IO> { Runtime &runtime; static thread_local IoContext *workerIo; + static constexpr bool needsCqLock = + emper::IO_COMPLETER_BEHAVIOR != emper::IoCompleterBehavior::none; // TryLock protecting the completion queue of ring. ALIGN_TO_CACHE_LINE CqLock cq_lock; struct io_uring ring;