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

Reply via email to