summaryrefslogtreecommitdiff
path: root/libs/ardour
diff options
context:
space:
mode:
Diffstat (limited to 'libs/ardour')
-rw-r--r--libs/ardour/ardour/audioengine.h13
-rw-r--r--libs/ardour/ardour/graph.h2
-rw-r--r--libs/ardour/ardour/rc_configuration_vars.h1
-rw-r--r--libs/ardour/audioengine.cc30
-rw-r--r--libs/ardour/delivery.cc2
-rw-r--r--libs/ardour/graph.cc61
6 files changed, 78 insertions, 31 deletions
diff --git a/libs/ardour/ardour/audioengine.h b/libs/ardour/ardour/audioengine.h
index 5e2657c56c..9a0104b8fe 100644
--- a/libs/ardour/ardour/audioengine.h
+++ b/libs/ardour/ardour/audioengine.h
@@ -245,6 +245,8 @@ _ the regular process() call to session->process() is not made.
static AudioEngine* instance() { return _instance; }
void died ();
+ pthread_t create_process_thread (boost::function<void()>, size_t stacksize);
+
private:
static AudioEngine* _instance;
@@ -316,6 +318,17 @@ _ the regular process() call to session->process() is not made.
static gint m_meter_exit;
ProcessThread* _main_thread;
+
+ struct ThreadData {
+ AudioEngine* engine;
+ boost::function<void()> f;
+ size_t stacksize;
+
+ ThreadData (AudioEngine* ae, boost::function<void()> fp, size_t stacksz)
+ : engine (ae) , f (fp) , stacksize (stacksz) {}
+ };
+
+ static void* _start_process_thread (void*);
};
} // namespace ARDOUR
diff --git a/libs/ardour/ardour/graph.h b/libs/ardour/ardour/graph.h
index 6226ed5602..f38ef12721 100644
--- a/libs/ardour/ardour/graph.h
+++ b/libs/ardour/ardour/graph.h
@@ -85,7 +85,7 @@ class Graph : public SessionHandleRef
virtual void session_going_away ();
private:
- std::list<Glib::Thread *> _thread_list;
+ std::list<pthread_t> _thread_list;
volatile bool _quit_threads;
node_list_t _nodes_rt[2];
diff --git a/libs/ardour/ardour/rc_configuration_vars.h b/libs/ardour/ardour/rc_configuration_vars.h
index 92397c149f..e98f396b95 100644
--- a/libs/ardour/ardour/rc_configuration_vars.h
+++ b/libs/ardour/ardour/rc_configuration_vars.h
@@ -153,6 +153,7 @@ CONFIG_VARIABLE (bool, show_waveforms_while_recording, "show-waveforms-while-rec
CONFIG_VARIABLE (WaveformScale, waveform_scale, "waveform-scale", Linear)
CONFIG_VARIABLE (WaveformShape, waveform_shape, "waveform-shape", Traditional)
CONFIG_VARIABLE (bool, allow_special_bus_removal, "allow-special-bus-removal", false)
+CONFIG_VARIABLE (int32_t, processor_usage, "processor-usage", -1)
/* denormal management */
diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc
index 903fbb227d..2282a20809 100644
--- a/libs/ardour/audioengine.cc
+++ b/libs/ardour/audioengine.cc
@@ -25,6 +25,9 @@
#include <sstream>
#include <glibmm/timer.h>
+#include <jack/jack.h>
+#include <jack/thread.h>
+
#include "pbd/pthread_utils.h"
#include "pbd/stacktrace.h"
#include "pbd/unknown_type.h"
@@ -1480,3 +1483,30 @@ AudioEngine::is_realtime () const
GET_PRIVATE_JACK_POINTER_RET (_jack,false);
return jack_is_realtime (_priv_jack);
}
+
+pthread_t
+AudioEngine::create_process_thread (boost::function<void()> f, size_t stacksize)
+{
+ GET_PRIVATE_JACK_POINTER_RET (_jack, 0);
+ pthread_t thread;
+ ThreadData* td = new ThreadData (this, f, stacksize);
+
+ if (jack_client_create_thread (_priv_jack, &thread, jack_client_real_time_priority (_priv_jack),
+ jack_is_realtime (_priv_jack), _start_process_thread, td)) {
+ return -1;
+ }
+
+ return thread;
+}
+
+void*
+AudioEngine::_start_process_thread (void* arg)
+{
+ ThreadData* td = reinterpret_cast<ThreadData*> (arg);
+ boost::function<void()> f = td->f;
+ delete td;
+
+ f ();
+
+ return 0;
+}
diff --git a/libs/ardour/delivery.cc b/libs/ardour/delivery.cc
index cb8dc539a2..7bacb1c058 100644
--- a/libs/ardour/delivery.cc
+++ b/libs/ardour/delivery.cc
@@ -481,7 +481,7 @@ Delivery::target_gain ()
return 0.0;
}
- MuteMaster::MutePoint mp;
+ MuteMaster::MutePoint mp = MuteMaster::Main; // stupid gcc uninit warning
switch (_role) {
case Main:
diff --git a/libs/ardour/graph.cc b/libs/ardour/graph.cc
index ae5758107a..54e619aef8 100644
--- a/libs/ardour/graph.cc
+++ b/libs/ardour/graph.cc
@@ -18,17 +18,11 @@
*/
-#ifdef __linux__
-#include <unistd.h>
-#elif defined(__APPLE__) || defined(__FreeBSD__)
-#include <sys/types.h>
-#include <sys/sysctl.h>
-#endif
-
#include <stdio.h>
#include <cmath>
#include "pbd/compose.h"
+#include "pbd/cpus.h"
#include "ardour/debug.h"
#include "ardour/graph.h"
@@ -45,22 +39,6 @@
using namespace ARDOUR;
using namespace PBD;
-static unsigned int
-hardware_concurrency()
-{
-#if defined(PTW32_VERSION) || defined(__hpux)
- return pthread_num_processors_np();
-#elif defined(__APPLE__) || defined(__FreeBSD__)
- int count;
- size_t size=sizeof(count);
- return sysctlbyname("hw.ncpu",&count,&size,NULL,0)?0:count;
-#elif defined(HAVE_UNISTD) && defined(_SC_NPROCESSORS_ONLN)
- int const count=sysconf(_SC_NPROCESSORS_ONLN);
- return (count>0)?count:0;
-#else
- return 0;
-#endif
-}
Graph::Graph (Session & session)
: SessionHandleRef (session)
@@ -81,10 +59,34 @@ Graph::Graph (Session & session)
_graph_empty = true;
int num_cpu = hardware_concurrency();
- info << string_compose (_("Using %1 CPUs via %1 threads\n"), num_cpu) << endmsg;
- _thread_list.push_back( Glib::Thread::create( sigc::mem_fun( *this, &Graph::main_thread), 100000, true, true, Glib::THREAD_PRIORITY_NORMAL) );
- for (int i=1; i<num_cpu; i++)
- _thread_list.push_back( Glib::Thread::create( sigc::mem_fun( *this, &Graph::helper_thread), 100000, true, true, Glib::THREAD_PRIORITY_NORMAL) );
+ int num_threads = num_cpu;
+ int pu = Config->get_processor_usage ();
+
+ if (pu < 0) {
+ /* use "pu" less cores for DSP than appear to be available
+ */
+
+ if (pu < num_threads) {
+ num_threads += pu; // pu is negative
+ } else {
+ num_threads = 1;
+ }
+ } else {
+ /* use "pu" cores, if available
+ */
+
+ if (pu <= num_threads) {
+ num_threads = pu;
+ }
+ }
+
+ info << string_compose (_("Using %2 threads on %1 CPUs"), num_cpu, num_threads) << endmsg;
+
+ _thread_list.push_back (AudioEngine::instance()->create_process_thread (boost::bind (&Graph::main_thread, this), 100000));
+
+ for (int i = 1; i < num_threads; ++i) {
+ _thread_list.push_back (AudioEngine::instance()->create_process_thread (boost::bind (&Graph::helper_thread, this), 100000));
+ }
}
void
@@ -98,8 +100,9 @@ Graph::session_going_away()
sem_post( &_callback_start_sem);
- for (std::list<Glib::Thread *>::iterator i=_thread_list.begin(); i!=_thread_list.end(); i++) {
- (*i)->join();
+ for (std::list<pthread_t>::iterator i = _thread_list.begin(); i != _thread_list.end(); i++) {
+ void* status;
+ pthread_join (*i, &status);
}
// now drop all references on the nodes.