diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/core-files.json | 1 | ||||
-rw-r--r-- | src/mbgl/util/thread_pool.cpp | 83 |
2 files changed, 84 insertions, 0 deletions
diff --git a/src/core-files.json b/src/core-files.json index 4521457bb1..dbca83c029 100644 --- a/src/core-files.json +++ b/src/core-files.json @@ -297,6 +297,7 @@ "src/mbgl/util/rapidjson.cpp", "src/mbgl/util/stopwatch.cpp", "src/mbgl/util/string.cpp", + "src/mbgl/util/thread_pool.cpp", "src/mbgl/util/tile_cover.cpp", "src/mbgl/util/tile_cover_impl.cpp", "src/mbgl/util/tiny_sdf.cpp", diff --git a/src/mbgl/util/thread_pool.cpp b/src/mbgl/util/thread_pool.cpp new file mode 100644 index 0000000000..d213aab71c --- /dev/null +++ b/src/mbgl/util/thread_pool.cpp @@ -0,0 +1,83 @@ +#include <mbgl/actor/scheduler.hpp> +#include <mbgl/actor/mailbox.hpp> +#include <mbgl/util/platform.hpp> +#include <mbgl/util/string.hpp> + +#include <condition_variable> +#include <mutex> +#include <queue> +#include <thread> + +namespace mbgl { + +class ThreadPool final : public Scheduler { +public: + explicit ThreadPool(std::size_t count); + ~ThreadPool() override; + + void schedule(std::weak_ptr<Mailbox>) override; + +private: + std::vector<std::thread> threads; + std::queue<std::weak_ptr<Mailbox>> queue; + std::mutex mutex; + std::condition_variable cv; + bool terminate { false }; +}; + +ThreadPool::ThreadPool(std::size_t count) { + threads.reserve(count); + + for (std::size_t i = 0; i < count; ++i) { + threads.emplace_back([this, i]() { + platform::setCurrentThreadName(std::string{ "Worker " } + util::toString(i + 1)); + + while (true) { + std::unique_lock<std::mutex> lock(mutex); + + cv.wait(lock, [this] { + return !queue.empty() || terminate; + }); + + if (terminate) { + return; + } + + auto mailbox = queue.front(); + queue.pop(); + lock.unlock(); + + Mailbox::maybeReceive(mailbox); + } + }); + } +} + +ThreadPool::~ThreadPool() { + { + std::lock_guard<std::mutex> lock(mutex); + terminate = true; + } + + cv.notify_all(); + + for (auto& thread : threads) { + thread.join(); + } +} + +void ThreadPool::schedule(std::weak_ptr<Mailbox> mailbox) { + { + std::lock_guard<std::mutex> lock(mutex); + queue.push(mailbox); + } + + cv.notify_one(); +} + +Scheduler& Scheduler::GetBackground() { + static std::unique_ptr<ThreadPool> pool(new ThreadPool(4)); + return *pool; +} + +} // namespace mbgl |