From 9fe19152570b6388fc518bda6ccd422d14cff37a Mon Sep 17 00:00:00 2001 From: David Robillard Date: Fri, 5 Oct 2007 19:41:24 +0000 Subject: Fix OSC receiving thread chewing CPU (xrun problem on single core systems). git-svn-id: http://svn.drobilla.net/lad/ingen@827 a436a847-0d15-0410-975c-d299462d15a1 --- src/libs/engine/OSCEngineReceiver.cpp | 23 ++++++++++++----------- src/libs/engine/OSCEngineReceiver.hpp | 11 ++++++++++- src/libs/engine/QueuedEventSource.cpp | 4 +++- src/libs/engine/QueuedEventSource.hpp | 2 +- 4 files changed, 26 insertions(+), 14 deletions(-) (limited to 'src/libs') diff --git a/src/libs/engine/OSCEngineReceiver.cpp b/src/libs/engine/OSCEngineReceiver.cpp index 3fb9e189..1c59a437 100644 --- a/src/libs/engine/OSCEngineReceiver.cpp +++ b/src/libs/engine/OSCEngineReceiver.cpp @@ -48,6 +48,8 @@ OSCEngineReceiver::OSCEngineReceiver(Engine& engine, size_t queue_size, uint16_t : QueuedEngineInterface(engine, queue_size, queue_size) // FIXME , _server(NULL) { + _receive_thread = new ReceiveThread(*this); + char port_str[6]; snprintf(port_str, 6, "%u", port); @@ -131,6 +133,8 @@ OSCEngineReceiver::~OSCEngineReceiver() { deactivate(); stop(); + _receive_thread->stop(); + delete _receive_thread; if (_server != NULL) { lo_server_free(_server); @@ -143,7 +147,8 @@ void OSCEngineReceiver::activate() { QueuedEventSource::activate(); - set_scheduling(SCHED_FIFO, 10); + set_scheduling(SCHED_FIFO, 5); // Jack default appears to be 10 + _receive_thread->start(); } @@ -159,30 +164,26 @@ OSCEngineReceiver::deactivate() * to wait on OSC messages and prepare them right away in the same thread. */ void -OSCEngineReceiver::_run() +OSCEngineReceiver::ReceiveThread::_run() { /* get a timestamp here and stamp all the events with the same time so * they all get executed in the same cycle */ while (true) { - assert(_server); + assert(_receiver._server); /*if ( ! _server) { cout << "[OSCEngineReceiver] Server is NULL, exiting" << endl; break; }*/ - assert( ! unprepared_events()); - // Wait on a message and enqueue it - lo_server_recv(_server); + lo_server_recv(_receiver._server); // Enqueue every other message that is here "now" // (would this provide truly atomic bundles?) - while (lo_server_recv_noblock(_server, 0) > 0) ; - - // Process them all - while (unprepared_events()) - _whipped(); // Whip our slave self + while (lo_server_recv_noblock(_receiver._server, 0) > 0) + if (_receiver.unprepared_events()) + _receiver.whip(); // No more unprepared events } diff --git a/src/libs/engine/OSCEngineReceiver.hpp b/src/libs/engine/OSCEngineReceiver.hpp index d46bc7c3..c4f86b8c 100644 --- a/src/libs/engine/OSCEngineReceiver.hpp +++ b/src/libs/engine/OSCEngineReceiver.hpp @@ -69,7 +69,16 @@ public: void deactivate(); private: - virtual void _run(); + struct ReceiveThread : public Raul::Thread { + ReceiveThread(OSCEngineReceiver& receiver) : _receiver(receiver) {} + virtual void _run(); + private: + OSCEngineReceiver& _receiver; + }; + + friend class ReceiveThread; + + ReceiveThread* _receive_thread; static void error_cb(int num, const char* msg, const char* path); static int set_response_address_cb(LO_HANDLER_ARGS, void* myself); diff --git a/src/libs/engine/QueuedEventSource.cpp b/src/libs/engine/QueuedEventSource.cpp index 5dcaf255..4b63b6c4 100644 --- a/src/libs/engine/QueuedEventSource.cpp +++ b/src/libs/engine/QueuedEventSource.cpp @@ -151,7 +151,9 @@ void QueuedEventSource::_whipped() { QueuedEvent* const ev = _events[_prepared_back]; - assert(ev); + //assert(ev); + if (!ev) + return; assert(!ev->is_prepared()); ev->pre_process(); diff --git a/src/libs/engine/QueuedEventSource.hpp b/src/libs/engine/QueuedEventSource.hpp index 4c212ee1..4c23f226 100644 --- a/src/libs/engine/QueuedEventSource.hpp +++ b/src/libs/engine/QueuedEventSource.hpp @@ -63,7 +63,7 @@ protected: Event* pop_earliest_queued_before(const SampleCount time); inline Event* pop_earliest_stamped_before(const SampleCount time); - bool unprepared_events() { return (_prepared_back != _back); } + inline bool unprepared_events() { return (_prepared_back != _back); } virtual void _whipped(); ///< Prepare 1 event -- cgit v1.2.1