summaryrefslogtreecommitdiffstats
path: root/src/server/EventSource.cpp
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2011-05-18 17:45:39 +0000
committerDavid Robillard <d@drobilla.net>2011-05-18 17:45:39 +0000
commit177f2b48b6516ba4dee70a709ce28105f1092de2 (patch)
tree84f6d9b9a026c6d35940e99f2981bd5be537548a /src/server/EventSource.cpp
parent27e3187270807c5e126a2e4bf66211de0f784a28 (diff)
downloadingen-177f2b48b6516ba4dee70a709ce28105f1092de2.tar.gz
ingen-177f2b48b6516ba4dee70a709ce28105f1092de2.tar.bz2
ingen-177f2b48b6516ba4dee70a709ce28105f1092de2.zip
Use an intrusive linked list for event queue rather than Raul::List.
This avoids the need to allocate list nodes, improving performance (event throughput), and making EventSource::push_queued realtime safe. Remove unused queue_size parameter from EventSource and friends. git-svn-id: http://svn.drobilla.net/lad/trunk/ingen@3282 a436a847-0d15-0410-975c-d299462d15a1
Diffstat (limited to 'src/server/EventSource.cpp')
-rw-r--r--src/server/EventSource.cpp69
1 files changed, 36 insertions, 33 deletions
diff --git a/src/server/EventSource.cpp b/src/server/EventSource.cpp
index 273a4693..cdecfd4a 100644
--- a/src/server/EventSource.cpp
+++ b/src/server/EventSource.cpp
@@ -15,19 +15,18 @@
* 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <sys/mman.h>
#include "EventSource.hpp"
-#include "QueuedEvent.hpp"
#include "PostProcessor.hpp"
-#include "ThreadManager.hpp"
#include "ProcessContext.hpp"
+#include "QueuedEvent.hpp"
+#include "ThreadManager.hpp"
using namespace std;
namespace Ingen {
namespace Server {
-EventSource::EventSource(size_t queue_size)
+EventSource::EventSource()
: _blocking_semaphore(0)
{
Thread::set_context(THREAD_PRE_PROCESS);
@@ -45,10 +44,22 @@ void
EventSource::push_queued(QueuedEvent* const ev)
{
assert(!ev->is_prepared());
- Raul::List<Event*>::Node* node = new Raul::List<Event*>::Node(ev);
- _events.push_back(node);
- if (_prepared_back.get() == NULL)
- _prepared_back = node;
+ assert(!ev->next());
+
+ QueuedEvent* const head = _head.get();
+ QueuedEvent* const tail = _tail.get();
+
+ if (!head) {
+ _head = ev;
+ _tail = ev;
+ } else {
+ _tail = ev;
+ tail->next(ev);
+ }
+
+ if (!_prepared_back.get()) {
+ _prepared_back = ev;
+ }
whip();
}
@@ -62,39 +73,35 @@ EventSource::process(PostProcessor& dest, ProcessContext& context, bool limit)
{
ThreadManager::assert_thread(THREAD_PROCESS);
- if (_events.empty())
+ if (!_head.get())
return;
/* Limit the maximum number of queued events to process per cycle. This
- * makes the process callback (more) realtime-safe by preventing being
- * choked by events coming in faster than they can be processed.
- * FIXME: test this and figure out a good value */
+ makes the process callback (more) realtime-safe by preventing being
+ choked by events coming in faster than they can be processed.
+ FIXME: test this and figure out a good value
+ */
const size_t MAX_QUEUED_EVENTS = context.nframes() / 32;
size_t num_events_processed = 0;
- Raul::List<Event*>::Node* head = _events.head();
- Raul::List<Event*>::Node* tail = head;
-
- if (!head)
- return;
-
- QueuedEvent* ev = (QueuedEvent*)head->elem();
+ QueuedEvent* ev = _head.get();
+ QueuedEvent* last = ev;
while (ev && ev->is_prepared() && ev->time() < context.end()) {
ev->execute(context);
- tail = head;
- head = head->next();
+ last = ev;
+ ev = (QueuedEvent*)ev->next();
++num_events_processed;
- if (limit && num_events_processed > MAX_QUEUED_EVENTS)
+ if (limit && (num_events_processed > MAX_QUEUED_EVENTS))
break;
- ev = (head ? (QueuedEvent*)head->elem() : NULL);
}
if (num_events_processed > 0) {
- Raul::List<Event*> front;
- _events.chop_front(front, num_events_processed, tail);
- dest.append(&front);
+ dest.append(_head.get(), last);
+ _head = (QueuedEvent*)last->next();
+ if (!last->next())
+ _tail = NULL;
}
}
@@ -102,19 +109,15 @@ EventSource::process(PostProcessor& dest, ProcessContext& context, bool limit)
void
EventSource::_whipped()
{
- Raul::List<Event*>::Node* pb = _prepared_back.get();
- if (!pb)
+ QueuedEvent* ev = _prepared_back.get();
+ if (!ev)
return;
- QueuedEvent* const ev = (QueuedEvent*)pb->elem();
- assert(ev);
-
assert(!ev->is_prepared());
ev->pre_process();
assert(ev->is_prepared());
- assert(_prepared_back.get() == pb);
- _prepared_back = pb->next();
+ _prepared_back = (QueuedEvent*)ev->next();
// If event was blocking, wait for event to being run through the
// process thread before preparing the next event