summaryrefslogtreecommitdiffstats
path: root/src/engine
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine')
-rw-r--r--src/engine/Driver.hpp8
-rw-r--r--src/engine/Engine.cpp35
-rw-r--r--src/engine/Engine.hpp44
-rw-r--r--src/engine/EngineStore.hpp2
-rw-r--r--src/engine/JackDriver.cpp13
-rw-r--r--src/engine/PatchImpl.cpp19
-rw-r--r--src/engine/ProcessContext.cpp36
-rw-r--r--src/engine/ProcessContext.hpp26
-rw-r--r--src/engine/ProcessSlave.cpp2
-rw-r--r--src/engine/ProcessSlave.hpp45
-rw-r--r--src/engine/QueuedEngineInterface.cpp6
-rw-r--r--src/engine/wscript1
12 files changed, 132 insertions, 105 deletions
diff --git a/src/engine/Driver.hpp b/src/engine/Driver.hpp
index c744b54f..6951d357 100644
--- a/src/engine/Driver.hpp
+++ b/src/engine/Driver.hpp
@@ -97,15 +97,17 @@ public:
virtual void add_port(DriverPort* port) = 0;
/** Remove a system visible port. */
- virtual Raul::Deletable* remove_port(const Raul::Path& path, Ingen::DriverPort** port=NULL) = 0;
+ virtual Raul::Deletable* remove_port(const Raul::Path& path,
+ Ingen::DriverPort** port=NULL) = 0;
/** Return true iff this driver supports the given type of I/O */
- virtual bool supports(Shared::PortType port_type, Shared::EventType event_type) = 0;
+ virtual bool supports(Shared::PortType port_type,
+ Shared::EventType event_type) = 0;
virtual void set_root_patch(PatchImpl* patch) = 0;
virtual PatchImpl* root_patch() = 0;
- /** Return the audio buffer size in frames (i.e. the maximum length of a process cycle) */
+ /** Return the audio buffer size in frames */
virtual SampleCount block_length() const = 0;
/** Return the sample rate in Hz */
diff --git a/src/engine/Engine.cpp b/src/engine/Engine.cpp
index b57fa542..538b967f 100644
--- a/src/engine/Engine.cpp
+++ b/src/engine/Engine.cpp
@@ -43,7 +43,6 @@
#include "PatchImpl.hpp"
#include "PostProcessor.hpp"
#include "ProcessContext.hpp"
-#include "ProcessSlave.hpp"
#include "QueuedEngineInterface.hpp"
#include "ThreadManager.hpp"
#include "tuning.hpp"
@@ -67,7 +66,6 @@ Engine::Engine(Ingen::Shared::World* a_world)
, _buffer_factory(new BufferFactory(*this, a_world->uris()))
, _control_bindings(new ControlBindings(*this))
, _quit_flag(false)
- , _activated(false)
{
if (a_world->store()) {
assert(PtrCast<EngineStore>(a_world->store()));
@@ -126,6 +124,13 @@ Engine::add_event_source(SharedPtr<EventSource> source)
}
+void
+Engine::set_driver(SharedPtr<Driver> driver)
+{
+ _driver = driver;
+}
+
+
static void
execute_and_delete_event(ProcessContext& context, QueuedEvent* ev)
{
@@ -139,19 +144,13 @@ execute_and_delete_event(ProcessContext& context, QueuedEvent* ev)
bool
Engine::activate()
{
- if (_activated)
- return true;
-
assert(_driver);
- //assert(ThreadManager::single_threaded == true);
ThreadManager::single_threaded = true;
_buffer_factory->set_block_length(_driver->block_length());
_message_context->Thread::start();
- uint32_t parallelism = _world->conf()->option("parallelism").get_int32();
-
for (EventSources::iterator i = _event_sources.begin(); i != _event_sources.end(); ++i)
(*i)->activate_source();
@@ -205,15 +204,8 @@ Engine::activate()
}
_driver->activate();
-
- _process_slaves.clear();
- _process_slaves.reserve(parallelism);
- for (size_t i=0; i < parallelism - 1; ++i)
- _process_slaves.push_back(new ProcessSlave(*this, _driver->is_realtime()));
-
root_patch->enable();
- _activated = true;
ThreadManager::single_threaded = false;
return true;
@@ -223,16 +215,12 @@ Engine::activate()
void
Engine::deactivate()
{
- if (!_activated)
- return;
-
for (EventSources::iterator i = _event_sources.begin(); i != _event_sources.end(); ++i)
(*i)->deactivate_source();
_driver->deactivate();
_driver->root_patch()->deactivate();
- _activated = false;
ThreadManager::single_threaded = true;
}
@@ -240,16 +228,11 @@ Engine::deactivate()
void
Engine::process_events(ProcessContext& context)
{
+ ThreadManager::assert_thread(THREAD_PROCESS);
+
for (EventSources::iterator i = _event_sources.begin(); i != _event_sources.end(); ++i)
(*i)->process(*_post_processor, context);
}
-bool
-Engine::activated()
-{
- return _activated;
-}
-
-
} // namespace Ingen
diff --git a/src/engine/Engine.hpp b/src/engine/Engine.hpp
index c2756e11..e50704f5 100644
--- a/src/engine/Engine.hpp
+++ b/src/engine/Engine.hpp
@@ -44,8 +44,6 @@ class MessageContext;
class NodeFactory;
class PostProcessor;
class ProcessContext;
-class ProcessSlave;
-
/**
The engine which executes the process graph.
@@ -54,7 +52,7 @@ class ProcessSlave;
that make up the engine implementation. In processes with a local engine,
it can be accessed via the Ingen::Shared::World.
- \ingroup engine
+ @ingroup engine
*/
class Engine : public boost::noncopyable
{
@@ -63,6 +61,9 @@ public:
virtual ~Engine();
+ virtual void set_driver(SharedPtr<Driver> driver);
+ virtual void add_event_source(SharedPtr<EventSource> source);
+
virtual bool activate();
virtual void deactivate();
@@ -70,26 +71,29 @@ public:
Indicate that a quit is desired
This function simply sets a flag which affects the return value of
- main iteration, it does not actually force the engine to stop running
- or block. The code driving the engine is responsible for stopping
- and cleaning up when main_iteration returns false.
+ main_iteration, it does not actually force the engine to stop running or
+ block. The code driving the engine is responsible for stopping and
+ cleaning up when main_iteration returns false.
*/
virtual void quit();
/**
Run a single iteration of the main context.
- The main context performs housekeeping duties like collecting garbage.
- This should be called regularly, e.g. a few times per second.
- The return value indicates whether execution should continue; i.e. if
- false is returned, the caller should cease calling main_iteration()
- and stop the engine.
+ The main context post-processes events and performs housekeeping duties
+ like collecting garbage. This should be called regularly, e.g. a few
+ times per second. The return value indicates whether execution should
+ continue; i.e. if false is returned, a quit has been requested and the
+ caller should cease calling main_iteration() and stop the engine.
*/
virtual bool main_iteration();
- virtual void process_events(ProcessContext& context);
+ /**
+ Process all events for this process cycle.
- virtual bool activated();
+ Must be called (likely by the Driver) from the process thread.
+ */
+ virtual void process_events(ProcessContext& context);
virtual BufferFactory* buffer_factory() const { return _buffer_factory; }
virtual ClientBroadcaster* broadcaster() const { return _broadcaster; }
@@ -99,24 +103,14 @@ public:
virtual NodeFactory* node_factory() const { return _node_factory; }
virtual PostProcessor* post_processor() const { return _post_processor; }
virtual Raul::Maid* maid() const { return _maid; }
+ virtual Shared::World* world() const { return _world; }
virtual SharedPtr<EngineStore> engine_store() const;
- virtual void set_driver(SharedPtr<Driver> driver) { _driver = driver; }
-
- virtual void add_event_source(SharedPtr<EventSource> source);
-
- virtual Ingen::Shared::World* world() { return _world; }
-
- typedef std::vector<ProcessSlave*> ProcessSlaves;
- virtual const ProcessSlaves& process_slaves() const { return _process_slaves; }
- virtual ProcessSlaves& process_slaves() { return _process_slaves; }
-
private:
typedef std::set< SharedPtr<EventSource> > EventSources;
EventSources _event_sources;
- ProcessSlaves _process_slaves;
Ingen::Shared::World* _world;
SharedPtr<Driver> _driver;
Raul::Maid* _maid;
@@ -128,10 +122,8 @@ private:
ControlBindings* _control_bindings;
bool _quit_flag;
- bool _activated;
};
-
} // namespace Ingen
#endif // INGEN_ENGINE_ENGINE_HPP
diff --git a/src/engine/EngineStore.hpp b/src/engine/EngineStore.hpp
index c6d428fd..0e30f9cb 100644
--- a/src/engine/EngineStore.hpp
+++ b/src/engine/EngineStore.hpp
@@ -18,8 +18,8 @@
#ifndef INGEN_ENGINE_OBJECTSTORE_HPP
#define INGEN_ENGINE_OBJECTSTORE_HPP
-#include <string>
#include "raul/SharedPtr.hpp"
+
#include "shared/Store.hpp"
namespace Ingen {
diff --git a/src/engine/JackDriver.cpp b/src/engine/JackDriver.cpp
index c807c098..e3c89ca6 100644
--- a/src/engine/JackDriver.cpp
+++ b/src/engine/JackDriver.cpp
@@ -291,19 +291,24 @@ JackDriver::attach(const std::string& server_name,
void
JackDriver::activate()
{
+ Shared::World* world = _engine.world();
+
if (_is_activated) {
LOG(warn) << "Jack driver already activated." << endl;
return;
}
if (!_client)
- attach(_engine.world()->conf()->option("jack-server").get_string(),
- _engine.world()->conf()->option("jack-client").get_string(), NULL);
+ attach(world->conf()->option("jack-server").get_string(),
+ world->conf()->option("jack-client").get_string(), NULL);
jack_set_process_callback(_client, process_cb, this);
_is_activated = true;
+ _process_context.activate(world->conf()->option("parallelism").get_int32(),
+ is_realtime());
+
if (jack_activate(_client)) {
LOG(error) << "Could not activate Jack client, aborting." << endl;
exit(EXIT_FAILURE);
@@ -446,8 +451,8 @@ JackDriver::_process_cb(jack_nframes_t nframes)
_process_context.locate(start_of_current_cycle, nframes, 0);
- for (Engine::ProcessSlaves::iterator i = _engine.process_slaves().begin();
- i != _engine.process_slaves().end(); ++i) {
+ for (ProcessContext::Slaves::iterator i = _process_context.slaves().begin();
+ i != _process_context.slaves().end(); ++i) {
(*i)->context().locate(start_of_current_cycle, nframes, 0);
}
diff --git a/src/engine/PatchImpl.cpp b/src/engine/PatchImpl.cpp
index eab1aed5..a9be238f 100644
--- a/src/engine/PatchImpl.cpp
+++ b/src/engine/PatchImpl.cpp
@@ -166,7 +166,7 @@ PatchImpl::process(ProcessContext& context)
// Run all nodes
if (_compiled_patch && _compiled_patch->size() > 0) {
- if (_engine.process_slaves().size() > 0) {
+ if (context.slaves().size() > 0) {
process_parallel(context);
} else {
process_single(context);
@@ -186,7 +186,7 @@ PatchImpl::process(ProcessContext& context)
void
PatchImpl::process_parallel(ProcessContext& context)
{
- size_t n_slaves = _engine.process_slaves().size();
+ size_t n_slaves = context.slaves().size();
CompiledPatch* const cp = _compiled_patch;
@@ -196,11 +196,11 @@ PatchImpl::process_parallel(ProcessContext& context)
n_slaves = cp->size()-1;
if (n_slaves > 0) {
- for (size_t i=0; i < cp->size(); ++i)
+ for (size_t i = 0; i < cp->size(); ++i)
(*cp)[i].node()->reset_input_ready();
- for (size_t i=0; i < n_slaves; ++i)
- _engine.process_slaves()[i]->whip(cp, i+1, context);
+ for (size_t i = 0; i < n_slaves; ++i)
+ context.slaves()[i]->whip(cp, i+1, context);
}
@@ -211,11 +211,10 @@ PatchImpl::process_parallel(ProcessContext& context)
* waiting in the Jack thread which pisses Jack off.
*/
- size_t index = 0;
+ size_t index = 0;
size_t num_finished = 0; // Number of consecutive finished nodes hit
while (num_finished < cp->size()) {
-
CompiledNode& n = (*cp)[index];
if (n.node()->process_lock()) {
@@ -223,7 +222,7 @@ PatchImpl::process_parallel(ProcessContext& context)
n.node()->process(context);
/* Signal dependants their input is ready */
- for (size_t i=0; i < n.dependants().size(); ++i)
+ for (uint32_t i = 0; i < n.dependants().size(); ++i)
n.dependants()[i]->signal_input_ready();
++num_finished;
@@ -246,8 +245,8 @@ PatchImpl::process_parallel(ProcessContext& context)
* FIXME: This probably breaks (race) at extremely small nframes where
* ingen is the majority of the DSP load.
*/
- for (size_t i=0; i < n_slaves; ++i)
- _engine.process_slaves()[i]->finish();
+ for (uint32_t i = 0; i < n_slaves; ++i)
+ context.slaves()[i]->finish();
}
diff --git a/src/engine/ProcessContext.cpp b/src/engine/ProcessContext.cpp
new file mode 100644
index 00000000..ad405f3b
--- /dev/null
+++ b/src/engine/ProcessContext.cpp
@@ -0,0 +1,36 @@
+/* This file is part of Ingen.
+ * Copyright 2007-2011 David Robillard <http://drobilla.net>
+ *
+ * Ingen 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.
+ *
+ * Ingen 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 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 St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#include "ProcessContext.hpp"
+#include "ProcessSlave.hpp"
+
+namespace Ingen {
+
+void
+ProcessContext::activate(uint32_t parallelism, bool sched_rt)
+{
+ for (uint32_t i = 0; i < _slaves.size(); ++i) {
+ delete _slaves[i];
+ }
+ _slaves.clear();
+ _slaves.reserve(parallelism);
+ for (uint32_t i = 0; i < parallelism - 1; ++i) {
+ _slaves.push_back(new ProcessSlave(_engine, sched_rt));
+ }
+}
+
+}
diff --git a/src/engine/ProcessContext.hpp b/src/engine/ProcessContext.hpp
index e7e8a001..9e43cc3d 100644
--- a/src/engine/ProcessContext.hpp
+++ b/src/engine/ProcessContext.hpp
@@ -1,5 +1,5 @@
/* This file is part of Ingen.
- * Copyright (C) 2007-2009 David Robillard <http://drobilla.net>
+ * Copyright 2007-2011 David Robillard <http://drobilla.net>
*
* Ingen 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
@@ -18,26 +18,33 @@
#ifndef INGEN_ENGINE_PROCESSCONTEXT_HPP
#define INGEN_ENGINE_PROCESSCONTEXT_HPP
-#include "types.hpp"
-#include "EventSink.hpp"
+#include <vector>
+
#include "Context.hpp"
+#include "EventSink.hpp"
+#include "types.hpp"
namespace Ingen {
+class ProcessSlave;
/** Context of a process() call (the audio context).
- *
- * This class currently adds no functionality to Context, but the
- * separate type is useful for writing functions that must only
- * be run in the audio context (the function taking a ProcessContext
- * parameter makes this clear, and makes breaking the rules obvious).
- *
* \ingroup engine
*/
class ProcessContext : public Context
{
public:
explicit ProcessContext(Engine& engine) : Context(engine, AUDIO) {}
+
+ typedef std::vector<ProcessSlave*> Slaves;
+
+ const Slaves& slaves() const { return _slaves; }
+ Slaves& slaves() { return _slaves; }
+
+ void activate(uint32_t parallelism, bool sched_rt);
+
+private:
+ Slaves _slaves;
};
@@ -45,4 +52,3 @@ public:
} // namespace Ingen
#endif // INGEN_ENGINE_PROCESSCONTEXT_HPP
-
diff --git a/src/engine/ProcessSlave.cpp b/src/engine/ProcessSlave.cpp
index 234f8cf1..a02d1140 100644
--- a/src/engine/ProcessSlave.cpp
+++ b/src/engine/ProcessSlave.cpp
@@ -48,7 +48,7 @@ ProcessSlave::_whipped()
n.node()->wait_for_input(n.n_providers());
- n.node()->process(_process_context);
+ n.node()->process(*_context);
/* Signal dependants their input is ready */
for (size_t i=0; i < n.dependants().size(); ++i)
diff --git a/src/engine/ProcessSlave.hpp b/src/engine/ProcessSlave.hpp
index bee231d3..1d3c169d 100644
--- a/src/engine/ProcessSlave.hpp
+++ b/src/engine/ProcessSlave.hpp
@@ -19,9 +19,13 @@
#define INGEN_ENGINE_PROCESSSLAVE_HPP
#include <sstream>
-#include "raul/Slave.hpp"
+
#include "raul/Array.hpp"
#include "raul/AtomicInt.hpp"
+#include "raul/Slave.hpp"
+
+#include "Driver.hpp"
+#include "Engine.hpp"
#include "ProcessContext.hpp"
namespace Ingen {
@@ -33,11 +37,12 @@ class CompiledPatch;
class ProcessSlave : protected Raul::Slave {
public:
ProcessSlave(Engine& engine, bool realtime)
- : _id(_next_id++)
+ : _engine(engine)
+ , _id(_next_id++)
, _index(0)
, _state(STATE_FINISHED)
, _compiled_patch(NULL)
- , _process_context(engine)
+ , _context(NULL)
{
std::stringstream ss;
ss << "Process Slave ";
@@ -54,12 +59,15 @@ public:
stop();
}
- inline void whip(CompiledPatch* compiled_patch, uint32_t start_index, ProcessContext& context) {
+ inline void whip(CompiledPatch* compiled_patch,
+ uint32_t start_index,
+ ProcessContext& context)
+ {
assert(_state == STATE_FINISHED);
- _index = start_index;
- _state = STATE_RUNNING;
+ _index = start_index;
+ _state = STATE_RUNNING;
_compiled_patch = compiled_patch;
- _process_context.locate(context);
+ _context = &context;
Raul::Slave::whip();
}
@@ -70,28 +78,27 @@ public:
}
inline uint32_t id() const { return _id; }
- inline const ProcessContext& context() const { return _process_context; }
- inline ProcessContext& context() { return _process_context; }
+ inline const ProcessContext& context() const { return _engine.driver()->context(); }
+ inline ProcessContext& context() { return _engine.driver()->context(); }
private:
-
void _whipped();
static uint32_t _next_id;
- static const int STATE_RUNNING = 0;
+ static const int STATE_RUNNING = 0;
static const int STATE_FINISH_SIGNALLED = 1;
- static const int STATE_FINISHED = 2;
-
- uint32_t _id;
- uint32_t _index;
- Raul::AtomicInt _state;
- CompiledPatch* _compiled_patch;
- ProcessContext _process_context;
+ static const int STATE_FINISHED = 2;
+
+ Engine& _engine;
+ uint32_t _id;
+ uint32_t _index;
+ Raul::AtomicInt _state;
+ CompiledPatch* _compiled_patch;
+ ProcessContext* _context;
};
} // namespace Ingen
#endif // INGEN_ENGINE_PROCESSSLAVE_HPP
-
diff --git a/src/engine/QueuedEngineInterface.cpp b/src/engine/QueuedEngineInterface.cpp
index c1051c0a..eea27126 100644
--- a/src/engine/QueuedEngineInterface.cpp
+++ b/src/engine/QueuedEngineInterface.cpp
@@ -231,11 +231,7 @@ QueuedEngineInterface::set_property(const URI& uri,
void
QueuedEngineInterface::ping()
{
- if (_engine.activated()) {
- push_queued(new Events::Ping(_engine, _request, now()));
- } else if (_request) {
- _request->respond_ok();
- }
+ push_queued(new Events::Ping(_engine, _request, now()));
}
diff --git a/src/engine/wscript b/src/engine/wscript
index 61be8c01..1a801b92 100644
--- a/src/engine/wscript
+++ b/src/engine/wscript
@@ -31,6 +31,7 @@ def build(bld):
PluginImpl.cpp
PortImpl.cpp
PostProcessor.cpp
+ ProcessContext.cpp
ProcessSlave.cpp
QueuedEngineInterface.cpp
QueuedEvent.cpp