diff options
Diffstat (limited to 'src/common')
| -rw-r--r-- | src/common/CMakeLists.txt | 2 | ||||
| -rw-r--r-- | src/common/thread_worker.cpp | 58 | ||||
| -rw-r--r-- | src/common/thread_worker.h | 30 | 
3 files changed, 90 insertions, 0 deletions
| diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index 943ff996e..5c8003eb1 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -162,6 +162,8 @@ add_library(common STATIC      thread.cpp      thread.h      thread_queue_list.h +    thread_worker.cpp +    thread_worker.h      threadsafe_queue.h      time_zone.cpp      time_zone.h diff --git a/src/common/thread_worker.cpp b/src/common/thread_worker.cpp new file mode 100644 index 000000000..8f9bf447a --- /dev/null +++ b/src/common/thread_worker.cpp @@ -0,0 +1,58 @@ +// Copyright 2020 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/thread.h" +#include "common/thread_worker.h" + +namespace Common { + +ThreadWorker::ThreadWorker(std::size_t num_workers, const std::string& name) { +    for (std::size_t i = 0; i < num_workers; ++i) +        threads.emplace_back([this, thread_name{std::string{name}}] { +            Common::SetCurrentThreadName(thread_name.c_str()); + +            // Wait for first request +            { +                std::unique_lock lock{queue_mutex}; +                condition.wait(lock, [this] { return stop || !requests.empty(); }); +            } + +            while (true) { +                std::function<void()> task; + +                { +                    std::unique_lock lock{queue_mutex}; +                    condition.wait(lock, [this] { return stop || !requests.empty(); }); +                    if (stop || requests.empty()) { +                        return; +                    } +                    task = std::move(requests.front()); +                    requests.pop(); +                } + +                task(); +            } +        }); +} + +ThreadWorker::~ThreadWorker() { +    { +        std::unique_lock lock{queue_mutex}; +        stop = true; +    } +    condition.notify_all(); +    for (std::thread& thread : threads) { +        thread.join(); +    } +} + +void ThreadWorker::QueueWork(std::function<void()>&& work) { +    { +        std::unique_lock lock{queue_mutex}; +        requests.emplace(work); +    } +    condition.notify_one(); +} + +} // namespace Common diff --git a/src/common/thread_worker.h b/src/common/thread_worker.h new file mode 100644 index 000000000..f1859971f --- /dev/null +++ b/src/common/thread_worker.h @@ -0,0 +1,30 @@ +// Copyright 2020 yuzu emulator team +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <atomic> +#include <functional> +#include <mutex> +#include <string> +#include <vector> +#include <queue> + +namespace Common { + +class ThreadWorker final { +public: +    explicit ThreadWorker(std::size_t num_workers, const std::string& name); +    ~ThreadWorker(); +    void QueueWork(std::function<void()>&& work); + +private: +    std::vector<std::thread> threads; +    std::queue<std::function<void()>> requests; +    std::mutex queue_mutex; +    std::condition_variable condition; +    std::atomic_bool stop{}; +}; + +} // namespace Common | 
