From 93e662348cac56ae7c8406d46714ea0198f6cdd9 Mon Sep 17 00:00:00 2001 From: Carl Hetherington Date: Sat, 5 Nov 2011 17:54:44 +0000 Subject: A few more comments. git-svn-id: svn://localhost/ardour2/branches/3.0@10462 d708f5d6-7413-0410-9779-e7cbd77b26cf --- libs/ardour/ardour/graph.h | 6 +++++- libs/ardour/ardour/graphnode.h | 1 + libs/ardour/graph.cc | 19 +++++++++++++++++-- libs/ardour/graphnode.cc | 11 ++++++++++- 4 files changed, 33 insertions(+), 4 deletions(-) (limited to 'libs') diff --git a/libs/ardour/ardour/graph.h b/libs/ardour/ardour/graph.h index 18a8c7a4c9..14ef353853 100644 --- a/libs/ardour/ardour/graph.h +++ b/libs/ardour/ardour/graph.h @@ -108,12 +108,16 @@ private: PBD::ProcessSemaphore _execution_sem; + /** Signalled to start a run of the graph for a process callback */ PBD::ProcessSemaphore _callback_start_sem; PBD::ProcessSemaphore _callback_done_sem; PBD::ProcessSemaphore _cleanup_sem; + /** The number of processing threads that are asleep */ volatile gint _execution_tokens; + /** The number of unprocessed nodes that do not feed any other node; updated during processing */ volatile gint _finished_refcount; + /** The initial number of nodes that do not feed any other node (for each chain) */ volatile gint _init_finished_refcount[2]; bool _graph_empty; @@ -135,7 +139,7 @@ private: bool _process_silent; bool _process_noroll; - int _process_retval; + int _process_retval; bool _process_need_butler; }; diff --git a/libs/ardour/ardour/graphnode.h b/libs/ardour/ardour/graphnode.h index 191babdb12..9e0182300f 100644 --- a/libs/ardour/ardour/graphnode.h +++ b/libs/ardour/ardour/graphnode.h @@ -53,6 +53,7 @@ class GraphNode private: friend class Graph; + /** Nodes that we directly feed */ node_set_t _activation_set[2]; boost::shared_ptr _graph; diff --git a/libs/ardour/graph.cc b/libs/ardour/graph.cc index 0950ee28c0..9dfc611e17 100644 --- a/libs/ardour/graph.cc +++ b/libs/ardour/graph.cc @@ -93,6 +93,7 @@ Graph::parameter_changed (std::string param) } } +/** Set up threads for running the graph */ void Graph::reset_thread_list () { @@ -220,6 +221,7 @@ Graph::prep() } _finished_refcount = _init_finished_refcount[chain]; + /* Trigger the initial nodes for processing, which are the ones at the `input' end */ for (i=_init_trigger_list[chain].begin(); i!=_init_trigger_list[chain].end(); i++) { this->trigger( i->get() ); } @@ -233,6 +235,9 @@ Graph::trigger (GraphNode* n) pthread_mutex_unlock (&_trigger_mutex); } +/** Called when a node at the `output' end of the chain (ie one that has no-one to feed) + * is finished. + */ void Graph::dec_ref() { @@ -254,7 +259,7 @@ Graph::restart_cycle() again: _callback_done_sem.signal (); - // block until we are triggered. + /* Block until the a process callback triggers us */ _callback_start_sem.wait(); if (_quit_threads) { @@ -383,6 +388,9 @@ Graph::rechain (boost::shared_ptr routelist) dump(chain); } +/** Called by both the main thread and all helpers. + * @return true to quit, false to carry on. + */ bool Graph::run_one() { @@ -396,10 +404,14 @@ Graph::run_one() to_run = 0; } + /* the number of threads that are asleep */ int et = _execution_tokens; + /* the number of nodes that need to be run */ int ts = _trigger_queue.size(); + /* hence how many threads to wake up */ int wakeup = min (et, ts); + /* update the number of threads that will still be sleeping */ _execution_tokens -= wakeup; DEBUG_TRACE(DEBUG::ProcessThreads, string_compose ("%1 signals %2\n", pthread_self(), wakeup)); @@ -470,6 +482,7 @@ Graph::helper_thread() pt->drop_buffers(); } +/** Here's the main graph thread */ void Graph::main_thread() { @@ -482,6 +495,7 @@ Graph::main_thread() again: _callback_start_sem.wait (); + DEBUG_TRACE(DEBUG::ProcessThreads, "main thread is awake\n"); if (_quit_threads) { @@ -492,10 +506,11 @@ Graph::main_thread() if (_graph_empty && !_quit_threads) { _callback_done_sem.signal (); - DEBUG_TRACE(DEBUG::ProcessThreads, "main thread sees graph done, goes back to slee\n"); + DEBUG_TRACE(DEBUG::ProcessThreads, "main thread sees graph done, goes back to sleep\n"); goto again; } + /* This loop will run forever */ while (1) { DEBUG_TRACE(DEBUG::ProcessThreads, "main thread runs one graph node\n"); if (run_one()) { diff --git a/libs/ardour/graphnode.cc b/libs/ardour/graphnode.cc index 72b64abae0..c8923a043d 100644 --- a/libs/ardour/graphnode.cc +++ b/libs/ardour/graphnode.cc @@ -36,14 +36,22 @@ GraphNode::~GraphNode() void GraphNode::prep (int chain) { + /* This is the number of nodes that directly feed us */ _refcount = _init_refcount[chain]; } +/** Called by another node to tell us that one of the nodes that feed us + * has been processed. + */ void GraphNode::dec_ref() { - if (g_atomic_int_dec_and_test (&_refcount)) + if (g_atomic_int_dec_and_test (&_refcount)) { + /* All the nodes that feed us are done, so we can queue this node + for processing. + */ _graph->trigger (this); + } } void @@ -52,6 +60,7 @@ GraphNode::finish (int chain) node_set_t::iterator i; bool feeds_somebody = 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; -- cgit v1.2.3