Use atomic operations in task pool
authorSergey Sharybin <sergey.vfx@gmail.com>
Tue, 2 Dec 2014 10:23:58 +0000 (15:23 +0500)
committerSergey Sharybin <sergey.vfx@gmail.com>
Tue, 2 Dec 2014 10:23:58 +0000 (15:23 +0500)
This ensures proper values of currently running tasks in the pool
(previously difference between mutex locks when acquiring new job
and releasing it might in theory give wrong values).

source/blender/blenlib/CMakeLists.txt
source/blender/blenlib/SConscript
source/blender/blenlib/intern/task.c

index cb84c0d2e5208beaebed24883f32cd77ddd66577..55a5d911d78b2517d8d90c34c7e1ecd47811015a 100644 (file)
@@ -30,6 +30,7 @@ set(INC
        # ../blenkernel  # dont add this back!
        ../makesdna
        ../../../intern/guardedalloc
+       ../../../intern/atomic
        ../../../extern/wcwidth
 )
 
index 2dabb5a7334c87644cc6ff4edf94ffe972f07d31..55747a426f013c97caa720d69ef471900be855a8 100644 (file)
@@ -35,6 +35,7 @@ incs = [
     '.',
     '#/extern/wcwidth',
     '#/intern/guardedalloc',
+    '#/intern/atomic',
     '../makesdna',
     env['BF_FREETYPE_INC'],
     env['BF_ZLIB_INC'],
index e4cded18b764b073c81b5275cc8c000c7ae7429c..d187a8d1968581305c0866e7c3c6b411426b47e6 100644 (file)
@@ -33,6 +33,8 @@
 #include "BLI_task.h"
 #include "BLI_threads.h"
 
+#include "atomic_ops.h"
+
 /* Types */
 
 typedef struct Task {
@@ -49,8 +51,8 @@ struct TaskPool {
 
        volatile size_t num;
        volatile size_t done;
-       volatile int num_threads;
-       volatile int currently_running_tasks;
+       size_t num_threads;
+       size_t currently_running_tasks;
        ThreadMutex num_mutex;
        ThreadCondition num_cond;
 
@@ -86,7 +88,7 @@ static void task_pool_num_decrease(TaskPool *pool, size_t done)
        BLI_assert(pool->num >= done);
 
        pool->num -= done;
-       pool->currently_running_tasks -= done;
+       atomic_sub_z(&pool->currently_running_tasks, done);
        pool->done += done;
 
        if (pool->num == 0)
@@ -130,7 +132,7 @@ static bool task_scheduler_thread_wait_pop(TaskScheduler *scheduler, Task **task
                        {
                                *task = current_task;
                                found_task = true;
-                               pool->currently_running_tasks++;
+                               atomic_add_z(&pool->currently_running_tasks, 1);
                                BLI_remlink(&scheduler->queue, *task);
                                break;
                        }
@@ -392,7 +394,7 @@ void BLI_task_pool_work_and_wait(TaskPool *pool)
                /* if found task, do it, otherwise wait until other tasks are done */
                if (found_task) {
                        /* run task */
-                       pool->currently_running_tasks++;
+                       atomic_add_z(&pool->currently_running_tasks, 1);
                        work_task->run(pool, work_task->taskdata, 0);
 
                        /* delete task */