diff options
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/audioengine.h | 13 | ||||
-rw-r--r-- | libs/ardour/ardour/graph.h | 2 | ||||
-rw-r--r-- | libs/ardour/ardour/rc_configuration_vars.h | 1 | ||||
-rw-r--r-- | libs/ardour/audioengine.cc | 30 | ||||
-rw-r--r-- | libs/ardour/delivery.cc | 2 | ||||
-rw-r--r-- | libs/ardour/graph.cc | 61 |
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. |