Dispatch Queue
Dispatch Queue / Thread Pool implementation for C++11 with built-in C++20 coroutine support
 
Loading...
Searching...
No Matches
worker_pool.cpp
Go to the documentation of this file.
1#include "../include/detail/worker_pool.hpp"
2
3#include <cassert>
4
5namespace dispatch_queue {
6
7namespace detail {
8
9worker_pool::~worker_pool() {
10 shutdown();
11}
12
13int worker_pool::thread_count() const {
14 return worker_thread_count;
15}
16
17size_t worker_pool::size() const {
18 std::lock_guard<std::mutex> lock(mutex);
19 return task_queue.size();
20}
21
22void worker_pool::enqueue_task(task_type type, task_function&& task, task_tag tag) {
23 bool should_wake_thread;
24 {
25 std::lock_guard<std::mutex> lock(mutex);
26 bool has_new_background_task = task_queue.push(type, std::move(task), tag);
27 should_wake_thread = has_new_background_task && idle_threads;
28 }
29 if (should_wake_thread) {
30 task_condition_variable.notify_one();
31 }
32}
33
34std::list<task_function> worker_pool::pop_main_loop_tasks() {
35 std::lock_guard<std::mutex> lock(mutex);
36 return task_queue.pop_main_loop_tasks();
37}
38
39void worker_pool::clear() {
40 std::lock_guard<std::mutex> lock(mutex);
41 task_queue.clear();
42}
43
44void worker_pool::shutdown() {
45 if (worker_threads.empty()) {
46 return;
47 }
48
49 {
50 std::lock_guard<std::mutex> lock(mutex);
51 is_shutting_down = true;
52 }
53 for (int i = 0; i < thread_count(); i++) {
54 task_condition_variable.notify_one();
55 }
56 for (auto& thread : worker_threads) {
57 if (thread.joinable()) {
58 thread.join();
59 }
60 }
61 worker_threads.clear();
62 idle_threads = 0;
63 is_shutting_down = false;
64}
65
66void worker_pool::wait() const {
67 std::unique_lock<std::mutex> lock(mutex);
68 all_done_condition_variable.wait(lock, wait_predicate());
69}
70
71void worker_pool::run_task_loop() {
72 pending_task task;
73 while (true) {
74 // 1. Get a valid task
75 {
76 std::unique_lock<std::mutex> lock(mutex);
77 if (!task_queue.try_pop(task)) {
78 ++idle_threads;
79 assert(idle_threads <= worker_thread_count);
80 if (idle_threads == worker_thread_count) {
81 all_done_condition_variable.notify_all();
82 }
83 task_condition_variable.wait(lock, [this, &task]{ return is_shutting_down || task_queue.try_pop(task); });
84 --idle_threads;
85 assert(idle_threads >= 0);
86 }
87 if (is_shutting_down) {
88 return;
89 }
90 }
91
92 // 2. Do some work
93 task();
94 }
95}
96
97} // end namespace detail
98
99} // end namespace dispatch_queue
Definition when_all.hpp:12
Definition dispatch_queue.hpp:19
int task_tag
Definition task_tag.hpp:12