[Bf-blender-cvs] [6bfe5e6] depsgraph_refactor: Extended scheduler implementation, adding task pools.
Lukas Tönne
noreply at git.blender.org
Sun May 25 11:18:26 CEST 2014
Commit: 6bfe5e63aa85ddf96f3b512a5df1ec3c6f6bad84
Author: Lukas Tönne
Date: Sun May 25 11:09:01 2014 +0200
https://developer.blender.org/rB6bfe5e63aa85ddf96f3b512a5df1ec3c6f6bad84
Extended scheduler implementation, adding task pools.
This is a concept added by Cycles and the current depsgraph. It allows
sorting tasks into groups (pools) and wait/stop/cancel them based on
these groups.
This might come in handy later for different evaluation contexts.
===================================================================
M source/blender/blenkernel/intern/scene.c
M source/blender/depsgraph/CMakeLists.txt
M source/blender/depsgraph/intern/depsgraph_eval.cpp
M source/blender/depsgraph/intern/depsgraph_eval.h
A source/blender/depsgraph/util/depsgraph_util_task.cpp
A source/blender/depsgraph/util/depsgraph_util_task.h
M source/blender/depsgraph/util/depsgraph_util_thread.h
===================================================================
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index dc82661..80a5c88 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -1550,7 +1550,7 @@ void BKE_scene_update_tagged(EvaluationContext *eval_ctx, Main *bmain, Scene *sc
{
Scene *sce_iter;
- /********* new depsgraph *********/\
+ /********* new depsgraph *********/
if (scene->depsgraph)
DEG_evaluate_on_refresh(scene->depsgraph, eval_ctx->for_render ? DEG_EVALUATION_CONTEXT_RENDER : DEG_EVALUATION_CONTEXT_VIEWPORT);
/******************/
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index 803c316..2a52114 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -76,6 +76,8 @@ set(SRC
util/depsgraph_util_rna.h
util/depsgraph_util_set.h
util/depsgraph_util_string.h
+ util/depsgraph_util_task.h
+ util/depsgraph_util_task.cpp
util/depsgraph_util_thread.h
util/depsgraph_util_type_traits.h
)
diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cpp b/source/blender/depsgraph/intern/depsgraph_eval.cpp
index 60bd6fa..1b41e98 100644
--- a/source/blender/depsgraph/intern/depsgraph_eval.cpp
+++ b/source/blender/depsgraph/intern/depsgraph_eval.cpp
@@ -73,13 +73,13 @@ extern "C" {
/* Initialise threading lock - called during application startup */
void DEG_threaded_init(void)
{
- Scheduler::init();
+ DepsgraphTaskScheduler::init();
}
/* Free threading lock - called during application shutdown */
void DEG_threaded_exit(void)
{
- Scheduler::exit();
+ DepsgraphTaskScheduler::exit();
}
/* *************************************************** */
@@ -120,140 +120,6 @@ static void deg_exec_node(Depsgraph *graph, DepsNode *node, eEvaluationContextTy
/* NOTE: "generic" nodes cannot be executed, but will still end up calling this */
}
-EvalQueue Scheduler::queue;
-ThreadMutex Scheduler::queue_mutex;
-ThreadCondition Scheduler::queue_cond;
-ThreadMutex Scheduler::mutex;
-Scheduler::Threads Scheduler::threads;
-bool Scheduler::do_exit;
-
-void Scheduler::init(int num_threads)
-{
- BLI_mutex_init(&mutex);
- BLI_mutex_init(&queue_mutex);
- BLI_condition_init(&queue_cond);
-
- do_exit = false;
-
- if(num_threads == 0) {
- /* automatic number of threads */
- num_threads = BLI_system_thread_count();
- }
-
- /* launch threads that will be waiting for work */
- threads.resize(num_threads);
-
- for(size_t i = 0; i < threads.size(); i++)
- threads[i] = new Thread((Thread::run_cb_t)Scheduler::thread_run, i);
-}
-
-void Scheduler::exit()
-{
- /* stop all waiting threads */
- do_exit = true;
- BLI_condition_notify_all(&queue_cond);
-
- /* delete threads */
- for (Threads::const_iterator it = threads.begin(); it != threads.end(); ++it) {
- Thread *t = *it;
- t->join();
- delete t;
- }
- threads.clear();
-
- BLI_mutex_end(&mutex);
- BLI_mutex_end(&queue_mutex);
- BLI_condition_end(&queue_cond);
-}
-
-bool Scheduler::thread_wait_pop(DepsgraphTask &task)
-{
- BLI_mutex_lock(&queue_mutex);
-
- while(queue.empty() && !do_exit)
- BLI_condition_wait(&queue_cond, &queue_mutex);
-
- if(queue.empty()) {
- BLI_assert(do_exit);
- return false;
- }
-
- task = queue.top();
- queue.pop();
-
- BLI_mutex_unlock(&queue_mutex);
-
- return true;
-}
-
-void Scheduler::thread_run(Thread *thread)
-{
- DepsgraphTask task;
-
- /* keep popping off tasks */
- while(thread_wait_pop(task)) {
- /* run task */
-
- deg_exec_node(task.graph, task.node, task.context_type);
-
- /* notify pool task was done */
- finish_node(task.graph, task.context_type, task.node);
- }
-}
-
-static bool is_node_ready(OperationDepsNode *node)
-{
- return (node->flag & DEPSOP_FLAG_NEEDS_UPDATE) && node->num_links_pending == 0;
-}
-
-void Scheduler::schedule_graph(Depsgraph *graph, eEvaluationContextType context_type)
-{
- BLI_mutex_lock(&queue_mutex);
-
- for (Depsgraph::OperationNodes::const_iterator it = graph->operations.begin(); it != graph->operations.end(); ++it) {
- OperationDepsNode *node = *it;
-
- if (is_node_ready(node)) {
- schedule_node(graph, context_type, node);
- }
- }
-
- BLI_mutex_unlock(&queue_mutex);
-}
-
-void Scheduler::schedule_node(Depsgraph *graph, eEvaluationContextType context_type, OperationDepsNode *node)
-{
- DepsgraphTask task;
- task.graph = graph;
- task.node = node;
- task.context_type = context_type;
-
- queue.push(task);
-}
-
-void Scheduler::finish_node(Depsgraph *graph, eEvaluationContextType context_type, OperationDepsNode *node)
-{
- bool notify = false;
-
- BLI_mutex_lock(&queue_mutex);
-
- for (OperationDepsNode::Relations::const_iterator it = node->outlinks.begin(); it != node->outlinks.end(); ++it) {
- DepsRelation *rel = *it;
-
- BLI_assert(rel->to->num_links_pending > 0);
- --rel->to->num_links_pending;
- if (rel->to->num_links_pending == 0) {
- schedule_node(graph, context_type, rel->to);
- notify = true;
- }
- }
-
- BLI_mutex_unlock(&queue_mutex);
-
- if (notify)
- BLI_condition_notify_all(&queue_cond);
-}
-
/* *************************************************** */
/* Evaluation Entrypoints */
@@ -295,6 +161,23 @@ static void calculate_eval_priority(OperationDepsNode *node)
node->eval_priority = 0.0f;
}
+static bool is_node_ready(OperationDepsNode *node)
+{
+ return (node->flag & DEPSOP_FLAG_NEEDS_UPDATE) && node->num_links_pending == 0;
+}
+
+static void schedule_graph(DepsgraphTaskPool &pool, Depsgraph *graph, eEvaluationContextType context_type)
+{
+ for (Depsgraph::OperationNodes::const_iterator it = graph->operations.begin(); it != graph->operations.end(); ++it) {
+ OperationDepsNode *node = *it;
+
+ if (is_node_ready(node)) {
+ /* XXX TODO */
+// pool.push();
+// schedule_node(graph, context_type, node);
+ }
+ }
+}
/* Evaluate all nodes tagged for updating
@@ -306,6 +189,9 @@ void DEG_evaluate_on_refresh(Depsgraph *graph, eEvaluationContextType context_ty
/* generate base evaluation context, upon which all the others are derived... */
// TODO: this needs both main and scene access...
+ /* XXX could use a separate pool for each eval context */
+ static DepsgraphTaskPool task_pool = DepsgraphTaskPool();
+
/* clear tags */
for (Depsgraph::OperationNodes::const_iterator it = graph->operations.begin(); it != graph->operations.end(); ++it) {
OperationDepsNode *node = *it;
@@ -322,7 +208,7 @@ void DEG_evaluate_on_refresh(Depsgraph *graph, eEvaluationContextType context_ty
DEG_debug_eval_step("Eval Priority Calculation");
- Scheduler::schedule_graph(graph, context_type);
+ schedule_graph(task_pool, graph, context_type);
/* from the root node, start queuing up nodes to evaluate */
// ... start scheduler, etc.
diff --git a/source/blender/depsgraph/intern/depsgraph_eval.h b/source/blender/depsgraph/intern/depsgraph_eval.h
index 4bfd63e..0eca9c1 100644
--- a/source/blender/depsgraph/intern/depsgraph_eval.h
+++ b/source/blender/depsgraph/intern/depsgraph_eval.h
@@ -33,12 +33,9 @@
#ifndef __DEPSGRAPH_EVAL_TYPES_H__
#define __DEPSGRAPH_EVAL_TYPES_H__
-#include <vector>
-
#include "DEG_depsgraph.h"
-#include "depsgraph_util_priority_queue.h"
-#include "depsgraph_util_thread.h"
+#include "depsgraph_util_task.h"
struct Depsgraph;
struct OperationDepsNode;
@@ -131,52 +128,4 @@ typedef struct DEG_PoseContext {
/* ****************************************** */
-struct DepsgraphTask {
- Depsgraph *graph;
- OperationDepsNode *node;
- eEvaluationContextType context_type;
-};
-
-struct CompareDepsgraphTask {
- bool operator() (const DepsgraphTask &a, const DepsgraphTask &b)
- {
- return a.node->eval_priority < b.node->eval_priority;
- }
-};
-
-typedef priority_queue<DepsgraphTask, vector<DepsgraphTask>, CompareDepsgraphTask> EvalQueue;
-
-class Scheduler {
-public:
- typedef std::vector<Thread*> Threads;
-
- static void init(int num_threads = 0);
- static void exit();
-
- /* number of threads that can work on task */
- static int num_threads() { return threads.size(); }
-
- static void schedule_graph(Depsgraph *graph, eEvaluationContextType context_type);
- static void schedule_node(Depsgraph *graph, eEvaluationContextType context_type, OperationDepsNode *node);
- static void finish_node(Depsgraph *graph, eEvaluationContextType context_type, OperationDepsNode *node);
-
- static EvalQueue queue;
- static ThreadMutex queue_mutex;
- static ThreadCondition queue_cond;
- /* XXX consider using spin lock here */
-
- static void thread_run(Thread *thread);
- static bool thread_wait_pop(DepsgraphTask &task);
-
- //static void push(Entry& entry, bool front);
- //static void clear(TaskPool *pool);
-
-private:
- static ThreadMutex mutex;
- static Threads threads;
- static bool do_exit;
-};
-
-/* ****************************************** */
-
#endif // __DEPSGRAPH_EVAL_TYPES_H__
diff --git a/source/blender/depsgraph/util/depsgraph_util_task.cpp b/source/blender/depsgraph/util/depsgraph_util_task.cpp
new file mode 100644
index 0000000..e5906be
--- /dev/null
+++ b/source/blender/depsgraph/util/depsgraph_util_task.cpp
@@ -0,0 +1,341 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2013 Blender Foundation.
+ * All rights reserved.
+ *
+ * Original Author: Brecht van Lommel
+ * Contributor(s): Lukas Toenne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <stdlib.h>
+#include "BLI_utildefines.h"
+
+#include "depsgraph_util_task.h"
+
+/*
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list