27# include <tbb/blocked_range.h>
28# include <tbb/task_arena.h>
29# include <tbb/task_group.h>
79 other.taskdata =
nullptr;
80 other.free_taskdata =
false;
81 other.freedata =
nullptr;
88#if (defined(WITH_TBB) && TBB_INTERFACE_VERSION_MAJOR < 10) || \
89 (defined(_MSC_VER) && defined(__clang__) && TBB_INTERFACE_VERSION_MAJOR < 12)
97 ((
Task &)other).pool =
nullptr;
98 ((
Task &)other).run =
nullptr;
99 ((
Task &)other).taskdata =
nullptr;
100 ((
Task &)other).free_taskdata =
false;
101 ((
Task &)other).freedata =
nullptr;
124class TBBTaskGroup :
public tbb::task_group {
128# if TBB_INTERFACE_VERSION_MAJOR >= 12
136 my_context.set_priority(tbb::priority_low);
139 my_context.set_priority(tbb::priority_normal);
189 switch (this->type) {
194 this->is_suspended =
true;
199 this->tbb_group = std::make_unique<TBBTaskGroup>(
priority);
222 this->background_task_pool_work_and_wait();
235 other.pool =
nullptr;
237 other.taskdata =
nullptr;
238 other.free_taskdata =
false;
239 other.freedata =
nullptr;
256 switch (this->type) {
260 this->tbb_task_pool_run({
this, run, taskdata, free_taskdata, freedata});
264 this->background_task_pool_run({
this, run, taskdata, free_taskdata, freedata});
274 switch (this->type) {
278 this->tbb_task_pool_work_and_wait();
282 this->background_task_pool_work_and_wait();
292 switch (this->type) {
296 this->tbb_task_pool_cancel();
300 this->background_task_pool_cancel();
307 switch (this->type) {
311 return this->tbb_task_pool_canceled();
314 return this->background_task_pool_canceled();
316 BLI_assert_msg(0,
"TaskPool::current_canceled: Control flow should not come here!");
328 void tbb_task_pool_run(
Task &&task);
329 void tbb_task_pool_work_and_wait();
330 void tbb_task_pool_cancel();
331 bool tbb_task_pool_canceled();
336 void background_task_pool_run(
Task &&task);
337 void background_task_pool_work_and_wait();
338 void background_task_pool_cancel();
339 bool background_task_pool_canceled();
340 static void *background_task_run(
void *
userdata);
343void TaskPool::tbb_task_pool_run(
Task &&task)
359 std::atomic_thread_fence(std::memory_order_release);
375void TaskPool::tbb_task_pool_work_and_wait()
384 this->tbb_task_pool_run(std::move(task));
399void TaskPool::tbb_task_pool_cancel()
410bool TaskPool::tbb_task_pool_canceled()
415 return tbb::is_current_task_group_canceling();
421void TaskPool::background_task_pool_run(
Task &&task)
425 Task *task_mem = MEM_new<Task>(__func__, std::move(task));
437void TaskPool::background_task_pool_work_and_wait()
448void TaskPool::background_task_pool_cancel()
465bool TaskPool::background_task_pool_canceled()
472void *TaskPool::background_task_run(
void *userdata)
486 return MEM_new<TaskPool>(__func__,
TASK_POOL_TBB, priority, userdata);
532 pool->
task_push(run, taskdata, free_taskdata, freedata);
#define BLI_assert_msg(a, msg)
int BLI_task_scheduler_num_threads(void)
void(* TaskRunFunction)(TaskPool *__restrict pool, void *taskdata)
void(* TaskFreeFunction)(TaskPool *__restrict pool, void *taskdata)
@ BLI_THREAD_QUEUE_WORK_PRIORITY_HIGH
@ BLI_THREAD_QUEUE_WORK_PRIORITY_NORMAL
void * BLI_thread_queue_pop(ThreadQueue *queue)
ThreadQueue * BLI_thread_queue_init(void)
void BLI_threadpool_remove(struct ListBase *threadbase, void *callerdata)
void BLI_threadpool_init(struct ListBase *threadbase, void *(*do_thread)(void *), int tot)
void BLI_thread_queue_free(ThreadQueue *queue)
void BLI_threadpool_end(struct ListBase *threadbase)
uint64_t BLI_thread_queue_push(ThreadQueue *queue, void *work, ThreadQueueWorkPriority priority)
void BLI_thread_queue_nowait(ThreadQueue *queue)
void BLI_thread_queue_wait_finish(ThreadQueue *queue)
void BLI_threadpool_clear(struct ListBase *threadbase)
int BLI_available_threads(struct ListBase *threadbase)
void BLI_threadpool_insert(struct ListBase *threadbase, void *callerdata)
These structs are the foundation for all linked lists in the library system.
Read Guarded memory(de)allocation.
Task & operator=(const Task &other)=delete
Task & operator=(Task &&other)=delete
Task(const Task &other)=delete
TaskFreeFunction freedata
Task(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
void MEM_freeN(void *vmemh)
TaskPool & operator=(TaskPool &&other)=delete
ThreadQueue * background_queue
TaskPool(TaskPool &&other)=delete
void task_push(TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)
volatile bool is_suspended
tbb::task_group tbb_group
TaskPool(const TaskPool &other)=delete
TaskPool & operator=(const TaskPool &other)=delete
TaskPool(const TaskPoolType type, const eTaskPriority priority, void *userdata)
ListBase background_threads
volatile bool background_is_canceling
blender::Vector< Task > suspended_tasks
std::function< void()> TaskRunFunction
TaskPool * BLI_task_pool_create_suspended(void *userdata, eTaskPriority priority)
void * BLI_task_pool_user_data(TaskPool *pool)
bool BLI_task_pool_current_canceled(TaskPool *pool)
TaskPool * BLI_task_pool_create_no_threads(void *userdata)
void BLI_task_pool_work_and_wait(TaskPool *pool)
void BLI_task_pool_cancel(TaskPool *pool)
TaskPool * BLI_task_pool_create_background(void *userdata, eTaskPriority priority)
TaskPool * BLI_task_pool_create_background_serial(void *userdata, eTaskPriority priority)
TaskPool * BLI_task_pool_create(void *userdata, eTaskPriority priority)
void BLI_task_pool_free(TaskPool *pool)
@ TASK_POOL_TBB_SUSPENDED
@ TASK_POOL_BACKGROUND_SERIAL
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskFreeFunction freedata)