BLI_task: fix queue in work_and_wait, and support resetting.
authorAlexander Gavrilov <angavrilov@gmail.com>
Mon, 3 Dec 2018 19:55:18 +0000 (22:55 +0300)
committerAlexander Gavrilov <angavrilov@gmail.com>
Tue, 4 Dec 2018 11:08:50 +0000 (14:08 +0300)
To make the pool more usable for running multiple stages of tasks,
fix local queue handling in BLI_task_pool_work_and_wait.

Specifically, after the wait loop the local queue should be empty,
or the wait part of the function contract isn't fulfilled. Instead,
check and run any tasks in queue before the wait loop.

Also, add a new function that resets the suspended state of the pool.

source/blender/blenlib/BLI_task.h
source/blender/blenlib/intern/task.c

index 9194caca007aba07c0177a1c024e7fdb5e136a40..8300f6242db2ec8c4e6acfd6dd255c16d844d670 100644 (file)
@@ -98,6 +98,8 @@ void BLI_task_pool_push_from_thread(TaskPool *pool, TaskRunFunction run,
 
 /* work and wait until all tasks are done */
 void BLI_task_pool_work_and_wait(TaskPool *pool);
+/* work and wait until all tasks are done, then reset to the initial suspended state */
+void BLI_task_pool_work_wait_and_reset(TaskPool *pool);
 /* cancel all tasks, keep worker threads running */
 void BLI_task_pool_cancel(TaskPool *pool);
 
index 047a7c0cc3b6e78930905e973db4cb2ec2f6eff6..edd588bd68b7c308c91b01631ebaae764852e78e 100644 (file)
@@ -175,6 +175,7 @@ struct TaskPool {
        volatile bool do_work;
 
        volatile bool is_suspended;
+       bool start_suspended;
        ListBase suspended_queue;
        size_t num_suspended;
 
@@ -650,6 +651,7 @@ static TaskPool *task_pool_create_ex(TaskScheduler *scheduler,
        pool->do_cancel = false;
        pool->do_work = false;
        pool->is_suspended = is_suspended;
+       pool->start_suspended = is_suspended;
        pool->num_suspended = 0;
        pool->suspended_queue.first = pool->suspended_queue.last = NULL;
        pool->run_in_background = is_background;
@@ -855,6 +857,8 @@ void BLI_task_pool_work_and_wait(TaskPool *pool)
 
                        BLI_condition_notify_all(&scheduler->queue_cond);
                        BLI_mutex_unlock(&scheduler->queue_mutex);
+
+                       pool->num_suspended = 0;
                }
        }
 
@@ -862,6 +866,8 @@ void BLI_task_pool_work_and_wait(TaskPool *pool)
 
        ASSERT_THREAD_ID(pool->scheduler, pool->thread_id);
 
+       handle_local_queue(tls, pool->thread_id);
+
        BLI_mutex_lock(&pool->num_mutex);
 
        while (pool->num != 0) {
@@ -913,7 +919,15 @@ void BLI_task_pool_work_and_wait(TaskPool *pool)
 
        BLI_mutex_unlock(&pool->num_mutex);
 
-       handle_local_queue(tls, pool->thread_id);
+       BLI_assert(tls->num_local_queue == 0);
+}
+
+void BLI_task_pool_work_wait_and_reset(TaskPool *pool)
+{
+       BLI_task_pool_work_and_wait(pool);
+
+       pool->do_work = false;
+       pool->is_suspended = pool->start_suspended;
 }
 
 void BLI_task_pool_cancel(TaskPool *pool)