Simple question, can be used Thread::notify() (to trigger an external thread) inside the AudioProcessor::processBlock()? Or does it perform any lock and it should be forbidden?
Sure, youāre almost certainly safe to call that.
Thank you, really appreciated
Iām on macOS - Thread::notify() calls WaitableEvent::signal(), and on a Posix system, this function calls pthread_mutex_lock (&mutex).
Unless macOS supports priority inheritance from realtime threads to normal Posix threads (does it? I donāt knowā¦), Iād rather avoid calling Thread::notify() on a realtime thread/audio callback.
Are there perhaps any good alternatives available that are guaranteed to be lock-free? Iād also like to wake up other threads from audio callback context, but seems dangerous with juce::notify() at least with the posix implementation that contains locks.
I think it does, the mutex is configured with the following attributes:
pthread_mutexattr_setprotocol (&atts, PTHREAD_PRIO_INHERIT);
@myhrman do you know that this is actually a problem? A mutex lock/unlock might take slightly more time to execute than a lock-free implementation but as long as itās not guarding anything that is unbounded the time is deterministic (resource contention considered).
If I understand correctly, the mutex inside a WaitableEvent::signal()
is only locked between entry in to wait/signal
and the condition broadcast/wait
calls.
If you have a low-priority thread calling wait
that happens to sleep between the mutex lock and condition wait, when it is signaled, that thread will wake up as soon as possible to complete.
The main thing to be worried of here is gettimeofday
if it results in a system call. However I have a feeling that these have mapped user-space versions in a lot of Linux OSes (and maybe macOS, it would be good to check).
Is there some other performance hit youāre seeing? Iād be interested to know as well how this kind of thing manifests on different OSes.
This quite likely only works within the Posix priority band. Itās unclear and undocumented whether regular Posix threads will be temporarily elevated to a time-constrained priority.
Cf. macos - OS X PTHREAD_PRIO_INHERIT mutexes between normal and real-time threads? - Stack Overflow
Interesting. It looks like wait_queues might be a better API to use on macOs? https://developer.apple.com/library/archive/documentation/Darwin/Conceptual/KernelProgramming/scheduler/scheduler.html
Or maybe GCD has a slightly higher level API.
Also, if weāre talking about JUCE Audio callbacks, donāt they run on their own thread which I donāt think gets created with THREAD_TIME_CONSTRAINT_POLICY anyway?
Iād like to get to the bottom of this tangent but back to the OP, whatās the use case? How quickly do you need to wake up other threads from within the audio thread and are you then waiting on them to complete or can you just carry on?
@dave96 I donāt know if there is an actual problem with notify() taking too long time to execute. I so far only have a suspicion about this being the case. We did mitigate a similar problem by getting rid of notify(), but it could also be that the root cause was something else in this situation, and that the observed result was just a side-effect.
My use-case is this BTW: on each audio frame, a thread needs to wake up and start asynchronous processing of some data that is passed via lock-free queues from each audio callback. Without the notify(), the thread needs to poll very often for new data, causing quite some CPU load when it is done basically each millisecond. The audio thread does not wait for the external thread to finish or anything, it just triggers it in order to minimize the latency.
In these situations Iām wondering if you could have something like a timer or third āserviceā thread that simply checks some atomics and then calls notify
on the processing thread.
That way, the audio callback would just set one of these atomic flags to mark it as āneeding a notification callā.
Itās a bit convoluted though and as you say, will add some extra overhead as youād need something to poll these flags but it would be lock-free.
Iād like to ask how is the situation today with calling Thread::notify()
from the audio thread? Any new experiences? I havenāt experienced any locks even under heavy load butā¦