summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gtk2_ardour/midi_region_view.cc6
-rw-r--r--gtk2_ardour/rc_option_editor.cc23
-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
-rw-r--r--libs/pbd/cpus.cc49
-rw-r--r--libs/pbd/pbd/cpus.h28
-rw-r--r--libs/pbd/wscript2
11 files changed, 183 insertions, 34 deletions
diff --git a/gtk2_ardour/midi_region_view.cc b/gtk2_ardour/midi_region_view.cc
index 486e09900f..92fe545c91 100644
--- a/gtk2_ardour/midi_region_view.cc
+++ b/gtk2_ardour/midi_region_view.cc
@@ -2256,8 +2256,8 @@ MidiRegionView::trim_note (CanvasNoteEvent* event, Evoral::MusicalTime front_del
{
bool change_start = false;
bool change_length = false;
- Evoral::MusicalTime new_start;
- Evoral::MusicalTime new_length;
+ Evoral::MusicalTime new_start = 0;
+ Evoral::MusicalTime new_length = 0;
/* NOTE: the semantics of the two delta arguments are slightly subtle:
@@ -2685,7 +2685,7 @@ MidiRegionView::paste (nframes64_t pos, float times, const MidiCutBuffer& mcb)
Evoral::MusicalTime beat_delta;
Evoral::MusicalTime paste_pos_beats;
Evoral::MusicalTime duration;
- Evoral::MusicalTime end_point;
+ Evoral::MusicalTime end_point = 0;
duration = (*mcb.notes().rbegin())->end_time() - (*mcb.notes().begin())->time();
paste_pos_beats = frames_to_beats (pos - _region->position());
diff --git a/gtk2_ardour/rc_option_editor.cc b/gtk2_ardour/rc_option_editor.cc
index 83b3e498cd..14fca7a417 100644
--- a/gtk2_ardour/rc_option_editor.cc
+++ b/gtk2_ardour/rc_option_editor.cc
@@ -5,6 +5,7 @@
#include <gtkmm2ext/slider_controller.h>
#include "pbd/fpu.h"
+#include "pbd/cpus.h"
#include "midi++/manager.h"
#include "midi++/factory.h"
@@ -930,6 +931,28 @@ RCOptionEditor::RCOptionEditor ()
{
/* MISC */
+ uint32_t hwcpus = hardware_concurrency ();
+
+ if (hwcpus > 1) {
+ add_option (_("Misc"), new OptionEditorHeading (_("DSP CPU Utilization")));
+
+ ComboOption<uint32_t>* procs = new ComboOption<uint32_t> (
+ "processor-usage",
+ _("Signal processing uses: "),
+ sigc::mem_fun (*_rc_config, &RCConfiguration::get_processor_usage),
+ sigc::mem_fun (*_rc_config, &RCConfiguration::set_processor_usage)
+ );
+
+ procs->add (-1, _("All but one"));
+ procs->add (0, _("All available processors"));
+
+ for (uint32_t i = 2; i < hwcpus; ++i) {
+ procs->add (1, string_compose (_("%1 processors"), i));
+ }
+
+ add_option (_("Misc"), procs);
+ }
+
add_option (_("Misc"), new OptionEditorHeading (_("Metering")));
ComboOption<float>* mht = new ComboOption<float> (
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.
diff --git a/libs/pbd/cpus.cc b/libs/pbd/cpus.cc
new file mode 100644
index 0000000000..ba4ba32fe4
--- /dev/null
+++ b/libs/pbd/cpus.cc
@@ -0,0 +1,49 @@
+/*
+ Copyright (C) 2010 Paul Davis
+ Author: Torben Hohn
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifdef WAF_BUILD
+#include "libpbd-config.h"
+#endif
+
+#ifdef __linux__
+#include <unistd.h>
+#elif defined(__APPLE__) || defined(__FreeBSD__)
+#include <sys/types.h>
+#include <sys/sysctl.h>
+#endif
+
+#include "pbd/cpus.h"
+
+uint32_t
+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
+}
diff --git a/libs/pbd/pbd/cpus.h b/libs/pbd/pbd/cpus.h
new file mode 100644
index 0000000000..1488f30068
--- /dev/null
+++ b/libs/pbd/pbd/cpus.h
@@ -0,0 +1,28 @@
+/*
+ Copyright (C) 2010 Paul Davis
+ Author: Torben Hohn
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+*/
+
+#ifndef __libpbd_cpus_h__
+#define __libpbd_cpus_h__
+
+#include <stdint.h>
+
+extern uint32_t hardware_concurrency ();
+
+#endif /* __libpbd_cpus_h__ */
diff --git a/libs/pbd/wscript b/libs/pbd/wscript
index 7052ad98ca..a558a04da2 100644
--- a/libs/pbd/wscript
+++ b/libs/pbd/wscript
@@ -40,6 +40,7 @@ def configure(conf):
conf.check(function_name='getmntent', header_name='mntent.h', define_name='HAVE_GETMNTENT')
conf.check(header_name='execinfo.h', define_name='HAVE_EXECINFO')
+ conf.check(header_name='unistd.h', define_name='HAVE_UNISTD')
conf.write_config_header('libpbd-config.h')
@@ -59,6 +60,7 @@ def build(bld):
controllable.cc
controllable_descriptor.cc
crossthread.cc
+ cpus.cc
debug.cc
enumwriter.cc
event_loop.cc