Am 08.02.22 um 16:41 schrieb Will Godfrey:
I've been doing a bit of poking around. It seems the Xruns are being caused by actually entering futureBuild.swap(), not the code inside it.
Hi Will, thanks for following up on that one. Last weekend I also tried somehow to provoke that Xrun, but I don't seem able to reproduce that behaviour, even with an VM using only two cores. Either I get Xruns all over the place, or I don't get any.
Flying by the seat of my pants here, is it possible to make the swap in a non-rt thread to maybe a 'plain' intermediate wavetable, and then do the rt swap with this?
That would kindof bring us back to square one: we use the std::future (which is managed within the class FutureBuild) to protect the passing of data between threads. Thus we'd again need some sync primitive to protect the handover from the helper-thread you propose to the actual rt-thread. Please recall that threads can potentially run on different or the same CPU, and that without any sync primitive, there is no guarantee that the other CPU sees the memory content coherently. E.g. it could be that the rt-thead sees the swap of the pointer, but not the new contents of the wavetable. Btw, such hickups are unlikely to happen on x86 processors, but more likely to happen on ARM or other architectures with "weak cache corherence" However, Your observations might point into an interesting direction.
If I comment out all the code inside the function, then while (obviously) there is no sound I still see all the Xruns. However, if I comment out the *call* to it in activate_wavetable() there are no Xruns.
Now the important question is: what is with the Condition test...?
if (futureBuild.isReady())
Does that coincide with Xruns? could you maybe test that in isolation? I.e. invoke the isReady(), but then only do something local wi within the Body of the if-clause. eg assign some variable? The reason why I am asking is as follows: The implementation of FutureBuild::isReady() (see BuildScheduler.h line 347) does a non-blocking wait on the future. However, while this "technically" does not incur any blocking wait, it implies a so called "yield point". That means, the OS scheduler *can* at that point preempt and reschedule to another thread, and this becomes more likely if the system as such is already under pressure (which might be the case, since, if I recall correct, your test system has only effectively two cores, and we have at least two threads with permanent computing or I/O activity (the ALSA thread and the Synth thread). Another thing you could try (in case the call to isReady() does not give us a lead) is to invoke some other function on the futureBuild object, within the body of the if-clause (instead of invoking FutureBuild::swap(). For example call FutureBuild::isUnderway() ... -- Hermann PS: last weekend I was struggling to chase down some problem within the Reverb effect, which seems to produce spurious differences in the test suite. _______________________________________________ Yoshimi-devel mailing list Yoshimi-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/yoshimi-devel