[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