From 9b7a2af07fd1f5df3e517021d676805eb20bc74f Mon Sep 17 00:00:00 2001 From: David Robillard Date: Thu, 9 Aug 2007 05:16:00 +0000 Subject: Realtime safe parallel graph execution, e.g. run with ingen -e -p 3 for 3 concurrent audio threads. git-svn-id: http://svn.drobilla.net/lad/ingen@689 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/engine/events/AddNodeEvent.cpp | 12 +++++----- src/libs/engine/events/AddNodeEvent.hpp | 23 ++++++++++--------- src/libs/engine/events/ClearPatchEvent.cpp | 6 ++--- src/libs/engine/events/ConnectionEvent.cpp | 11 ++++----- src/libs/engine/events/ConnectionEvent.hpp | 3 ++- src/libs/engine/events/CreatePatchEvent.cpp | 12 +++++----- src/libs/engine/events/CreatePatchEvent.hpp | 4 ++-- src/libs/engine/events/DestroyEvent.cpp | 33 ++++++++++++++------------- src/libs/engine/events/DestroyEvent.hpp | 3 ++- src/libs/engine/events/DisconnectionEvent.cpp | 12 +++++----- src/libs/engine/events/DisconnectionEvent.hpp | 3 ++- src/libs/engine/events/EnablePatchEvent.cpp | 10 ++++---- src/libs/engine/events/EnablePatchEvent.hpp | 7 +++--- 13 files changed, 72 insertions(+), 67 deletions(-) (limited to 'src/libs/engine/events') diff --git a/src/libs/engine/events/AddNodeEvent.cpp b/src/libs/engine/events/AddNodeEvent.cpp index e692a8ee..3b2b01cf 100644 --- a/src/libs/engine/events/AddNodeEvent.cpp +++ b/src/libs/engine/events/AddNodeEvent.cpp @@ -42,7 +42,7 @@ AddNodeEvent::AddNodeEvent(Engine& engine, SharedPtr responder, Sampl _poly(poly), _patch(NULL), _node(NULL), - _process_order(NULL), + _compiled_patch(NULL), _node_already_exists(false) { } @@ -62,7 +62,7 @@ AddNodeEvent::AddNodeEvent(Engine& engine, SharedPtr responder, Sampl _poly(poly), _patch(NULL), _node(NULL), - _process_order(NULL), + _compiled_patch(NULL), _node_already_exists(false) { } @@ -101,7 +101,7 @@ AddNodeEvent::pre_process() // FIXME: not really necessary to build process order since it's not connected, // just append to the list if (_patch->enabled()) - _process_order = _patch->build_process_order(); + _compiled_patch = _patch->compile(); } } QueuedEvent::pre_process(); @@ -114,9 +114,9 @@ AddNodeEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) QueuedEvent::execute(nframes, start, end); if (_node != NULL) { - if (_patch->process_order() != NULL) - _engine.maid()->push(_patch->process_order()); - _patch->process_order(_process_order); + if (_patch->compiled_patch() != NULL) + _engine.maid()->push(_patch->compiled_patch()); + _patch->compiled_patch(_compiled_patch); } } diff --git a/src/libs/engine/events/AddNodeEvent.hpp b/src/libs/engine/events/AddNodeEvent.hpp index 28df137c..eaf48807 100644 --- a/src/libs/engine/events/AddNodeEvent.hpp +++ b/src/libs/engine/events/AddNodeEvent.hpp @@ -31,6 +31,7 @@ namespace Ingen { class Patch; class Node; class Plugin; +class CompiledPatch; /** An event to load a Node and insert it into a Patch. @@ -62,17 +63,17 @@ public: void post_process(); private: - string _patch_name; - Raul::Path _path; - string _plugin_uri; ///< If nonempty then type, library, label, are ignored - string _plugin_type; - string _plugin_lib; - string _plugin_label; - bool _poly; - Patch* _patch; - Node* _node; - Raul::Array* _process_order; ///< Patch's new process order - bool _node_already_exists; + string _patch_name; + Raul::Path _path; + string _plugin_uri; ///< If nonempty then type, library, label, are ignored + string _plugin_type; + string _plugin_lib; + string _plugin_label; + bool _poly; + Patch* _patch; + Node* _node; + CompiledPatch* _compiled_patch; ///< Patch's new process order + bool _node_already_exists; }; diff --git a/src/libs/engine/events/ClearPatchEvent.cpp b/src/libs/engine/events/ClearPatchEvent.cpp index 2c991cf7..5a914901 100644 --- a/src/libs/engine/events/ClearPatchEvent.cpp +++ b/src/libs/engine/events/ClearPatchEvent.cpp @@ -72,9 +72,9 @@ ClearPatchEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) //for (Raul::List::const_iterator i = _patch->nodes().begin(); i != _patch->nodes().end(); ++i) // (*i)->remove_from_patch(); - if (_patch->process_order() != NULL) { - _engine.maid()->push(_patch->process_order()); - _patch->process_order(NULL); + if (_patch->compiled_patch() != NULL) { + _engine.maid()->push(_patch->compiled_patch()); + _patch->compiled_patch(NULL); } } } diff --git a/src/libs/engine/events/ConnectionEvent.cpp b/src/libs/engine/events/ConnectionEvent.cpp index a8c5dc13..69bb2645 100644 --- a/src/libs/engine/events/ConnectionEvent.cpp +++ b/src/libs/engine/events/ConnectionEvent.cpp @@ -41,7 +41,7 @@ ConnectionEvent::ConnectionEvent(Engine& engine, SharedPtr responder, _patch(NULL), _src_port(NULL), _dst_port(NULL), - _process_order(NULL), + _compiled_patch(NULL), _connection(NULL), _patch_listnode(NULL), _port_listnode(NULL), @@ -138,7 +138,7 @@ ConnectionEvent::pre_process() } if (_patch->enabled()) - _process_order = _patch->build_process_order(); + _compiled_patch = _patch->compile(); QueuedEvent::pre_process(); } @@ -153,9 +153,9 @@ ConnectionEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) // These must be inserted here, since they're actually used by the audio thread _dst_input_port->add_connection(_port_listnode); _patch->add_connection(_patch_listnode); - if (_patch->process_order() != NULL) - _engine.maid()->push(_patch->process_order()); - _patch->process_order(_process_order); + if (_patch->compiled_patch() != NULL) + _engine.maid()->push(_patch->compiled_patch()); + _patch->compiled_patch(_compiled_patch); } } @@ -170,7 +170,6 @@ ConnectionEvent::post_process() // FIXME: better error messages string msg = "Unable to make connection "; msg.append(_src_port_path + " -> " + _dst_port_path); - cerr << "CONNECTION ERROR " << (unsigned)_error << endl; _responder->respond_error(msg); } } diff --git a/src/libs/engine/events/ConnectionEvent.hpp b/src/libs/engine/events/ConnectionEvent.hpp index 1efcee1b..202fef01 100644 --- a/src/libs/engine/events/ConnectionEvent.hpp +++ b/src/libs/engine/events/ConnectionEvent.hpp @@ -39,6 +39,7 @@ class Port; class Connection; class InputPort; class OutputPort; +class CompiledPatch; /** Make a Connection between two Ports. @@ -75,7 +76,7 @@ private: OutputPort* _src_output_port; InputPort* _dst_input_port; - Raul::Array* _process_order; ///< New process order for Patch + CompiledPatch* _compiled_patch; ///< New process order for Patch Connection* _connection; Raul::ListNode* _patch_listnode; diff --git a/src/libs/engine/events/CreatePatchEvent.cpp b/src/libs/engine/events/CreatePatchEvent.cpp index 6c0cd0e8..365b1a02 100644 --- a/src/libs/engine/events/CreatePatchEvent.cpp +++ b/src/libs/engine/events/CreatePatchEvent.cpp @@ -36,7 +36,7 @@ CreatePatchEvent::CreatePatchEvent(Engine& engine, SharedPtr responde _path(path), _patch(NULL), _parent(NULL), - _process_order(NULL), + _compiled_patch(NULL), _poly(poly), _error(NO_ERROR) { @@ -69,13 +69,13 @@ CreatePatchEvent::pre_process() if (_parent != NULL && _poly > 1 && _poly == static_cast(_parent->internal_poly())) poly = _poly; - _patch = new Patch(_path.name(), poly, _parent, _engine.audio_driver()->sample_rate(), _engine.audio_driver()->buffer_size(), _poly); + _patch = new Patch(_engine, _path.name(), poly, _parent, _engine.audio_driver()->sample_rate(), _engine.audio_driver()->buffer_size(), _poly); if (_parent != NULL) { _parent->add_node(new Raul::ListNode(_patch)); if (_parent->enabled()) - _process_order = _parent->build_process_order(); + _compiled_patch = _parent->compile(); } _patch->activate(); @@ -102,9 +102,9 @@ CreatePatchEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) assert(_parent != NULL); assert(_path != "/"); - if (_parent->process_order() != NULL) - _engine.maid()->push(_parent->process_order()); - _parent->process_order(_process_order); + if (_parent->compiled_patch() != NULL) + _engine.maid()->push(_parent->compiled_patch()); + _parent->compiled_patch(_compiled_patch); } } } diff --git a/src/libs/engine/events/CreatePatchEvent.hpp b/src/libs/engine/events/CreatePatchEvent.hpp index 1e45b353..1eb33ed4 100644 --- a/src/libs/engine/events/CreatePatchEvent.hpp +++ b/src/libs/engine/events/CreatePatchEvent.hpp @@ -32,6 +32,7 @@ namespace Ingen { class Patch; class Node; class Plugin; +class CompiledPatch; /** Creates a new Patch. @@ -53,8 +54,7 @@ private: Raul::Path _path; Patch* _patch; Patch* _parent; - Raul::Array* _process_order; - TreeNode* _patch_treenode; + CompiledPatch* _compiled_patch; int _poly; ErrorType _error; }; diff --git a/src/libs/engine/events/DestroyEvent.cpp b/src/libs/engine/events/DestroyEvent.cpp index a30bb3ae..91823a79 100644 --- a/src/libs/engine/events/DestroyEvent.cpp +++ b/src/libs/engine/events/DestroyEvent.cpp @@ -47,7 +47,7 @@ DestroyEvent::DestroyEvent(Engine& engine, SharedPtr responder, Frame _patch_node_listnode(NULL), _patch_port_listnode(NULL), _ports_array(NULL), - _process_order(NULL), + _compiled_patch(NULL), _disconnect_node_event(NULL), _disconnect_port_event(NULL) { @@ -65,9 +65,8 @@ DestroyEvent::DestroyEvent(Engine& engine, SharedPtr responder, Frame _driver_port(NULL), _patch_node_listnode(NULL), _patch_port_listnode(NULL), - _store_treenode(NULL), _ports_array(NULL), - _process_order(NULL), + _compiled_patch(NULL), _disconnect_node_event(NULL), _disconnect_port_event(NULL) { @@ -114,17 +113,19 @@ DestroyEvent::pre_process() if (_node->parent_patch()->enabled()) { // FIXME: is this called multiple times? - _process_order = _node->parent_patch()->build_process_order(); + _compiled_patch = _node->parent_patch()->compile(); // Remove node to be removed from the process order so it isn't executed by // Patch::run and can safely be destroyed - //for (size_t i=0; i < _process_order->size(); ++i) - // if (_process_order->at(i) == _node) - // _process_order->at(i) = NULL; // ew, gap + //for (size_t i=0; i < _compiled_patch->size(); ++i) + // if (_compiled_patch->at(i) == _node) + // _compiled_patch->at(i) = NULL; // ew, gap #ifdef DEBUG // Be sure node is removed from process order, so it can be destroyed - for (size_t i=0; i < _process_order->size(); ++i) - assert(_process_order->at(i) != _node); + for (size_t i=0; i < _compiled_patch->size(); ++i) { + assert(_compiled_patch->at(i).node() != _node); + // FIXME: check providers/dependants too + } #endif } } @@ -141,7 +142,7 @@ DestroyEvent::pre_process() if (_port->parent_patch()->enabled()) { // FIXME: is this called multiple times? - _process_order = _port->parent_patch()->build_process_order(); + _compiled_patch = _port->parent_patch()->compile(); _ports_array = _port->parent_patch()->build_ports_array(); assert(_ports_array->size() == _port->parent_patch()->num_ports()); } @@ -164,9 +165,9 @@ DestroyEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) if (_disconnect_node_event) _disconnect_node_event->execute(nframes, start, end); - if (_node->parent_patch()->process_order()) - _engine.maid()->push(_node->parent_patch()->process_order()); - _node->parent_patch()->process_order(_process_order); + if (_node->parent_patch()->compiled_patch()) + _engine.maid()->push(_node->parent_patch()->compiled_patch()); + _node->parent_patch()->compiled_patch(_compiled_patch); } else if (_patch_port_listnode) { assert(_port); @@ -174,10 +175,10 @@ DestroyEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) if (_disconnect_port_event) _disconnect_port_event->execute(nframes, start, end); - if (_port->parent_patch()->process_order()) - _engine.maid()->push(_port->parent_patch()->process_order()); + if (_port->parent_patch()->compiled_patch()) + _engine.maid()->push(_port->parent_patch()->compiled_patch()); - _port->parent_patch()->process_order(_process_order); + _port->parent_patch()->compiled_patch(_compiled_patch); if (_port->parent_patch()->external_ports()) _engine.maid()->push(_port->parent_patch()->external_ports()); diff --git a/src/libs/engine/events/DestroyEvent.hpp b/src/libs/engine/events/DestroyEvent.hpp index a858ee0b..c401ff31 100644 --- a/src/libs/engine/events/DestroyEvent.hpp +++ b/src/libs/engine/events/DestroyEvent.hpp @@ -41,6 +41,7 @@ class DriverPort; class Plugin; class DisconnectNodeEvent; class DisconnectPortEvent; +class CompiledPatch; /** An event to remove and delete a Node. @@ -68,7 +69,7 @@ private: Raul::ListNode* _patch_node_listnode; Raul::ListNode* _patch_port_listnode; Raul::Array* _ports_array; ///< New (external) ports array for Patch - Raul::Array* _process_order; ///< Patch's new process order + CompiledPatch* _compiled_patch; ///< Patch's new process order DisconnectNodeEvent* _disconnect_node_event; DisconnectPortEvent* _disconnect_port_event; }; diff --git a/src/libs/engine/events/DisconnectionEvent.cpp b/src/libs/engine/events/DisconnectionEvent.cpp index 794399b3..67c3b5fb 100644 --- a/src/libs/engine/events/DisconnectionEvent.cpp +++ b/src/libs/engine/events/DisconnectionEvent.cpp @@ -44,7 +44,7 @@ DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr resp _src_port(NULL), _dst_port(NULL), _lookup(true), - _process_order(NULL), + _compiled_patch(NULL), _error(NO_ERROR) { } @@ -58,7 +58,7 @@ DisconnectionEvent::DisconnectionEvent(Engine& engine, SharedPtr resp _src_port(src_port), _dst_port(dst_port), _lookup(false), - _process_order(NULL), + _compiled_patch(NULL), _error(NO_ERROR) { // FIXME: These break for patch ports.. is that ok? @@ -145,7 +145,7 @@ DisconnectionEvent::pre_process() } if (_patch->enabled()) - _process_order = _patch->build_process_order(); + _compiled_patch = _patch->compile(); QueuedEvent::pre_process(); } @@ -172,9 +172,9 @@ DisconnectionEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) _engine.maid()->push(patch_connection); _engine.maid()->push(port_connection->elem()); - if (_patch->process_order() != NULL) - _engine.maid()->push(_patch->process_order()); - _patch->process_order(_process_order); + if (_patch->compiled_patch() != NULL) + _engine.maid()->push(_patch->compiled_patch()); + _patch->compiled_patch(_compiled_patch); } else { _error = CONNECTION_NOT_FOUND; } diff --git a/src/libs/engine/events/DisconnectionEvent.hpp b/src/libs/engine/events/DisconnectionEvent.hpp index 5a30b7f1..7109c645 100644 --- a/src/libs/engine/events/DisconnectionEvent.hpp +++ b/src/libs/engine/events/DisconnectionEvent.hpp @@ -39,6 +39,7 @@ class Port; class Connection; class InputPort; class OutputPort; +class CompiledPatch; /** Make a Connection between two Ports. @@ -78,7 +79,7 @@ private: bool _lookup; - Raul::Array* _process_order; ///< New process order for Patch + CompiledPatch* _compiled_patch; ///< New process order for Patch ErrorType _error; }; diff --git a/src/libs/engine/events/EnablePatchEvent.cpp b/src/libs/engine/events/EnablePatchEvent.cpp index ed39ae04..46cc5cc6 100644 --- a/src/libs/engine/events/EnablePatchEvent.cpp +++ b/src/libs/engine/events/EnablePatchEvent.cpp @@ -30,7 +30,7 @@ EnablePatchEvent::EnablePatchEvent(Engine& engine, SharedPtr responde : QueuedEvent(engine, responder, timestamp), _patch_path(patch_path), _patch(NULL), - _process_order(NULL) + _compiled_patch(NULL) { } @@ -44,8 +44,8 @@ EnablePatchEvent::pre_process() /* Any event that requires a new process order will set the patch's * process order to NULL if it is executed when the patch is not * active. So, if the PO is NULL, calculate it here */ - if (_patch->process_order() == NULL) - _process_order = _patch->build_process_order(); + if (_patch->compiled_patch() == NULL) + _compiled_patch = _patch->compile(); } QueuedEvent::pre_process(); @@ -60,8 +60,8 @@ EnablePatchEvent::execute(SampleCount nframes, FrameTime start, FrameTime end) if (_patch != NULL) { _patch->enable(); - if (_patch->process_order() == NULL) - _patch->process_order(_process_order); + if (_patch->compiled_patch() == NULL) + _patch->compiled_patch(_compiled_patch); } } diff --git a/src/libs/engine/events/EnablePatchEvent.hpp b/src/libs/engine/events/EnablePatchEvent.hpp index d187594b..2bacd17d 100644 --- a/src/libs/engine/events/EnablePatchEvent.hpp +++ b/src/libs/engine/events/EnablePatchEvent.hpp @@ -29,6 +29,7 @@ namespace Ingen { class Patch; class Node; +class CompiledPatch; /** Enables a patch's DSP processing. @@ -45,9 +46,9 @@ public: void post_process(); private: - string _patch_path; - Patch* _patch; - Raul::Array* _process_order; // Patch's new process order + string _patch_path; + Patch* _patch; + CompiledPatch* _compiled_patch; // Patch's new process order }; -- cgit v1.2.1