1
0
Fork 0
mirror of https://gitlab.com/niansa/libcrosscoro.git synced 2025-03-06 20:53:32 +01:00
libcrosscoro/inc/coro/thread_pool.hpp
Josh Baldwin c548433dd9
Correctly implement sync_wait and when_all_awaitable (#8)
See issue for more details, in general attempting to
implement a coro::thread_pool exposed that the coro::sync_wait
and coro::when_all only worked if the coroutines executed on
that same thread.  They should now possibly have the ability
to execute on another thread, to be determined in a later issue.

Fixes #7
2020-10-25 20:54:19 -06:00

73 lines
1.9 KiB
C++

#pragma once
#include "coro/shutdown.hpp"
#include <atomic>
#include <vector>
#include <thread>
#include <mutex>
#include <condition_variable>
#include <coroutine>
#include <deque>
#include <optional>
#include <iostream>
namespace coro
{
class thread_pool;
class thread_pool
{
public:
class operation
{
friend class thread_pool;
public:
explicit operation(thread_pool& tp) noexcept;
auto await_ready() noexcept -> bool { std::cerr << "thread_pool::operation::await_ready()\n"; return false; }
auto await_suspend(std::coroutine_handle<> awaiting_coroutine) noexcept -> bool;
auto await_resume() noexcept -> void { std::cerr << "thread_pool::operation::await_resume()\n";/* no-op */ }
private:
thread_pool& m_thread_pool;
std::coroutine_handle<> m_awaiting_coroutine{nullptr};
};
explicit thread_pool(uint32_t thread_count = std::thread::hardware_concurrency());
thread_pool(const thread_pool&) = delete;
thread_pool(thread_pool&&) = delete;
auto operator=(const thread_pool&) -> thread_pool& = delete;
auto operator=(thread_pool&&) -> thread_pool& = delete;
~thread_pool();
auto thread_count() const -> uint32_t { return m_threads.size(); }
[[nodiscard]]
auto schedule() noexcept -> std::optional<operation>;
auto shutdown(shutdown_t wait_for_tasks = shutdown_t::sync) -> void;
auto size() const -> std::size_t { return m_size.load(std::memory_order::relaxed); }
auto empty() const -> bool { return size() == 0; }
private:
std::atomic<bool> m_shutdown_requested{false};
std::vector<std::thread> m_threads;
std::mutex m_queue_cv_mutex;
std::condition_variable m_queue_cv;
std::mutex m_queue_mutex;
std::deque<operation*> m_queue;
std::atomic<std::size_t> m_size{0};
auto run(uint32_t worker_idx) -> void;
auto join() -> void;
auto schedule_impl(operation* op) -> void;
};
} // namespace coro