Twine polling & sleep

I wanted to ask for a suggestion on how to perform polling on a Twine thread.
I need my new thread to be ready to perform a routine when a condition is met in the audio thread: in the worker callback I have set up a while loop with a termination flag and an if condition inside, which should check for available data in a ring buffer.
As it is I’m starving xenomai since I have no sleep function in place:
Can I use std::this_thread::sleep_for or should I clone the xenomai repository and use __cobalt_nanosleep?

I’ve also been looking for an alternative to polling, however, I don’t think I can use the wakeup_workers function to signal the rt thread, since my triggering condition happens in the audio thread and that function should be a blocking one. I don’t think can use RtConditionVariable either, since the documentation says that it is used to signal a lower priority non-real-time thread.
Please let me know if there is a nicer way to signal rt threads from other rt threads.

Hi domenico

Is there a reason your worker thread needs to be a xenomai/twine thread? If the worker thread is processing audio data and had the same realtime requirements as the main audio thread, then wouldn’t it make sense to do it synchronously in the same thread? Or partition the work across a few twine worker threads? They could just wake up, check if there’s data in the queue and then return.

You shouldn’t sleep or wait for data in the twine worker callback, that will just mess up the worker pools synchronisation.

If it’s more background work you want to do, then it does sound more like it the RtConditionVariable with a regular Linux thread you should use, though with that there’s no absolute guarantee that that will finish on time.

Hi @Gustav ,
thank you very much for all the details!
Basically, my routine performs the classification of an excerpt of the audio signal with a neural network, and the result is needed to trigger samples. I would call it synchronously but it takes about 4 ms when the time budget of my audio callback is just 1.33 ms (64 samples at 48kHz). I have no way to split the routine into shorter parallel executions so my only alternative seemed to be to call it asynchronously and read the results a few audio-callback calls later (where the samples are triggered). This events can only happen once in a while (min. 20ms apart) so it is not a problem to have the results later. Moreover, I cannot increase the buffer size because of other code that needs to run at a quick rate.

My reason for using a Twine worker (and please tell me if it is a misconception) is that it would allow this routine to always be executed as quickly as possible, as soon as I need it (I suppose because of quick scheduling from the rt kernel). Do you think that it could work as well with a regular Linux kernel?

1 Like

Thanks for the details domenico, I understand your use case better now. I definitely think you should go the route of doing this in a non-rt thread. The RtConditionVariable could be a good fit here. If you use that, you can be reasonable sure that it will execute in the next slot after xenomai gives control back to the Linux scheduler. You could also raise the priority of your processing thread above normal for good measure.

Iif you estimate that it takes ~4 ms to compute the classification, you def don’t want to run this in a twine worker as that would stall the audio for 2-3 audio interrupts, resulting in audio glitches. Because of the nature of xenomai, and it taking control of the scheduler, a xenomai interrupt interrupts all linux threads across all cores. This means that all twine workers have to start and finish within the timespan of 1 audio interrupt (1.33 ms for 64 samples @48kHz in your case) minus any time taken by the rest of Sushi and other plugins that might be running. Otherwise you’ll miss then next audio interrupt and cause an overrun.

Thank you very much!
I definitely misunderstood the inner workings of scheduling with additional threads in xenomai.
I’ll move this to a standard thread and try out the RtConditionVariable then.

Thank you

1 Like

You’re welcome, and good luck!