[LV2] worker thread question

hermann meyer brummer- at web.de
Sat Dec 29 23:16:46 PST 2012


Am 30.12.2012 07:52, schrieb Robin Gareus:
> 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().

Thanks, I understand that and have moved the call to the worker thread 
back to run.
Well I didn't use a sem_post, but a volatile int32_t set by my watch thread.

if (atomic_get(schedule_doit))
     {
       atomic_set(&schedule_doit,0);
       schedule->schedule_work(schedule->handle, sizeof(bool), &doit);
     }
>
> 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..
surly a low-level machine have better things to do then check exactly 
that every ~5ms in the rt-context.

> 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.
>
What I do here in the work thread is a single process run for a float 
array and fill the impdata from the convolver. Thus cant have any timed 
guaranty.

> 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(...);
>      }
>    }
well, that is how I have release it for now. :-)

> Cheers!
> robin
greets
hermann



More information about the Devel mailing list