mirror of
https://github.com/Ardour/ardour.git
synced 2026-01-10 07:26:32 +01:00
use JACK thread creation functions to create process-graph threads; provide GUI control over number of threads-relative-to-number-of-CPUS
git-svn-id: svn://localhost/ardour2/branches/3.0@7296 d708f5d6-7413-0410-9779-e7cbd77b26cf
This commit is contained in:
parent
fe229a830e
commit
0f5bdd666f
11 changed files with 183 additions and 34 deletions
|
|
@ -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());
|
||||
|
|
|
|||
|
|
@ -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> (
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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];
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
49
libs/pbd/cpus.cc
Normal file
49
libs/pbd/cpus.cc
Normal file
|
|
@ -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
|
||||
}
|
||||
28
libs/pbd/pbd/cpus.h
Normal file
28
libs/pbd/pbd/cpus.h
Normal file
|
|
@ -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__ */
|
||||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue