diff options
21 files changed, 132 insertions, 44 deletions
diff --git a/source/blender/blenkernel/intern/editmesh_tangent.c b/source/blender/blenkernel/intern/editmesh_tangent.c index d849f4ab37d..088a2087a96 100644 --- a/source/blender/blenkernel/intern/editmesh_tangent.c +++ b/source/blender/blenkernel/intern/editmesh_tangent.c @@ -362,7 +362,7 @@ void BKE_editmesh_loop_tangent_calc(BMEditMesh *em, /* Calculation */ if (em->tottri != 0) { TaskPool *task_pool; - task_pool = BLI_task_pool_create(NULL, TASK_PRIORITY_LOW); + task_pool = BLI_task_pool_create(NULL, TASK_PRIORITY_LOW, TASK_ISOLATION_ON); tangent_mask_curr = 0; /* Calculate tangent layers */ diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c index c93971e7b11..6b2ffa3b944 100644 --- a/source/blender/blenkernel/intern/lib_override.c +++ b/source/blender/blenkernel/intern/lib_override.c @@ -2335,7 +2335,8 @@ bool BKE_lib_override_library_main_operations_create(Main *bmain, const bool for } struct LibOverrideOpCreateData create_pool_data = {.bmain = bmain, .changed = false}; - TaskPool *task_pool = BLI_task_pool_create(&create_pool_data, TASK_PRIORITY_HIGH); + TaskPool *task_pool = BLI_task_pool_create( + &create_pool_data, TASK_PRIORITY_HIGH, TASK_ISOLATION_ON); FOREACH_MAIN_ID_BEGIN (bmain, id) { if (!ID_IS_LINKED(id) && ID_IS_OVERRIDE_LIBRARY_REAL(id) && diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c index 616ec79c099..345546bc9cf 100644 --- a/source/blender/blenkernel/intern/mesh_evaluate.c +++ b/source/blender/blenkernel/intern/mesh_evaluate.c @@ -1715,7 +1715,8 @@ void BKE_mesh_normals_loop_split(const MVert *mverts, loop_split_generator(NULL, &common_data); } else { - TaskPool *task_pool = BLI_task_pool_create(&common_data, TASK_PRIORITY_HIGH); + TaskPool *task_pool = BLI_task_pool_create( + &common_data, TASK_PRIORITY_HIGH, TASK_ISOLATION_ON); loop_split_generator(task_pool, &common_data); diff --git a/source/blender/blenkernel/intern/mesh_tangent.c b/source/blender/blenkernel/intern/mesh_tangent.c index 2e22e521a13..6a7ff0851f5 100644 --- a/source/blender/blenkernel/intern/mesh_tangent.c +++ b/source/blender/blenkernel/intern/mesh_tangent.c @@ -656,7 +656,7 @@ void BKE_mesh_calc_loop_tangent_ex(const MVert *mvert, /* Calculation */ if (looptri_len != 0) { - TaskPool *task_pool = BLI_task_pool_create(NULL, TASK_PRIORITY_LOW); + TaskPool *task_pool = BLI_task_pool_create(NULL, TASK_PRIORITY_LOW, TASK_ISOLATION_ON); tangent_mask_curr = 0; /* Calculate tangent layers */ diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c index 9d53dad8d03..9b9ed0adcf4 100644 --- a/source/blender/blenkernel/intern/ocean.c +++ b/source/blender/blenkernel/intern/ocean.c @@ -663,7 +663,7 @@ void BKE_ocean_simulate(struct Ocean *o, float t, float scale, float chop_amount osd.scale = scale; osd.chop_amount = chop_amount; - pool = BLI_task_pool_create(&osd, TASK_PRIORITY_HIGH); + pool = BLI_task_pool_create(&osd, TASK_PRIORITY_HIGH, TASK_ISOLATION_ON); BLI_rw_mutex_lock(&o->oceanmutex, THREAD_LOCK_WRITE); diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c index a873ecec6f1..3ae5d039125 100644 --- a/source/blender/blenkernel/intern/particle.c +++ b/source/blender/blenkernel/intern/particle.c @@ -3179,7 +3179,7 @@ void psys_cache_child_paths(ParticleSimulationData *sim, return; } - task_pool = BLI_task_pool_create(&ctx, TASK_PRIORITY_LOW); + task_pool = BLI_task_pool_create(&ctx, TASK_PRIORITY_LOW, TASK_ISOLATION_ON); totchild = ctx.totchild; totparent = ctx.totparent; diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c index ad617b4198b..6cae6cd6fa2 100644 --- a/source/blender/blenkernel/intern/particle_distribute.c +++ b/source/blender/blenkernel/intern/particle_distribute.c @@ -1330,7 +1330,7 @@ static void distribute_particles_on_dm(ParticleSimulationData *sim, int from) return; } - task_pool = BLI_task_pool_create(&ctx, TASK_PRIORITY_LOW); + task_pool = BLI_task_pool_create(&ctx, TASK_PRIORITY_LOW, TASK_ISOLATION_ON); totpart = (from == PART_FROM_CHILD ? sim->psys->totchild : sim->psys->totpart); psys_tasks_create(&ctx, 0, totpart, &tasks, &numtasks); diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h index 9e61686b37a..339bb256819 100644 --- a/source/blender/blenlib/BLI_task.h +++ b/source/blender/blenlib/BLI_task.h @@ -67,17 +67,55 @@ typedef enum TaskPriority { TASK_PRIORITY_HIGH, } TaskPriority; +/** + * Task isolation helps avoid unexpected task scheduling decisions that can lead to bugs if wrong + * assumptions were made. Typically that happens when doing "nested threading", i.e. one thread + * schedules a bunch of main-tasks and those spawn new subtasks. + * + * What can happen is that when a main-task waits for its subtasks to complete on other threads, + * another main-task is scheduled within the already running main-task. Generally, this is good, + * because it leads to better performance. However, sometimes code (often unintentionally) makes + * the assumption that at most one main-task runs on a thread at a time. + * + * The bugs often show themselves in two ways: + * - Deadlock, when a main-task holds a mutex while waiting for its subtasks to complete. + * - Data corruption, when a main-task makes wrong assumptions about a threadlocal variable. + * + * Task isolation can avoid these bugs by making sure that a main-task does not start executing + * another main-task while waiting for its subtasks. More precisely, a function that runs in an + * isolated region is only allowed to run subtasks that were spawned in the same isolated region. + * + * Unfortunately, incorrect use of task isolation can lead to deadlocks itself. This can happen + * when threading primitives are used that separate spawning tasks from executing them. The problem + * occurs when a task is spawned in one isolated region while the tasks are waited for in another + * isolated region. In this setup, the thread that is waiting for the spawned tasks to complete + * cannot run the tasks itself. On a single thread, that causes a deadlock already. When there are + * multiple threads, another thread will typically run the task and avoid the deadlock. However, if + * this situation happens on all threads at the same time, all threads will deadlock. This happened + * in T88598. + */ +typedef enum TaskIsolation { + /* Do not use task isolation. Always use this when tasks are pushed recursively. */ + TASK_ISOLATION_OFF, + /* Run each task in its own isolated region. */ + TASK_ISOLATION_ON, +} TaskIsolation; + typedef struct TaskPool TaskPool; typedef void (*TaskRunFunction)(TaskPool *__restrict pool, void *taskdata); typedef void (*TaskFreeFunction)(TaskPool *__restrict pool, void *taskdata); /* Regular task pool that immediately starts executing tasks as soon as they * are pushed, either on the current or another thread. */ -TaskPool *BLI_task_pool_create(void *userdata, TaskPriority priority); +TaskPool *BLI_task_pool_create(void *userdata, + TaskPriority priority, + TaskIsolation task_isolation); /* Background: always run tasks in a background thread, never immediately * execute them. For running background jobs. */ -TaskPool *BLI_task_pool_create_background(void *userdata, TaskPriority priority); +TaskPool *BLI_task_pool_create_background(void *userdata, + TaskPriority priority, + TaskIsolation task_isolation); /* Background Serial: run tasks one after the other in the background, * without parallelization between the tasks. */ @@ -87,7 +125,9 @@ TaskPool *BLI_task_pool_create_background_serial(void *userdata, TaskPriority pr * as threads can't immediately start working. But it can be used if the data * structures the threads operate on are not fully initialized until all tasks * are created. */ -TaskPool *BLI_task_pool_create_suspended(void *userdata, TaskPriority priority); +TaskPool *BLI_task_pool_create_suspended(void *userdata, + TaskPriority priority, + TaskIsolation task_isolation); /* No threads: immediately executes tasks on the same thread. For debugging. */ TaskPool *BLI_task_pool_create_no_threads(void *userdata); diff --git a/source/blender/blenlib/intern/task_iterator.c b/source/blender/blenlib/intern/task_iterator.c index 38271e5823f..85cd9718ed4 100644 --- a/source/blender/blenlib/intern/task_iterator.c +++ b/source/blender/blenlib/intern/task_iterator.c @@ -223,7 +223,7 @@ static void task_parallel_iterator_do(const TaskParallelSettings *settings, void *userdata_chunk_array = NULL; const bool use_userdata_chunk = (userdata_chunk_size != 0) && (userdata_chunk != NULL); - TaskPool *task_pool = BLI_task_pool_create(state, TASK_PRIORITY_HIGH); + TaskPool *task_pool = BLI_task_pool_create(state, TASK_PRIORITY_HIGH, TASK_ISOLATION_ON); if (use_userdata_chunk) { userdata_chunk_array = MALLOCA(userdata_chunk_size * num_tasks); @@ -398,7 +398,7 @@ void BLI_task_parallel_mempool(BLI_mempool *mempool, return; } - task_pool = BLI_task_pool_create(&state, TASK_PRIORITY_HIGH); + task_pool = BLI_task_pool_create(&state, TASK_PRIORITY_HIGH, TASK_ISOLATION_ON); num_threads = BLI_task_scheduler_num_threads(); /* The idea here is to prevent creating task for each of the loop iterations diff --git a/source/blender/blenlib/intern/task_pool.cc b/source/blender/blenlib/intern/task_pool.cc index 6404f5264cc..d72674c1c00 100644 --- a/source/blender/blenlib/intern/task_pool.cc +++ b/source/blender/blenlib/intern/task_pool.cc @@ -22,6 +22,7 @@ #include <cstdlib> #include <memory> +#include <thread> #include <utility> #include "MEM_guardedalloc.h" @@ -111,15 +112,7 @@ class Task { Task &operator=(const Task &other) = delete; Task &operator=(Task &&other) = delete; - /* Execute task. */ - void operator()() const - { -#ifdef WITH_TBB - tbb::this_task_arena::isolate([this] { run(pool, taskdata); }); -#else - run(pool, taskdata); -#endif - } + void operator()() const; }; /* TBB Task Group. @@ -163,13 +156,16 @@ enum TaskPoolType { struct TaskPool { TaskPoolType type; bool use_threads; + TaskIsolation task_isolation; ThreadMutex user_mutex; void *userdata; - /* TBB task pool. */ #ifdef WITH_TBB + /* TBB task pool. */ TBBTaskGroup tbb_group; + /* This is used to detect a common way to accidentally create a deadlock with task isolation. */ + std::thread::id task_pool_create_thread_id; #endif volatile bool is_suspended; BLI_mempool *suspended_mempool; @@ -180,6 +176,36 @@ struct TaskPool { volatile bool background_is_canceling; }; +/* Execute task. */ +void Task::operator()() const +{ +#ifdef WITH_TBB + if (pool->task_isolation == TASK_ISOLATION_ON) { + tbb::this_task_arena::isolate([this] { run(pool, taskdata); }); + return; + } +#endif + run(pool, taskdata); +} + +static void assert_on_valid_thread(TaskPool *pool) +{ + /* TODO: Remove this `return` to enable the check. */ + return; +#ifdef DEBUG +# ifdef WITH_TBB + if (pool->task_isolation == TASK_ISOLATION_ON) { + const std::thread::id current_id = std::this_thread::get_id(); + /* This task pool is modified from different threads. To avoid deadlocks, `TASK_ISOLATION_OFF` + * has to be used. Task isolation can still be used in a more fine-grained way within the + * tasks, but should not be enabled for the entire task pool. */ + BLI_assert(pool->task_pool_create_thread_id == current_id); + } +# endif +#endif + UNUSED_VARS_NDEBUG(pool); +} + /* TBB Task Pool. * * Task pool using the TBB scheduler for tasks. When building without TBB @@ -365,7 +391,10 @@ static void background_task_pool_free(TaskPool *pool) /* Task Pool */ -static TaskPool *task_pool_create_ex(void *userdata, TaskPoolType type, TaskPriority priority) +static TaskPool *task_pool_create_ex(void *userdata, + TaskPoolType type, + TaskPriority priority, + TaskIsolation task_isolation) { const bool use_threads = BLI_task_scheduler_num_threads() > 1 && type != TASK_POOL_NO_THREADS; @@ -381,6 +410,11 @@ static TaskPool *task_pool_create_ex(void *userdata, TaskPoolType type, TaskPrio pool->type = type; pool->use_threads = use_threads; + pool->task_isolation = task_isolation; + +#ifdef WITH_TBB + pool->task_pool_create_thread_id = std::this_thread::get_id(); +#endif pool->userdata = userdata; BLI_mutex_init(&pool->user_mutex); @@ -403,9 +437,9 @@ static TaskPool *task_pool_create_ex(void *userdata, TaskPoolType type, TaskPrio /** * Create a normal task pool. Tasks will be executed as soon as they are added. */ -TaskPool *BLI_task_pool_create(void *userdata, TaskPriority priority) +TaskPool *BLI_task_pool_create(void *userdata, TaskPriority priority, TaskIsolation task_isolation) { - return task_pool_create_ex(userdata, TASK_POOL_TBB, priority); + return task_pool_create_ex(userdata, TASK_POOL_TBB, priority, task_isolation); } /** @@ -420,9 +454,11 @@ TaskPool *BLI_task_pool_create(void *userdata, TaskPriority priority) * they could end never being executed, since the 'fallback' background thread is already * busy with parent task in single-threaded context). */ -TaskPool *BLI_task_pool_create_background(void *userdata, TaskPriority priority) +TaskPool *BLI_task_pool_create_background(void *userdata, + TaskPriority priority, + TaskIsolation task_isolation) { - return task_pool_create_ex(userdata, TASK_POOL_BACKGROUND, priority); + return task_pool_create_ex(userdata, TASK_POOL_BACKGROUND, priority, task_isolation); } /** @@ -430,9 +466,11 @@ TaskPool *BLI_task_pool_create_background(void *userdata, TaskPriority priority) * for until BLI_task_pool_work_and_wait() is called. This helps reducing threading * overhead when pushing huge amount of small initial tasks from the main thread. */ -TaskPool *BLI_task_pool_create_suspended(void *userdata, TaskPriority priority) +TaskPool *BLI_task_pool_create_suspended(void *userdata, + TaskPriority priority, + TaskIsolation task_isolation) { - return task_pool_create_ex(userdata, TASK_POOL_TBB_SUSPENDED, priority); + return task_pool_create_ex(userdata, TASK_POOL_TBB_SUSPENDED, priority, task_isolation); } /** @@ -441,7 +479,8 @@ TaskPool *BLI_task_pool_create_suspended(void *userdata, TaskPriority priority) */ TaskPool *BLI_task_pool_create_no_threads(void *userdata) { - return task_pool_create_ex(userdata, TASK_POOL_NO_THREADS, TASK_PRIORITY_HIGH); + return task_pool_create_ex( + userdata, TASK_POOL_NO_THREADS, TASK_PRIORITY_HIGH, TASK_ISOLATION_ON); } /** @@ -450,7 +489,7 @@ TaskPool *BLI_task_pool_create_no_threads(void *userdata) */ TaskPool *BLI_task_pool_create_background_serial(void *userdata, TaskPriority priority) { - return task_pool_create_ex(userdata, TASK_POOL_BACKGROUND_SERIAL, priority); + return task_pool_create_ex(userdata, TASK_POOL_BACKGROUND_SERIAL, priority, TASK_ISOLATION_ON); } void BLI_task_pool_free(TaskPool *pool) @@ -478,6 +517,8 @@ void BLI_task_pool_push(TaskPool *pool, bool free_taskdata, TaskFreeFunction freedata) { + assert_on_valid_thread(pool); + Task task(pool, run, taskdata, free_taskdata, freedata); switch (pool->type) { @@ -495,6 +536,8 @@ void BLI_task_pool_push(TaskPool *pool, void BLI_task_pool_work_and_wait(TaskPool *pool) { + assert_on_valid_thread(pool); + switch (pool->type) { case TASK_POOL_TBB: case TASK_POOL_TBB_SUSPENDED: diff --git a/source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc b/source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc index e9810aed179..8be89d66062 100644 --- a/source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc +++ b/source/blender/blenlib/tests/BLI_linklist_lockfree_test.cc @@ -81,7 +81,7 @@ TEST(LockfreeLinkList, InsertMultipleConcurrent) LockfreeLinkList list; BLI_linklist_lockfree_init(&list); /* Initialize task scheduler and pool. */ - TaskPool *pool = BLI_task_pool_create_suspended(&list, TASK_PRIORITY_HIGH); + TaskPool *pool = BLI_task_pool_create_suspended(&list, TASK_PRIORITY_HIGH, TASK_ISOLATION_ON); /* Push tasks to the pool. */ for (int i = 0; i < num_nodes; ++i) { BLI_task_pool_push(pool, concurrent_insert, POINTER_FROM_INT(i), false, nullptr); diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cc b/source/blender/compositor/intern/COM_WorkScheduler.cc index 157ded943d6..cd0139fd18e 100644 --- a/source/blender/compositor/intern/COM_WorkScheduler.cc +++ b/source/blender/compositor/intern/COM_WorkScheduler.cc @@ -411,7 +411,8 @@ static void threading_model_task_schedule(WorkPackage *package) static void threading_model_task_start() { BLI_thread_local_create(g_thread_device); - g_work_scheduler.task.pool = BLI_task_pool_create(nullptr, TASK_PRIORITY_HIGH); + g_work_scheduler.task.pool = BLI_task_pool_create( + nullptr, TASK_PRIORITY_HIGH, TASK_ISOLATION_ON); } static void threading_model_task_finish() diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc index 620e86550cc..2107e075139 100644 --- a/source/blender/depsgraph/intern/eval/deg_eval.cc +++ b/source/blender/depsgraph/intern/eval/deg_eval.cc @@ -353,7 +353,8 @@ static TaskPool *deg_evaluate_task_pool_create(DepsgraphEvalState *state) return BLI_task_pool_create_no_threads(state); } - return BLI_task_pool_create_suspended(state, TASK_PRIORITY_HIGH); + /* TODO: Disable task isolation. */ + return BLI_task_pool_create_suspended(state, TASK_PRIORITY_HIGH, TASK_ISOLATION_ON); } /** diff --git a/source/blender/editors/mesh/editmesh_undo.c b/source/blender/editors/mesh/editmesh_undo.c index 112de68b52c..274f4cdbb6c 100644 --- a/source/blender/editors/mesh/editmesh_undo.c +++ b/source/blender/editors/mesh/editmesh_undo.c @@ -626,7 +626,7 @@ static void *undomesh_from_editmesh(UndoMesh *um, BMEditMesh *em, Key *key, Undo # ifdef USE_ARRAY_STORE_THREAD if (um_arraystore.task_pool == NULL) { - um_arraystore.task_pool = BLI_task_pool_create_background(NULL, TASK_PRIORITY_LOW); + um_arraystore.task_pool = BLI_task_pool_create_background(NULL, TASK_PRIORITY_LOW, true); } struct UMArrayData *um_data = MEM_mallocN(sizeof(*um_data), __func__); diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c index 48f937fb4ec..cfc07de3f6c 100644 --- a/source/blender/editors/render/render_opengl.c +++ b/source/blender/editors/render/render_opengl.c @@ -859,7 +859,7 @@ static bool screen_opengl_render_init(bContext *C, wmOperator *op) oglrender->task_pool = BLI_task_pool_create_background_serial(oglrender, TASK_PRIORITY_LOW); } else { - oglrender->task_pool = BLI_task_pool_create(oglrender, TASK_PRIORITY_LOW); + oglrender->task_pool = BLI_task_pool_create(oglrender, TASK_PRIORITY_LOW, TASK_ISOLATION_ON); } oglrender->pool_ok = true; BLI_spin_init(&oglrender->reports_lock); diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c index 530689ce049..f03eeeb3c75 100644 --- a/source/blender/editors/sculpt_paint/paint_image_proj.c +++ b/source/blender/editors/sculpt_paint/paint_image_proj.c @@ -5571,7 +5571,7 @@ static bool project_paint_op(void *state, const float lastpos[2], const float po } if (ps->thread_tot > 1) { - task_pool = BLI_task_pool_create_suspended(NULL, TASK_PRIORITY_HIGH); + task_pool = BLI_task_pool_create_suspended(NULL, TASK_PRIORITY_HIGH, TASK_ISOLATION_ON); } image_pool = BKE_image_pool_new(); diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c index 2da13646a8b..9aa6a993c13 100644 --- a/source/blender/editors/space_clip/clip_editor.c +++ b/source/blender/editors/space_clip/clip_editor.c @@ -904,7 +904,7 @@ static void start_prefetch_threads(MovieClip *clip, queue.do_update = do_update; queue.progress = progress; - TaskPool *task_pool = BLI_task_pool_create(&queue, TASK_PRIORITY_LOW); + TaskPool *task_pool = BLI_task_pool_create(&queue, TASK_PRIORITY_LOW, TASK_ISOLATION_ON); for (int i = 0; i < tot_thread; i++) { BLI_task_pool_push(task_pool, prefetch_task_func, clip, false, NULL); } diff --git a/source/blender/editors/space_clip/clip_ops.c b/source/blender/editors/space_clip/clip_ops.c index 0c54a042a1a..cd60ebf3031 100644 --- a/source/blender/editors/space_clip/clip_ops.c +++ b/source/blender/editors/space_clip/clip_ops.c @@ -1431,7 +1431,7 @@ static void do_sequence_proxy(void *pjv, queue.do_update = do_update; queue.progress = progress; - TaskPool *task_pool = BLI_task_pool_create(&queue, TASK_PRIORITY_LOW); + TaskPool *task_pool = BLI_task_pool_create(&queue, TASK_PRIORITY_LOW, TASK_ISOLATION_ON); handles = MEM_callocN(sizeof(ProxyThread) * tot_thread, "proxy threaded handles"); for (int i = 0; i < tot_thread; i++) { ProxyThread *handle = &handles[i]; diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c index 37a32164cfc..8ea44e5c3ee 100644 --- a/source/blender/editors/space_file/filelist.c +++ b/source/blender/editors/space_file/filelist.c @@ -1553,7 +1553,8 @@ static void filelist_cache_preview_freef(TaskPool *__restrict UNUSED(pool), void static void filelist_cache_preview_ensure_running(FileListEntryCache *cache) { if (!cache->previews_pool) { - cache->previews_pool = BLI_task_pool_create_background(cache, TASK_PRIORITY_LOW); + cache->previews_pool = BLI_task_pool_create_background( + cache, TASK_PRIORITY_LOW, TASK_ISOLATION_ON); cache->previews_done = BLI_thread_queue_init(); IMB_thumb_locks_acquire(); diff --git a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c index d623a553ab8..98b24be0d54 100644 --- a/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c +++ b/source/blender/gpencil_modifiers/intern/lineart/lineart_cpu.c @@ -482,7 +482,7 @@ static void lineart_main_occlusion_begin(LineartRenderBuffer *rb) rb->material.last = rb->material.first; rb->edge_mark.last = rb->edge_mark.first; - TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH); + TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH, TASK_ISOLATION_ON); for (i = 0; i < thread_count; i++) { rti[i].thread_id = i; @@ -1987,7 +1987,7 @@ static void lineart_main_load_geometries( } DEG_OBJECT_ITER_END; - TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH); + TaskPool *tp = BLI_task_pool_create(NULL, TASK_PRIORITY_HIGH, TASK_ISOLATION_ON); for (int i = 0; i < thread_count; i++) { olti[i].rb = rb; diff --git a/source/blender/imbuf/intern/imageprocess.c b/source/blender/imbuf/intern/imageprocess.c index 7ada0130059..1fe3a7717fb 100644 --- a/source/blender/imbuf/intern/imageprocess.c +++ b/source/blender/imbuf/intern/imageprocess.c @@ -374,7 +374,7 @@ void IMB_processor_apply_threaded( int total_tasks = (buffer_lines + lines_per_task - 1) / lines_per_task; int i, start_line; - task_pool = BLI_task_pool_create(do_thread, TASK_PRIORITY_LOW); + task_pool = BLI_task_pool_create(do_thread, TASK_PRIORITY_LOW, TASK_ISOLATION_ON); handles = MEM_callocN(handle_size * total_tasks, "processor apply threaded handles"); @@ -432,7 +432,7 @@ void IMB_processor_apply_threaded_scanlines(int total_scanlines, data.scanlines_per_task = scanlines_per_task; data.total_scanlines = total_scanlines; const int total_tasks = (total_scanlines + scanlines_per_task - 1) / scanlines_per_task; - TaskPool *task_pool = BLI_task_pool_create(&data, TASK_PRIORITY_LOW); + TaskPool *task_pool = BLI_task_pool_create(&data, TASK_PRIORITY_LOW, TASK_ISOLATION_ON); for (int i = 0, start_line = 0; i < total_tasks; i++) { BLI_task_pool_push( task_pool, processor_apply_scanline_func, POINTER_FROM_INT(start_line), false, NULL); |