summaryrefslogtreecommitdiffstats
path: root/src/server
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2017-03-19 10:36:11 +0100
committerDavid Robillard <d@drobilla.net>2017-03-20 02:58:56 +0100
commitefc0fe0a973db706d9409b345ad6fae585f4388c (patch)
tree6348b6bd17e358ed328b5c443966436fb36521e5 /src/server
parentf46a3ec40a691a6892ad5536ca47de175a9c05b7 (diff)
downloadingen-efc0fe0a973db706d9409b345ad6fae585f4388c.tar.gz
ingen-efc0fe0a973db706d9409b345ad6fae585f4388c.tar.bz2
ingen-efc0fe0a973db706d9409b345ad6fae585f4388c.zip
Improve arc list efficiency
Diffstat (limited to 'src/server')
-rw-r--r--src/server/ArcImpl.cpp10
-rw-r--r--src/server/ArcImpl.hpp4
-rw-r--r--src/server/DirectDriver.hpp6
-rw-r--r--src/server/EnginePort.hpp4
-rw-r--r--src/server/GraphImpl.hpp3
-rw-r--r--src/server/InputPort.cpp24
-rw-r--r--src/server/InputPort.hpp9
-rw-r--r--src/server/JackDriver.hpp4
-rw-r--r--src/server/PortAudioDriver.hpp4
-rw-r--r--src/server/events/Connect.cpp2
-rw-r--r--src/server/events/Disconnect.cpp9
11 files changed, 39 insertions, 40 deletions
diff --git a/src/server/ArcImpl.cpp b/src/server/ArcImpl.cpp
index 1dd92d48..406d2010 100644
--- a/src/server/ArcImpl.cpp
+++ b/src/server/ArcImpl.cpp
@@ -42,6 +42,16 @@ ArcImpl::ArcImpl(PortImpl* tail, PortImpl* head)
assert(tail->path() != head->path());
}
+ArcImpl::~ArcImpl()
+{
+ if (is_linked()) {
+ InputPort* iport = dynamic_cast<InputPort*>(_head);
+ if (iport) {
+ iport->remove_arc(*this);
+ }
+ }
+}
+
const Raul::Path&
ArcImpl::tail_path() const
{
diff --git a/src/server/ArcImpl.hpp b/src/server/ArcImpl.hpp
index c796384a..40a6d179 100644
--- a/src/server/ArcImpl.hpp
+++ b/src/server/ArcImpl.hpp
@@ -49,11 +49,11 @@ class InputPort;
class ArcImpl
: private Raul::Noncopyable
, public Arc
- , public boost::intrusive::slist_base_hook<
- boost::intrusive::link_mode<boost::intrusive::auto_unlink> >
+ , public boost::intrusive::slist_base_hook<>
{
public:
ArcImpl(PortImpl* tail, PortImpl* head);
+ ~ArcImpl();
inline PortImpl* tail() const { return _tail; }
inline PortImpl* head() const { return _head; }
diff --git a/src/server/DirectDriver.hpp b/src/server/DirectDriver.hpp
index 5bc7998f..376c6ad8 100644
--- a/src/server/DirectDriver.hpp
+++ b/src/server/DirectDriver.hpp
@@ -17,7 +17,7 @@
#ifndef INGEN_ENGINE_DIRECT_DRIVER_HPP
#define INGEN_ENGINE_DIRECT_DRIVER_HPP
-#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
#include "Driver.hpp"
@@ -87,7 +87,9 @@ public:
virtual int real_time_priority() { return 60; }
private:
- typedef boost::intrusive::list<EnginePort> Ports;
+ typedef boost::intrusive::slist<EnginePort,
+ boost::intrusive::cache_last<true>
+ > Ports;
Ports _ports;
SampleCount _sample_rate;
diff --git a/src/server/EnginePort.hpp b/src/server/EnginePort.hpp
index ee00d4ed..c657f75a 100644
--- a/src/server/EnginePort.hpp
+++ b/src/server/EnginePort.hpp
@@ -20,7 +20,7 @@
#include "raul/Deletable.hpp"
#include "raul/Noncopyable.hpp"
-#include <boost/intrusive/list.hpp>
+#include <boost/intrusive/slist.hpp>
#include "DuplexPort.hpp"
@@ -33,7 +33,7 @@ namespace Server {
*/
class EnginePort : public Raul::Noncopyable
, public Raul::Deletable
- , public boost::intrusive::list_base_hook<>
+ , public boost::intrusive::slist_base_hook<>
{
public:
explicit EnginePort(DuplexPort* port)
diff --git a/src/server/GraphImpl.hpp b/src/server/GraphImpl.hpp
index 62af07f6..6064624a 100644
--- a/src/server/GraphImpl.hpp
+++ b/src/server/GraphImpl.hpp
@@ -159,8 +159,7 @@ public:
/** Remove an arc from this graph.
* Pre-processing thread only.
*/
- SPtr<ArcImpl> remove_arc(const PortImpl* tail,
- const PortImpl* head);
+ SPtr<ArcImpl> remove_arc(const PortImpl* tail, const PortImpl* head);
bool has_arc(const PortImpl* tail, const PortImpl* head) const;
diff --git a/src/server/InputPort.cpp b/src/server/InputPort.cpp
index b0e2ee61..63a752b1 100644
--- a/src/server/InputPort.cpp
+++ b/src/server/InputPort.cpp
@@ -125,29 +125,15 @@ InputPort::setup_buffers(RunContext& ctx, BufferFactory& bufs, uint32_t poly)
}
void
-InputPort::add_arc(RunContext& context, ArcImpl* c)
+InputPort::add_arc(RunContext& context, ArcImpl& c)
{
- _arcs.push_front(*c);
+ _arcs.push_front(c);
}
-ArcImpl*
-InputPort::remove_arc(RunContext& context, const PortImpl* tail)
+void
+InputPort::remove_arc(ArcImpl& arc)
{
- ArcImpl* arc = NULL;
- for (Arcs::iterator i = _arcs.begin(); i != _arcs.end(); ++i) {
- if (i->tail() == tail) {
- arc = &*i;
- _arcs.erase(i);
- break;
- }
- }
-
- if (!arc) {
- context.engine().log().rt_error("Attempt to remove non-existent arc\n");
- return NULL;
- }
-
- return arc;
+ _arcs.erase(_arcs.iterator_to(arc));
}
uint32_t
diff --git a/src/server/InputPort.hpp b/src/server/InputPort.hpp
index 73911789..323da3e5 100644
--- a/src/server/InputPort.hpp
+++ b/src/server/InputPort.hpp
@@ -58,10 +58,8 @@ public:
const Atom& value,
size_t buffer_size = 0);
- virtual ~InputPort() {}
-
typedef boost::intrusive::slist<ArcImpl,
- boost::intrusive::constant_time_size<false>
+ boost::intrusive::constant_time_size<true>
> Arcs;
/** Return the maximum polyphony of an output connected to this input. */
@@ -76,14 +74,13 @@ public:
*
* setup_buffers() must be called later for the change to take effect.
*/
- void add_arc(RunContext& context, ArcImpl* c);
+ void add_arc(RunContext& context, ArcImpl& c);
/** Remove an arc. Realtime safe.
*
* setup_buffers() must be called later for the change to take effect.
*/
- ArcImpl* remove_arc(RunContext& context,
- const PortImpl* tail);
+ void remove_arc(ArcImpl& arc);
/** Like `get_buffers`, but for the pre-process thread.
*
diff --git a/src/server/JackDriver.hpp b/src/server/JackDriver.hpp
index 49d3e4c2..ce9af82e 100644
--- a/src/server/JackDriver.hpp
+++ b/src/server/JackDriver.hpp
@@ -138,7 +138,9 @@ private:
#endif
protected:
- typedef boost::intrusive::list<EnginePort> Ports;
+ typedef boost::intrusive::slist<EnginePort,
+ boost::intrusive::cache_last<true>
+ > Ports;
Engine& _engine;
Ports _ports;
diff --git a/src/server/PortAudioDriver.hpp b/src/server/PortAudioDriver.hpp
index 5c5c2445..24d10925 100644
--- a/src/server/PortAudioDriver.hpp
+++ b/src/server/PortAudioDriver.hpp
@@ -104,7 +104,9 @@ private:
void* outputs);
protected:
- typedef boost::intrusive::list<EnginePort> Ports;
+ typedef boost::intrusive::slist<EnginePort,
+ boost::intrusive::cache_last<true>
+ > Ports;
Engine& _engine;
Ports _ports;
diff --git a/src/server/events/Connect.cpp b/src/server/events/Connect.cpp
index e02b19a8..c75e56a1 100644
--- a/src/server/events/Connect.cpp
+++ b/src/server/events/Connect.cpp
@@ -153,7 +153,7 @@ void
Connect::execute(RunContext& context)
{
if (_status == Status::SUCCESS) {
- _head->add_arc(context, _arc.get());
+ _head->add_arc(context, *_arc.get());
if (!_head->is_driver_port()) {
_head->set_voices(context, std::move(_voices));
}
diff --git a/src/server/events/Disconnect.cpp b/src/server/events/Disconnect.cpp
index 9320163a..176f0999 100644
--- a/src/server/events/Disconnect.cpp
+++ b/src/server/events/Disconnect.cpp
@@ -170,11 +170,12 @@ Disconnect::pre_process(PreProcessContext& ctx)
bool
Disconnect::Impl::execute(RunContext& context, bool set_head_buffers)
{
- ArcImpl* const port_arc = _head->remove_arc(context, _tail);
-
- if (!port_arc) {
+ if (!_arc) {
return false;
- } else if (_head->is_driver_port()) {
+ }
+
+ _head->remove_arc(*_arc.get());
+ if (_head->is_driver_port()) {
return true;
}