Clean up and hopefully fix handling of logarithmic plugin parameters (fixes #3769).
[ardour.git] / libs / ardour / graph.cc
1 /*
2   Copyright (C) 2010 Paul Davis
3   Author: Torben Hohn
4
5   This program is free software; you can redistribute it and/or modify
6   it under the terms of the GNU General Public License as published by
7   the Free Software Foundation; either version 2 of the License, or
8   (at your option) any later version.
9
10   This program is distributed in the hope that it will be useful,
11   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   GNU General Public License for more details.
14
15   You should have received a copy of the GNU General Public License
16   along with this program; if not, write to the Free Software
17   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18
19 */
20 #include <stdio.h>
21 #include <cmath>
22
23 #include "pbd/compose.h"
24 #include "pbd/debug_rt_alloc.h"
25
26 #include "ardour/debug.h"
27 #include "ardour/graph.h"
28 #include "ardour/types.h"
29 #include "ardour/session.h"
30 #include "ardour/route.h"
31 #include "ardour/process_thread.h"
32 #include "ardour/audioengine.h"
33
34 #include <jack/thread.h>
35
36 #include "i18n.h"
37
38 using namespace ARDOUR;
39 using namespace PBD;
40 using namespace std;
41
42 #ifdef DEBUG_RT_ALLOC
43 static Graph* graph = 0;
44 extern "C" {
45
46 int alloc_allowed ()
47 {
48         return !graph->in_process_thread ();
49 }
50
51 }
52 #endif
53
54 Graph::Graph (Session & session) 
55         : SessionHandleRef (session) 
56         , _quit_threads (false)
57         , _execution_sem ("graph_execution", 0)
58         , _callback_start_sem ("graph_start", 0)
59         , _callback_done_sem ("graph_done", 0)
60         , _cleanup_sem ("graph_cleanup", 0)
61 {
62         pthread_mutex_init( &_trigger_mutex, NULL);
63
64         /* XXX: rather hacky `fix' to stop _trigger_queue.push_back() allocating
65            memory in the RT thread.
66         */
67         _trigger_queue.reserve (8192);
68
69         _execution_tokens = 0;
70
71         _current_chain = 0;
72         _pending_chain = 0;
73         _setup_chain   = 1;
74         _quit_threads = false;
75         _graph_empty = true;
76         
77         reset_thread_list ();
78
79         Config->ParameterChanged.connect_same_thread (processor_usage_connection, boost::bind (&Graph::parameter_changed, this, _1));
80
81 #ifdef DEBUG_RT_ALLOC   
82         graph = this;
83         pbd_alloc_allowed = &::alloc_allowed;
84 #endif  
85 }
86
87 void
88 Graph::parameter_changed (std::string param)
89 {
90         if (param == X_("processor-usage")) {
91                 reset_thread_list ();
92         }
93 }
94
95 void
96 Graph::reset_thread_list ()
97 {
98         uint32_t num_threads = how_many_dsp_threads ();
99
100         /* don't bother doing anything here if we already have the right
101            number of threads.
102         */
103
104         if (_thread_list.size() == num_threads) {
105                 return;
106         }
107
108         Glib::Mutex::Lock lm (_session.engine().process_lock());
109         pthread_t a_thread;
110
111         if (!_thread_list.empty()) {
112                 drop_threads ();
113         }
114
115         if (num_threads <= 1) {
116                 /* no point creating 1 thread - the AudioEngine already gives us one
117                  */
118                 return;
119         }
120
121         if (AudioEngine::instance()->create_process_thread (boost::bind (&Graph::main_thread, this), &a_thread, 100000) == 0) {
122                 _thread_list.push_back (a_thread);
123         }
124
125         for (uint32_t i = 1; i < num_threads; ++i) {
126                 if (AudioEngine::instance()->create_process_thread (boost::bind (&Graph::helper_thread, this), &a_thread, 100000) == 0) {
127                         _thread_list.push_back (a_thread);
128                 }
129         }
130 }
131
132 void
133 Graph::session_going_away()
134 {
135         drop_threads ();
136
137         // now drop all references on the nodes.
138         _nodes_rt[0].clear();
139         _nodes_rt[1].clear();
140         _init_trigger_list[0].clear();
141         _init_trigger_list[1].clear();
142         _trigger_queue.clear();
143 }
144
145 void
146 Graph::drop_threads ()
147 {
148         _quit_threads = true;
149
150         for (unsigned int i=0; i< _thread_list.size(); i++) {
151                 _execution_sem.signal ();
152         }
153
154         _callback_start_sem.signal ();
155
156         for (list<pthread_t>::iterator i = _thread_list.begin(); i != _thread_list.end(); ++i) {
157                 void* status;
158                 pthread_join (*i, &status);
159         }
160
161         _thread_list.clear ();
162
163         _quit_threads = false;
164 }
165
166 void
167 Graph::clear_other_chain ()
168 {
169         Glib::Mutex::Lock ls (_swap_mutex);
170
171         while (1) {
172                 if (_setup_chain != _pending_chain) {
173
174                         for (node_list_t::iterator ni=_nodes_rt[_setup_chain].begin(); ni!=_nodes_rt[_setup_chain].end(); ni++) {
175                                 (*ni)->_activation_set[_setup_chain].clear();
176                         }
177
178                         _nodes_rt[_setup_chain].clear ();
179                         _init_trigger_list[_setup_chain].clear ();
180                         break;
181                 }
182                 /* setup chain == pending chain - we have
183                    to wait till this is no longer true.
184                 */
185                 _cleanup_cond.wait (_swap_mutex);                
186         }
187 }
188
189 void
190 Graph::prep()
191 {
192         node_list_t::iterator i;
193         int chain;
194
195         if (_swap_mutex.trylock()) {
196                 // we got the swap mutex.
197                 if (_current_chain != _pending_chain)
198                 {
199                         // printf ("chain swap ! %d -> %d\n", _current_chain, _pending_chain);
200                         _setup_chain = _current_chain;
201                         _current_chain = _pending_chain;
202                         _cleanup_cond.signal ();
203                 }
204                 _swap_mutex.unlock ();
205         }
206
207         chain = _current_chain;
208
209         _graph_empty = true;
210         for (i=_nodes_rt[chain].begin(); i!=_nodes_rt[chain].end(); i++) {
211                 (*i)->prep( chain);
212                 _graph_empty = false;
213         }
214         _finished_refcount = _init_finished_refcount[chain];
215
216         for (i=_init_trigger_list[chain].begin(); i!=_init_trigger_list[chain].end(); i++) {
217                 this->trigger( i->get() );
218         }
219 }
220
221 void
222 Graph::trigger (GraphNode* n)
223 {
224         pthread_mutex_lock (&_trigger_mutex);
225         _trigger_queue.push_back (n);
226         pthread_mutex_unlock (&_trigger_mutex);
227 }
228
229 void
230 Graph::dec_ref()
231 {
232         if (g_atomic_int_dec_and_test (&_finished_refcount)) {
233
234                 // ok... this cycle is finished now.
235                 // we are the only thread alive.
236         
237                 this->restart_cycle();
238         }
239 }
240
241 void
242 Graph::restart_cycle()
243 {
244         // we are through. wakeup our caller.
245
246   again:
247         _callback_done_sem.signal ();
248
249         // block until we are triggered.
250         _callback_start_sem.wait();
251
252         if (_quit_threads) {
253                 return;
254         }
255
256         this->prep();
257
258         if (_graph_empty) {
259                 goto again;
260         }
261
262         // returning will restart the cycle.
263         // starting with waking up the others.
264 }
265
266 static bool
267 is_feedback (boost::shared_ptr<RouteList> routelist, Route* from, boost::shared_ptr<Route> to)
268 {
269         for (RouteList::iterator ri=routelist->begin(); ri!=routelist->end(); ri++) {
270                 if ((*ri).get() == from)
271                         return false;
272                 if ((*ri) == to)
273                         return true;
274         }
275         assert(0);
276         return false;
277 }
278
279 static bool
280 is_feedback (boost::shared_ptr<RouteList> routelist, boost::shared_ptr<Route> from, Route* to)
281 {
282         for (RouteList::iterator ri=routelist->begin(); ri!=routelist->end(); ri++) {
283                 if ((*ri).get() == to)
284                         return true;
285                 if ((*ri) == from)
286                         return false;
287         }
288         assert(0);
289         return false;
290 }
291
292 void
293 Graph::rechain (boost::shared_ptr<RouteList> routelist)
294 {
295         node_list_t::iterator ni;
296         Glib::Mutex::Lock ls (_swap_mutex);
297
298         int chain = _setup_chain;
299         DEBUG_TRACE (DEBUG::Graph, string_compose ("============== setup %1\n", chain));
300         // set all refcounts to 0;
301
302         _init_finished_refcount[chain] = 0;
303         _init_trigger_list[chain].clear();
304
305         _nodes_rt[chain].clear();
306
307         for (RouteList::iterator ri=routelist->begin(); ri!=routelist->end(); ri++) {
308                 node_ptr_t n = boost::dynamic_pointer_cast<GraphNode> (*ri);
309
310                 n->_init_refcount[chain] = 0;
311                 n->_activation_set[chain].clear();
312                 _nodes_rt[chain].push_back(n);
313         }
314
315         // now add refs for the connections.
316
317         for (ni=_nodes_rt[chain].begin(); ni!=_nodes_rt[chain].end(); ni++) {
318                 bool has_input  = false;
319                 bool has_output = false;
320
321                 boost::shared_ptr<Route> rp = boost::dynamic_pointer_cast<Route>( *ni);
322
323                 for (RouteList::iterator ri=routelist->begin(); ri!=routelist->end(); ri++) {
324                         if (rp->direct_feeds (*ri)) {
325                                 if (is_feedback (routelist, rp.get(), *ri)) {
326                                         continue; 
327                                 }
328
329                                 has_output = true;
330                                 (*ni)->_activation_set[chain].insert (boost::dynamic_pointer_cast<GraphNode> (*ri) );
331                         }
332                 }
333
334                 for (Route::FedBy::iterator fi=rp->fed_by().begin(); fi!=rp->fed_by().end(); fi++) {
335                         if (boost::shared_ptr<Route> r = fi->r.lock()) {
336                                 if (!is_feedback (routelist, r, rp.get())) {
337                                         has_input = true;
338                                 }
339                         }
340                 }
341
342                 for (node_set_t::iterator ai=(*ni)->_activation_set[chain].begin(); ai!=(*ni)->_activation_set[chain].end(); ai++) {
343                         (*ai)->_init_refcount[chain] += 1;
344                 }
345
346                 if (!has_input)
347                         _init_trigger_list[chain].push_back (*ni);
348
349                 if (!has_output)
350                         _init_finished_refcount[chain] += 1;
351         } 
352
353         _pending_chain = chain;
354         dump(chain);
355 }
356
357 bool
358 Graph::run_one()
359 {
360         GraphNode* to_run;
361
362         pthread_mutex_lock (&_trigger_mutex);
363         if (_trigger_queue.size()) {
364                 to_run = _trigger_queue.back();
365                 _trigger_queue.pop_back();
366         } else {
367                 to_run = 0;
368         }
369
370         int et = _execution_tokens;
371         int ts = _trigger_queue.size();
372
373         int wakeup = min (et, ts);
374         _execution_tokens -= wakeup;
375
376         DEBUG_TRACE(DEBUG::ProcessThreads, string_compose ("%1 signals %2\n", pthread_self(), wakeup));
377
378         for (int i = 0; i < wakeup; i++) {
379                 _execution_sem.signal ();
380         }
381
382         while (to_run == 0) {
383                 _execution_tokens += 1;
384                 pthread_mutex_unlock (&_trigger_mutex);
385                 DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 goes to sleep\n", pthread_self()));
386                 _execution_sem.wait ();
387                 if (_quit_threads) {
388                         return true;
389                 }
390                 DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 is awake\n", pthread_self()));
391                 pthread_mutex_lock (&_trigger_mutex);
392                 if (_trigger_queue.size()) {
393                         to_run = _trigger_queue.back();
394                         _trigger_queue.pop_back();
395                 }
396         }
397         pthread_mutex_unlock (&_trigger_mutex);
398
399         to_run->process();
400         to_run->finish (_current_chain);
401
402         DEBUG_TRACE(DEBUG::ProcessThreads, string_compose ("%1 has finished run_one()\n", pthread_self()));
403
404         return false;
405 }
406
407 static void get_rt()
408 {
409         if (!jack_is_realtime (AudioEngine::instance()->jack())) {
410                 return;
411         }
412
413         int priority = jack_client_real_time_priority (AudioEngine::instance()->jack());
414
415         if (priority) {
416                 struct sched_param rtparam;
417         
418                 memset (&rtparam, 0, sizeof (rtparam));
419                 rtparam.sched_priority = priority;
420         
421                 pthread_setschedparam (pthread_self(), SCHED_FIFO, &rtparam);
422         }
423 }
424
425 void
426 Graph::helper_thread()
427 {
428         suspend_rt_malloc_checks ();
429         ProcessThread* pt = new ProcessThread ();
430         resume_rt_malloc_checks ();
431
432         pt->get_buffers();
433         get_rt();
434
435         while(1) {
436                 if (run_one()) {
437                         break;
438                 }
439         }
440
441         pt->drop_buffers();
442 }
443
444 void
445 Graph::main_thread()
446 {
447         suspend_rt_malloc_checks ();
448         ProcessThread* pt = new ProcessThread ();
449         resume_rt_malloc_checks ();
450
451         pt->get_buffers();
452         get_rt();
453
454   again:
455         _callback_start_sem.wait ();
456         DEBUG_TRACE(DEBUG::Graph, "main thread is awake\n");
457
458         if (_quit_threads) {
459                 return;
460         }
461
462         this->prep();
463
464         if (_graph_empty && !_quit_threads) {
465                 _callback_done_sem.signal ();
466                 DEBUG_TRACE(DEBUG::Graph, "main thread sees graph done, goes back to slee\n");
467                 goto again;
468         }
469
470         while (1) {
471                 DEBUG_TRACE(DEBUG::Graph, "main thread runs one graph node\n");
472                 if (run_one()) {
473                         break;
474                 }
475         }
476
477         pt->drop_buffers();
478 }
479
480 void
481 Graph::dump (int chain)
482 {
483 #ifndef NDEBUG
484         node_list_t::iterator ni;
485         node_set_t::iterator ai;
486
487         chain = _pending_chain;
488
489         DEBUG_TRACE (DEBUG::Graph, "--------------------------------------------Graph dump:\n");
490         for (ni=_nodes_rt[chain].begin(); ni!=_nodes_rt[chain].end(); ni++) {
491                 boost::shared_ptr<Route> rp = boost::dynamic_pointer_cast<Route>( *ni);
492                 DEBUG_TRACE (DEBUG::Graph, string_compose ("GraphNode: %1  refcount: %2\n", rp->name().c_str(), (*ni)->_init_refcount[chain]));
493                 for (ai=(*ni)->_activation_set[chain].begin(); ai!=(*ni)->_activation_set[chain].end(); ai++) {
494                         DEBUG_TRACE (DEBUG::Graph, string_compose ("  triggers: %1\n", boost::dynamic_pointer_cast<Route>(*ai)->name().c_str()));
495                 }
496         }
497
498         DEBUG_TRACE (DEBUG::Graph, "------------- trigger list:\n");
499         for (ni=_init_trigger_list[chain].begin(); ni!=_init_trigger_list[chain].end(); ni++) {
500                 DEBUG_TRACE (DEBUG::Graph, string_compose ("GraphNode: %1  refcount: %2\n", boost::dynamic_pointer_cast<Route>(*ni)->name().c_str(), (*ni)->_init_refcount[chain]));
501         }
502
503         DEBUG_TRACE (DEBUG::Graph, string_compose ("final activation refcount: %1\n", _init_finished_refcount[chain]));
504 #endif
505 }
506
507 int
508 Graph::silent_process_routes (pframes_t nframes, framepos_t start_frame, framepos_t end_frame,
509                               bool can_record, bool rec_monitors_input, bool& need_butler)
510 {
511         _process_nframes = nframes;
512         _process_start_frame = start_frame;
513         _process_end_frame = end_frame;
514         _process_can_record = can_record;
515         _process_rec_monitors_input = rec_monitors_input;
516
517         _process_silent = true;
518         _process_noroll = false;
519         _process_retval = 0;
520         _process_need_butler = false;
521
522         if (!_graph_empty) {
523                 DEBUG_TRACE(DEBUG::Graph, "wake graph for silent process\n");
524                 _callback_start_sem.signal ();
525                 _callback_done_sem.wait ();
526         }
527
528         need_butler = _process_need_butler;
529
530         return _process_retval;
531 }
532
533 int
534 Graph::process_routes (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, int declick,
535                        bool can_record, bool rec_monitors_input, bool& need_butler)
536 {
537         DEBUG_TRACE (DEBUG::Graph, string_compose ("graph execution from %1 to %2 = %3\n", start_frame, end_frame, nframes));
538
539         _process_nframes = nframes;
540         _process_start_frame = start_frame;
541         _process_end_frame = end_frame;
542         _process_can_record = can_record;
543         _process_rec_monitors_input = rec_monitors_input;
544         _process_declick = declick;
545
546         _process_silent = false;
547         _process_noroll = false;
548         _process_retval = 0;
549         _process_need_butler = false;
550
551         DEBUG_TRACE(DEBUG::Graph, "wake graph for non-silent process\n");
552         _callback_start_sem.signal ();
553         _callback_done_sem.wait ();
554
555         DEBUG_TRACE (DEBUG::Graph, "graph execution complete\n");
556
557         need_butler = _process_need_butler;
558
559         return _process_retval;
560 }
561
562 int
563 Graph::routes_no_roll (pframes_t nframes, framepos_t start_frame, framepos_t end_frame, 
564                        bool non_rt_pending, bool can_record, int declick)
565 {
566         DEBUG_TRACE (DEBUG::Graph, string_compose ("no-roll graph execution from %1 to %2 = %3\n", start_frame, end_frame, nframes));
567
568         _process_nframes = nframes;
569         _process_start_frame = start_frame;
570         _process_end_frame = end_frame;
571         _process_can_record = can_record;
572         _process_declick = declick;
573         _process_non_rt_pending = non_rt_pending;
574
575         _process_silent = false;
576         _process_noroll = true;
577         _process_retval = 0;
578         _process_need_butler = false;
579
580         DEBUG_TRACE(DEBUG::Graph, "wake graph for no-roll process\n");
581         _callback_start_sem.signal ();
582         _callback_done_sem.wait ();
583
584         return _process_retval;
585 }
586 void
587 Graph::process_one_route (Route* route)
588 {
589         bool need_butler = false;
590         int retval;
591
592         assert (route);
593
594         DEBUG_TRACE (DEBUG::ProcessThreads, string_compose ("%1 runs route %2\n", pthread_self(), route->name()));
595
596         if (_process_silent) {
597                 retval = route->silent_roll (_process_nframes, _process_start_frame, _process_end_frame, _process_can_record, _process_rec_monitors_input, need_butler);
598         } else if (_process_noroll) {
599                 route->set_pending_declick (_process_declick);
600                 retval = route->no_roll (_process_nframes, _process_start_frame, _process_end_frame, _process_non_rt_pending, _process_can_record, _process_declick);
601         } else {
602                 route->set_pending_declick (_process_declick);
603                 retval = route->roll (_process_nframes, _process_start_frame, _process_end_frame, _process_declick, _process_can_record, _process_rec_monitors_input, need_butler);
604         }
605
606         if (retval) {
607                 _process_retval = retval;
608         }
609     
610         if (need_butler) {
611                 _process_need_butler = true;
612         }
613 }
614
615 bool
616 Graph::in_process_thread () const
617 {
618         list<pthread_t>::const_iterator i = _thread_list.begin ();
619         while (i != _thread_list.end() && *i != pthread_self ()) {
620                 ++i;
621         }
622
623         return i != _thread_list.end ();
624 }