/* SPDX-License-Identifier: GPL-2.0-or-later */ /** \file * \ingroup bli * * Task scheduler initialization. */ #include "MEM_guardedalloc.h" #include "BLI_task.h" #include "BLI_threads.h" #ifdef WITH_TBB /* Need to include at least one header to get the version define. */ # include # include # if TBB_INTERFACE_VERSION_MAJOR >= 10 # include # define WITH_TBB_GLOBAL_CONTROL # endif #endif /* Task Scheduler */ static int task_scheduler_num_threads = 1; #ifdef WITH_TBB_GLOBAL_CONTROL static tbb::global_control *task_scheduler_global_control = nullptr; #endif void BLI_task_scheduler_init() { #ifdef WITH_TBB_GLOBAL_CONTROL const int threads_override_num = BLI_system_num_threads_override_get(); if (threads_override_num > 0) { /* Override number of threads. This settings is used within the lifetime * of tbb::global_control, so we allocate it on the heap. */ task_scheduler_global_control = MEM_new( __func__, tbb::global_control::max_allowed_parallelism, threads_override_num); task_scheduler_num_threads = threads_override_num; } else { /* Let TBB choose the number of threads. For (legacy) code that calls * BLI_task_scheduler_num_threads() we provide the system thread count. * Ideally such code should be rewritten not to use the number of threads * at all. */ task_scheduler_num_threads = BLI_system_thread_count(); } #else task_scheduler_num_threads = BLI_system_thread_count(); #endif } void BLI_task_scheduler_exit() { #ifdef WITH_TBB_GLOBAL_CONTROL MEM_delete(task_scheduler_global_control); #endif } int BLI_task_scheduler_num_threads() { return task_scheduler_num_threads; } void BLI_task_isolate(void (*func)(void *userdata), void *userdata) { #ifdef WITH_TBB tbb::this_task_arena::isolate([&] { func(userdata); }); #else func(userdata); #endif }