summaryrefslogtreecommitdiff
path: root/libs/ardour/graphnode.cc
diff options
context:
space:
mode:
authorRobin Gareus <robin@gareus.org>2019-07-10 19:11:07 +0200
committerRobin Gareus <robin@gareus.org>2019-07-10 20:39:27 +0200
commitb7369f421f151a7e9f31969828c38882027cd996 (patch)
treeb8c1116e1228b4045d72c31b6435fd30adf7cf63 /libs/ardour/graphnode.cc
parent929ecf622bf86f4126433c20fb57e7978881362f (diff)
Re-work process-graph to use lock-free queues
This removes the trigger_mutex which was used for exclusive access of the work-queue for concurrent processing.
Diffstat (limited to 'libs/ardour/graphnode.cc')
-rw-r--r--libs/ardour/graphnode.cc43
1 files changed, 22 insertions, 21 deletions
diff --git a/libs/ardour/graphnode.cc b/libs/ardour/graphnode.cc
index 47cabfbae0..b42d57bf9c 100644
--- a/libs/ardour/graphnode.cc
+++ b/libs/ardour/graphnode.cc
@@ -25,11 +25,11 @@
using namespace ARDOUR;
GraphNode::GraphNode (boost::shared_ptr<Graph> graph)
- : _graph(graph)
+ : _graph (graph)
{
}
-GraphNode::~GraphNode()
+GraphNode::~GraphNode ()
{
}
@@ -37,19 +37,20 @@ void
GraphNode::prep (int chain)
{
/* This is the number of nodes that directly feed us */
- _refcount = _init_refcount[chain];
+ g_atomic_int_set (&_refcount, _init_refcount[chain]);
}
-/** Called by another node to tell us that one of the nodes that feed us
- * has been processed.
- */
+/** Called by an upstream node, when it has completed processing */
void
-GraphNode::dec_ref()
+GraphNode::trigger ()
{
+ /* check if we can run */
if (g_atomic_int_dec_and_test (&_refcount)) {
- /* All the nodes that feed us are done, so we can queue this node
- * for processing.
- */
+#if 0 // TODO optimize: remove prep()
+ /* reset reference count for next cycle */
+ g_atomic_int_set (&_refcount, _init_refcount[chain]);
+#endif
+ /* All nodes that feed this node have completed, so this node be processed now. */
_graph->trigger (this);
}
}
@@ -58,23 +59,23 @@ void
GraphNode::finish (int chain)
{
node_set_t::iterator i;
- bool feeds_somebody = false;
+ bool feeds = false;
- /* Tell the nodes that we feed that we've finished */
- for (i=_activation_set[chain].begin(); i!=_activation_set[chain].end(); i++) {
- (*i)->dec_ref();
- feeds_somebody = true;
+ /* Notify downstream nodes that depend on this node */
+ for (i = _activation_set[chain].begin (); i != _activation_set[chain].end (); ++i) {
+ (*i)->trigger ();
+ feeds = true;
}
- if (!feeds_somebody) {
- /* This node does not feed anybody, so decrement the graph's finished count */
- _graph->dec_ref();
+ if (!feeds) {
+ /* This node is a terminal node that does not feed another note,
+ * so notify the graph to decrement the the finished count */
+ _graph->reached_terminal_node ();
}
}
-
void
-GraphNode::process()
+GraphNode::process ()
{
- _graph->process_one_route (dynamic_cast<Route *>(this));
+ _graph->process_one_route (dynamic_cast<Route*> (this));
}