dingusppc icon indicating copy to clipboard operation
dingusppc copied to clipboard

soundserver_cubeb: fix cross-thread access of the sound out DMA buffer

Open mihaip opened this issue 1 year ago • 3 comments

Instead of directly reading from the sound out DMA buffer in the cubeb callback, we have a polling task that copies it to a thread-safe ring buffer (found in the cubeb sources). That buffer can be read from the cubeb callback safely.

mihaip avatar Aug 15 '24 06:08 mihaip

I'll look at this tonight.

maximumspatium avatar Aug 15 '24 14:08 maximumspatium

This is necessary only if the cubeb callback can read the sound out DMA buffer after the guest OS thinks the sound hardware is done with the sound out DMA buffer?

joevt avatar Aug 17 '24 06:08 joevt

At least on a macOS host the cubeb callback runs on a separate thread, and can be invoked at arbitrary times. The main thread (where the rest of DPPC runs) can be in any state, including mid-update of the DMA channel fields. That would lead to inconsistent results at best, or corruption at worst.

The DMA channel read also has other side effects (e.g. it may register a timer in the PDM/AMIC implementation), which is another source of threading issues. I put some examples of the issues that Thread Sanitizer flagged in Discord: https://discord.com/channels/394224641654259712/441411517297065994/1273848926067232842

The approach here is to do all DMA channel acces on the main thread, and to have it keep a (thread safe) buffer filled that the cubeb callback/thread can read from. This being done via polling is not ideal, but I'm less familiar with DMA internals (ideally there could be a callback reigsteree whenever data is added).

mihaip avatar Aug 17 '24 06:08 mihaip

Will close for now, and revisit if I have better ideas for doing this without polling (e.g. registering a callback on the DMA channel to copy data out of it whenever it's written to)

mihaip avatar Feb 14 '25 16:02 mihaip