Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2015-11-02 18:52:19 +0300
committerBastien Montagne <montagne29@wanadoo.fr>2015-11-02 18:52:19 +0300
commit44774f81606f74b0268f7e6fa58e67f1f8c28ca7 (patch)
treed341ed31685ad5fc364eddf61e1b6946c83a7eb3 /source/blender/blenlib
parent952afbf9168c8601e61fa64ffb37e6d93f1d3d61 (diff)
BLI_task: add freedata callback to tasks.
Useful in case one needs more complex handling of tasks data than a mere MEM_freeN().
Diffstat (limited to 'source/blender/blenlib')
-rw-r--r--source/blender/blenlib/BLI_task.h4
-rw-r--r--source/blender/blenlib/intern/task.c40
2 files changed, 33 insertions, 11 deletions
diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h
index 780b0bfbbd6..3bf58a64307 100644
--- a/source/blender/blenlib/BLI_task.h
+++ b/source/blender/blenlib/BLI_task.h
@@ -74,10 +74,14 @@ typedef enum TaskPriority {
typedef struct TaskPool TaskPool;
typedef void (*TaskRunFunction)(TaskPool *__restrict pool, void *taskdata, int threadid);
+typedef void (*TaskFreeFunction)(TaskPool *__restrict pool, void *taskdata, int threadid);
TaskPool *BLI_task_pool_create(TaskScheduler *scheduler, void *userdata);
void BLI_task_pool_free(TaskPool *pool);
+void BLI_task_pool_push_ex(
+ TaskPool *pool, TaskRunFunction run, void *taskdata,
+ bool free_taskdata, TaskFreeFunction freedata, TaskPriority priority);
void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run,
void *taskdata, bool free_taskdata, TaskPriority priority);
diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c
index 7ce230e97f3..20ea5ec5ec8 100644
--- a/source/blender/blenlib/intern/task.c
+++ b/source/blender/blenlib/intern/task.c
@@ -43,6 +43,7 @@ typedef struct Task {
TaskRunFunction run;
void *taskdata;
bool free_taskdata;
+ TaskFreeFunction freedata;
TaskPool *pool;
} Task;
@@ -79,6 +80,19 @@ typedef struct TaskThread {
int id;
} TaskThread;
+/* Helper */
+static void task_data_free(Task *task, const int thread_id)
+{
+ if (task->free_taskdata) {
+ if (task->freedata) {
+ task->freedata(task->pool, task->taskdata, thread_id);
+ }
+ else {
+ MEM_freeN(task->taskdata);
+ }
+ }
+}
+
/* Task Scheduler */
static void task_pool_num_decrease(TaskPool *pool, size_t done)
@@ -172,8 +186,7 @@ static void *task_scheduler_thread_run(void *thread_p)
task->run(pool, task->taskdata, thread_id);
/* delete task */
- if (task->free_taskdata)
- MEM_freeN(task->taskdata);
+ task_data_free(task, thread_id);
MEM_freeN(task);
/* notify pool task was done */
@@ -221,7 +234,7 @@ TaskScheduler *BLI_task_scheduler_create(int num_threads)
}
}
}
-
+
return scheduler;
}
@@ -254,8 +267,7 @@ void BLI_task_scheduler_free(TaskScheduler *scheduler)
/* delete leftover tasks */
for (task = scheduler->queue.first; task; task = task->next) {
- if (task->free_taskdata)
- MEM_freeN(task->taskdata);
+ task_data_free(task, 0);
}
BLI_freelistN(&scheduler->queue);
@@ -299,8 +311,7 @@ static void task_scheduler_clear(TaskScheduler *scheduler, TaskPool *pool)
nexttask = task->next;
if (task->pool == pool) {
- if (task->free_taskdata)
- MEM_freeN(task->taskdata);
+ task_data_free(task, 0);
BLI_freelinkN(&scheduler->queue, task);
done++;
@@ -356,19 +367,27 @@ void BLI_task_pool_free(TaskPool *pool)
BLI_end_threaded_malloc();
}
-void BLI_task_pool_push(TaskPool *pool, TaskRunFunction run,
- void *taskdata, bool free_taskdata, TaskPriority priority)
+void BLI_task_pool_push_ex(
+ TaskPool *pool, TaskRunFunction run, void *taskdata,
+ bool free_taskdata, TaskFreeFunction freedata, TaskPriority priority)
{
Task *task = MEM_callocN(sizeof(Task), "Task");
task->run = run;
task->taskdata = taskdata;
task->free_taskdata = free_taskdata;
+ task->freedata = freedata;
task->pool = pool;
task_scheduler_push(pool->scheduler, task, priority);
}
+void BLI_task_pool_push(
+ TaskPool *pool, TaskRunFunction run, void *taskdata, bool free_taskdata, TaskPriority priority)
+{
+ BLI_task_pool_push_ex(pool, run, taskdata, free_taskdata, NULL, priority);
+}
+
void BLI_task_pool_work_and_wait(TaskPool *pool)
{
TaskScheduler *scheduler = pool->scheduler;
@@ -408,8 +427,7 @@ void BLI_task_pool_work_and_wait(TaskPool *pool)
work_task->run(pool, work_task->taskdata, 0);
/* delete task */
- if (work_task->free_taskdata)
- MEM_freeN(work_task->taskdata);
+ task_data_free(task, 0);
MEM_freeN(work_task);
/* notify pool task was done */