[LV2] worker thread question

Robin Gareus robin at gareus.org
Sat Dec 29 22:52:50 PST 2012


On 12/30/2012 07:02 AM, hermann meyer wrote:
>> Accessing 'self->schedule' from this context is just wrong.
> Could you explain me why? I call a thread from a other thread, so under
> which circumstances it mater from which thread I call it? If I get what
> you mean here, I could truly move this call to run, just using a
> sem_post.

sem_post() is the same in green. possibly makes things even worse. --
but I'll leave that to Dave, he loves bashing sem_post() :)

There are various aspects to consider:

You don't know the parent process/thread that calls instantiate() which
in turn creates your thread. Launching a thread may have unwanted side
effects on the host itself.
Besides you don't have any handle to the jack_client or the host's
environment to use pthread_getschedparam() to set proper scheduler
priorities for your thread (more on that below).

The host is expected to check for scheduled work after the run() loop
has finished. Scheduling work in places other than the plugin's run()
function can lead to concurrency issues, deadlocks or even crashes of
the host application.
The host must be able to assume that it is in control of the 'schedule'
unless it explicitly grants the plugin control over it. i.e. calling
plugin->run().

Furthermore your thread is kicked at fixed intervals, while it does not
do much work, this still causes a context switch every ~200ms. Surely a
low-latency machine has better things to do..

Lastly, it does not produce reliable reproducible output. Take the
following example: Ardour, plugin parameter automation.
Said automation will change a specific value at a given time and thus
will trigger a worker thread in your plugin.
When exporting (jack freewheeling) ardour processes data as fast as
possible. However, if some plugin's run() schedules a worker-thread, the
worker will be executed right away before things continue.
With your current model the custom thread will get called at some later
time while ardour is busy doing other things.. Since you don't know
thread priorities it may even not be called at all during the export
cycle! The change will come into effect at a random time later.
Even when not exporting you'll add unnecessary random latency to the
effect's output.


Why can't you just move it to the end of the run() function?

sth a like:

  if (val_changed || work_queued) {
    if (worker_is_active) {
      work_queued=true;
    } else {
      work_queued=false;
      schedule->schedule_work(...);
    }
  }

Cheers!
robin



More information about the Devel mailing list