[Bf-blender-cvs] [0fe7446] master: BLI_task: fix case were some pool could work in more threads than allowed.

Bastien Montagne noreply at git.blender.org
Sat Oct 8 14:51:48 CEST 2016


Commit: 0fe7446a308028545b7d0e73d797824bfc090c17
Author: Bastien Montagne
Date:   Sat Oct 8 14:46:01 2016 +0200
Branches: master
https://developer.blender.org/rB0fe7446a308028545b7d0e73d797824bfc090c17

BLI_task: fix case were some pool could work in more threads than allowed.

We were checking for number of tasks from given pool already active, and
then atomically increasing it if allowed - this is not correct, number
could be increased by another thread between check and atomic op!

Atomic primitives are nice, but you must be very careful with *how* you
use them... Now we atomically increase counter, check result, and if we
end up over max value, abort and decrease counter again.

Spotted by Sergey, thanks!

===================================================================

M	source/blender/blenlib/intern/task.c

===================================================================

diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c
index 9d4d40e..436cd2b 100644
--- a/source/blender/blenlib/intern/task.c
+++ b/source/blender/blenlib/intern/task.c
@@ -292,15 +292,17 @@ static bool task_scheduler_thread_wait_pop(TaskScheduler *scheduler, Task **task
 				continue;
 			}
 
-			if (pool->num_threads == 0 ||
-			    pool->currently_running_tasks < pool->num_threads)
+			if (atomic_add_z(&pool->currently_running_tasks, 1) <= pool->num_threads ||
+			    pool->num_threads == 0)
 			{
 				*task = current_task;
 				found_task = true;
-				atomic_add_z(&pool->currently_running_tasks, 1);
 				BLI_remlink(&scheduler->queue, *task);
 				break;
 			}
+			else {
+				atomic_sub_z(&pool->currently_running_tasks, 1);
+			}
 		}
 		if (!found_task)
 			BLI_condition_wait(&scheduler->queue_cond, &scheduler->queue_mutex);




More information about the Bf-blender-cvs mailing list