Blender V4.3
task.cpp
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2022 Blender Foundation
2 *
3 * SPDX-License-Identifier: Apache-2.0 */
4
5#include "util/task.h"
6#include "util/foreach.h"
7#include "util/log.h"
8#include "util/system.h"
9#include "util/time.h"
10
12
13/* Task Pool */
14
15TaskPool::TaskPool() : start_time(time_dt()), num_tasks_pushed(0) {}
16
21
23{
24 tbb_group.run(std::move(task));
26}
27
29{
30 tbb_group.wait();
31
32 if (stats != NULL) {
33 stats->time_total = time_dt() - start_time;
35 }
36
38}
39
41{
42 if (num_tasks_pushed > 0) {
43 tbb_group.cancel();
44 tbb_group.wait();
46 }
47}
48
50{
51 return tbb::is_current_task_group_canceling();
52}
53
54/* Task Scheduler */
55
59tbb::global_control *TaskScheduler::global_control = nullptr;
60
61void TaskScheduler::init(int num_threads)
62{
64 /* Multiple cycles instances can use this task scheduler, sharing the same
65 * threads, so we keep track of the number of users. */
66 ++users;
67 if (users != 1) {
68 return;
69 }
70 if (num_threads > 0) {
71 /* Automatic number of threads. */
72 VLOG_INFO << "Overriding number of TBB threads to " << num_threads << ".";
73 global_control = new tbb::global_control(tbb::global_control::max_allowed_parallelism,
74 num_threads);
75 active_num_threads = num_threads;
76 }
77 else {
78 active_num_threads = tbb::this_task_arena::max_concurrency();
79 }
80}
81
83{
85 users--;
86 if (users == 0) {
87 delete global_control;
88 global_control = nullptr;
90 }
91}
92
94{
95 assert(users == 0);
96}
97
99{
101 return (users > 0) ? active_num_threads : tbb::this_task_arena::max_concurrency();
102}
103
104/* Dedicated Task Pool */
105
114
116{
117 wait();
118
119 do_exit = true;
120 queue_cond.notify_all();
121
123 delete worker_thread;
124}
125
127{
128 num_increase();
129
130 /* add task to queue */
131 queue_mutex.lock();
132 if (front) {
133 queue.emplace_front(std::move(task));
134 }
135 else {
136 queue.emplace_back(std::move(task));
137 }
138
139 queue_cond.notify_one();
140 queue_mutex.unlock();
141}
142
144{
146
147 while (num) {
148 num_cond.wait(num_lock);
149 }
150}
151
153{
154 do_cancel = true;
155
156 clear();
157 wait();
158
159 do_cancel = false;
160}
161
163{
164 return do_cancel;
165}
166
168{
170 num -= done;
171
172 assert(num >= 0);
173 if (num == 0) {
174 num_cond.notify_all();
175 }
176}
177
179{
181 num++;
182 num_cond.notify_all();
183}
184
186{
188
189 while (queue.empty() && !do_exit) {
190 queue_cond.wait(queue_lock);
191 }
192
193 if (queue.empty()) {
194 assert(do_exit);
195 return false;
196 }
197
198 task = queue.front();
199 queue.pop_front();
200
201 return true;
202}
203
205{
206 TaskRunFunction task;
207
208 /* keep popping off tasks */
209 while (thread_wait_pop(task)) {
210 /* run task */
211 task();
212
213 /* delete task */
214 task = nullptr;
215
216 /* notify task was done */
217 num_decrease(1);
218 }
219}
220
222{
224
225 /* erase all tasks from the queue */
226 int done = queue.size();
227 queue.clear();
228
229 queue_lock.unlock();
230
231 /* notify done */
232 num_decrease(done);
233}
234
236{
237 string report = "";
238 report += string_printf("Total time: %f\n", time_total);
239 report += string_printf("Tasks handled: %d\n", num_tasks_handled);
240 return report;
241}
242
volatile int lock
thread_condition_variable num_cond
Definition task.h:121
void thread_run()
Definition task.cpp:204
thread_mutex queue_mutex
Definition task.h:124
thread_mutex num_mutex
Definition task.h:120
void num_decrease(int done)
Definition task.cpp:167
void push(TaskRunFunction &&run, bool front=false)
Definition task.cpp:126
thread * worker_thread
Definition task.h:131
thread_condition_variable queue_cond
Definition task.h:125
bool canceled()
Definition task.cpp:162
void num_increase()
Definition task.cpp:178
bool thread_wait_pop(TaskRunFunction &task)
Definition task.cpp:185
static void free_memory()
Definition task.cpp:93
static void exit()
Definition task.cpp:82
static void init(int num_threads=0)
Definition task.cpp:61
static thread_mutex mutex
Definition task.h:83
static int users
Definition task.h:84
static int active_num_threads
Definition task.h:85
static int max_concurrency()
Definition task.cpp:98
bool join()
Definition thread.cpp:43
#define function_bind
#define CCL_NAMESPACE_END
#define NULL
#define VLOG_INFO
Definition log.h:72
CCL_NAMESPACE_BEGIN string string_printf(const char *format,...)
Definition string.cpp:23
string full_report() const
Definition task.cpp:235
int num_tasks_handled
Definition task.h:36
double time_total
Definition task.h:33
void push(TaskRunFunction &&task)
Definition task.cpp:22
static bool canceled()
Definition task.cpp:49
int num_tasks_pushed
Definition task.h:63
tbb::task_group tbb_group
Definition task.h:55
double start_time
Definition task.h:60
~TaskPool()
Definition task.cpp:17
void cancel()
Definition task.cpp:40
TaskPool()
Definition task.cpp:15
void wait_work(Summary *stats=NULL)
Definition task.cpp:28
function< void(void)> TaskRunFunction
Definition task.h:19
std::unique_lock< std::mutex > thread_scoped_lock
Definition thread.h:30
CCL_NAMESPACE_BEGIN typedef std::mutex thread_mutex
Definition thread.h:29
CCL_NAMESPACE_BEGIN double time_dt()
Definition time.cpp:36