From d7b465ce74235cd035eddb478863109c0d034cd1 Mon Sep 17 00:00:00 2001 From: "Alexander A. Klimov" Date: Fri, 15 Feb 2019 12:25:25 +0100 Subject: [PATCH] Implement IoBoundWorkSlot --- lib/base/io-engine.cpp | 23 +++++++++++++++++++++++ lib/base/io-engine.hpp | 20 ++++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/lib/base/io-engine.cpp b/lib/base/io-engine.cpp index 482d57176..daad42df0 100644 --- a/lib/base/io-engine.cpp +++ b/lib/base/io-engine.cpp @@ -64,6 +64,29 @@ void CpuBoundWork::Done() } } +IoBoundWorkSlot::IoBoundWorkSlot(boost::asio::yield_context yc) + : yc(yc) +{ + IoEngine::Get().m_CpuBoundSemaphore.fetch_add(1); +} + +IoBoundWorkSlot::~IoBoundWorkSlot() +{ + auto& ioEngine (IoEngine::Get()); + + for (;;) { + auto availableSlots (ioEngine.m_CpuBoundSemaphore.fetch_sub(1)); + + if (availableSlots < 1) { + ioEngine.m_CpuBoundSemaphore.fetch_add(1); + ioEngine.m_AlreadyExpiredTimer.async_wait(yc); + continue; + } + + break; + } +} + LazyInit> IoEngine::m_Instance ([]() { return std::unique_ptr(new IoEngine()); }); IoEngine& IoEngine::Get() diff --git a/lib/base/io-engine.hpp b/lib/base/io-engine.hpp index efeb56f99..ada80d1ca 100644 --- a/lib/base/io-engine.hpp +++ b/lib/base/io-engine.hpp @@ -55,6 +55,25 @@ private: bool m_Done; }; +/** + * Scope break for CPU-bound work done in an I/O thread + * + * @ingroup base + */ +class IoBoundWorkSlot +{ +public: + IoBoundWorkSlot(boost::asio::yield_context yc); + IoBoundWorkSlot(const IoBoundWorkSlot&) = delete; + IoBoundWorkSlot(IoBoundWorkSlot&&) = delete; + IoBoundWorkSlot& operator=(const IoBoundWorkSlot&) = delete; + IoBoundWorkSlot& operator=(IoBoundWorkSlot&&) = delete; + ~IoBoundWorkSlot(); + +private: + boost::asio::yield_context yc; +}; + /** * Async I/O engine * @@ -63,6 +82,7 @@ private: class IoEngine { friend CpuBoundWork; + friend IoBoundWorkSlot; public: IoEngine(const IoEngine&) = delete;