Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stop using mutexes #1

Open
Clownacy opened this issue Nov 3, 2019 · 5 comments
Open

Stop using mutexes #1

Clownacy opened this issue Nov 3, 2019 · 5 comments

Comments

@Clownacy
Copy link
Owner

Clownacy commented Nov 3, 2019

Apparently using mutexes in an audio callback is a stupid idea, because of stuff like priority-inversion. I never liked using them anyway, since the ones in clownaudio are locked to Windows and POSIX.

Supposedly I should look into lock-free buffers or something. Maybe I can set up a kind of communication system where the main thread only gives commands to the audio callback, instead of modifying shared data - that way, the audio callback is solely-responsible for modifying its private data, avoiding conflicts.

@Clownacy
Copy link
Owner Author

I should probably point out, for future reference, that miniaudio provides a lock-free ring-buffer implementation that might come in handy here.

@Clownacy
Copy link
Owner Author

Arg, apparently miniaudio's lock-free ring buffers aren't for message queues... I wonder what the proper way to go about this is?

@larpon
Copy link

larpon commented Jan 12, 2020

I've wondered about that too. Getting data into the callback without locks aren't as straightforward as it seems at first glance

@Clownacy
Copy link
Owner Author

Clownacy commented Mar 3, 2020

So apparently writing a simple lock-free single-consumer/single-producer FIFO is pretty easy, and relatively portable too (the GCC devs claim 'int' is very likely to be atomic).

So, off the top of my head, I could just create a command FIFO, and make the audio thread entirely self-contained - responsible for sound creation, destruction, mixing, etc.

I should probably stop using malloc in that case, since apparently you can't be sure how fast those functions are. A static array of sound slots with a compile-time-configurable size should be fine, instead.

Regarding how exactly the command queue will work, I'm thinking of taking some inspiration from my Mega Drive days - namely the FIFO used by the VDP: each command has an ID, and a tiny data buffer (maybe an int). Any commands that require more than an int's worth of data will be spread across multiple commands, and it will be only the final command in that list that will cause the audio thread to finally process them (think of how you set up a VDP DMA transfer).

Granted, there is one case where the audio thread needs to communicate back to the main thread: the newly-added GetSoundStatus function. However, because this function only returns 0, 1, or -1, I think I can actually safely use a table of atomics, allowing this function to be performed entirely-asynchronously.

@larpon
Copy link

larpon commented Mar 3, 2020

Thanks for sharing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants