diff --git a/emper/io/IoContext.cpp b/emper/io/IoContext.cpp index 6768524fc08384646cd69541a84a0cb3aae805ee..90a5992392261af6d091983d90481ee6f7e0a942 100644 --- a/emper/io/IoContext.cpp +++ b/emper/io/IoContext.cpp @@ -179,7 +179,7 @@ template void IoContext::submit<CallerEnvironment::ANYWHERE>(Future &future); template <CallerEnvironment callerEnvironment> void IoContext::reapCompletions() { // Someone else is currently reaping completions - if (unlikely(!cq_mutex.try_lock())) { + if (unlikely(!cq_lock.try_lock())) { return; } @@ -254,7 +254,7 @@ void IoContext::reapCompletions() { } unlock: - cq_mutex.unlock(); + cq_lock.unlock(); } // Show the compiler our template incarnations diff --git a/emper/io/IoContext.hpp b/emper/io/IoContext.hpp index 37081f41212058bc9aee13f139288cd5b8c559d4..4031c963308c4cee757facdcfc4c8c2cd7796bcb 100644 --- a/emper/io/IoContext.hpp +++ b/emper/io/IoContext.hpp @@ -11,13 +11,13 @@ #include <cstdint> // for uint64_t #include <functional> // for less #include <memory> // for allocator -#include <mutex> // for mutex #include "CallerEnvironment.hpp" // for CallerEnvironment, EMPER #include "Debug.hpp" // for LogSubsystem, LogSubsystem::IO, Logger #include "Runtime.hpp" // for Runtime #include "emper-config.h" // for EMPER_IO_WORKER_URING_ENTRIES #include "io/Stats.hpp" // for Stats +#include "lib/adt/AtomicTryLock.hpp" #include "lib/adt/LockedSet.hpp" // for LockedSet namespace emper::io { @@ -44,9 +44,8 @@ class IoContext : public Logger<LogSubsystem::IO> { // to the global IoContext static void startGlobalCompleter(IoContext &globalIo); - // Mutex protecting the completion queue of ring. - // It is used with try_lock() in reapCompletions. - std::mutex cq_mutex; + // TryLock protecting the completion queue of ring. + lib::adt::AtomicTryLock cq_lock; struct io_uring ring; // eventfd registered with ring. diff --git a/emper/lib/adt/AtomicTryLock.hpp b/emper/lib/adt/AtomicTryLock.hpp new file mode 100644 index 0000000000000000000000000000000000000000..222d80e70c9ddf60dad68ea99e3c20541bff867e --- /dev/null +++ b/emper/lib/adt/AtomicTryLock.hpp @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: LGPL-3.0-or-later +// Copyright © 2020 Florian Fischer +#pragma once + +#include <atomic> + +#include "Common.hpp" + +namespace emper::lib::adt { + +class ALIGN_TO_CACHE_LINE AtomicTryLock { + private: + std::atomic<bool> locked; + + public: + AtomicTryLock(bool locked = false) : locked(locked) {} + + auto try_lock() -> bool { + bool previously_locked = locked.exchange(true, std::memory_order_acquire); + return !previously_locked; + } + + void unlock() { locked.store(false, std::memory_order_release); } +}; +} // namespace emper::lib::adt