[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [fluid-dev] Thread safety
Re: [fluid-dev] Thread safety
Mon, 25 May 2009 03:49:19 -0400
Internet Messaging Program (IMP) H3 (4.1.6)
Quoting David Henningsson <address@hidden>:
Excitement is a good thing. It would be nice to know your plans in terms
of time and effort, that is, if you can tell in advance. :-)
Indeed, it is difficult for me to know how much time I have available.
I've had my mind on this particular subject for a bit now though.
Looking at how things are coded in FluidSynth, I'm amazed there aren't
more issues, in real world use. I suspect there are lots of issues
lurking, those one in a million synthesis glitches or worst case,
I wonder what the effect would be of using mutexes. In real life, how
bad would the lock contention be and would it lead to audio underruns?
Identifying the areas where mutexes are needed would help with this.
Perhaps we could have "big" mutexes (i e one for everything), but on the
voice level instead of the synth level. And on the synth level we try to
use the atomic functions, I assume that's doable.
The downside is more mutexes (one per playing voice), but on the other
hand they should be finished more quickly. So we win in the worst case
but lose in the average case.
Another wild idea would be to preprocess the voices so we're always a
few buffers ahead for every voice. A lower priority thread (or several,
for multicore CPUs) could handle this. The audio thread would then just
mix the voices together. Care has to be taken that MIDI events will
throw already created buffers away.
I think ideas like these are good. Having each voice be processed and
then mixed, would only require one buffer (64 bytes) per voice and
would not require much extra CPU. This could also facilitate moving
to the multi-thread voice processing model.
I've been thinking about what the ideal FluidSynth thread model would
be for lock-free (or as close to lock free as possible) and of course
crash free ;)
Here are some initial thoughts, though perhaps faulty by design and
* Make active voices and voice pool private to the synthesis thread.
* Parameter updates (MIDI events, etc) go through a lock free FIFO queue.
* Voices are allocated outside of the synthesis process, initialized
and added to the FIFO queue for processing.
* Note-off events are also appended to the event queue.
This would leave the main synthesis thread (and future helper threads)
to do the dirty work, without pesky meddling from other threads.
The issue that I have run into, is that I haven't been able to find a
FIFO queue algorithm which allows multiple producers. A lock free
FIFO with single producer and consumer is pretty trivial, but if there
are events occurring from more than one thread, then those won't work.
Seems silly to have a lock based queue to the main producer thread
which then sends things over the lock free queue. If the main MIDI
thread was the single producer though, then it might not be such a
limitation, to post events from any other threads via another lock
based queue (for example the FluidSynth shell).
Doing things right, seems a bit complicated!
My patch - in its current state - does not touch the synth. It changes
the sequencer according to the text above, and fluidsynth.c manually
inserts a sequencer between the midi router and the synth. So
libfluidsynth applications such as Swami and qsynth will neither suffer
or gain from this patch, unless they do the same.
What do you say if we leave it at that for the moment, I commit the
patch and we can all test it to see if we find any difference in latency
or stability when we use fluidsynth from the command line?
And at a later point in time we could review the synth threading a bit
more deep, to see if we can improve the situation (with regards to
segfaults, parallellization, stalls etc)?
Lets hold off on the patch for the moment. I want to have a look over
the lot myself to get a better idea of how we might proceed.
My idea was that if I commit my patch in its current state, at least we
will have something more stable (fix for ticket #43). And I think the
possibility to route midi events through the sequencer makes a valuable
addition to the sequencer. And when we have improved the synth thread
safety, we will simply revert the three lines in fluidsynth.c that
inserts the sequencer in the chain. What do you think?
Sure, if it improves things in the short term, go ahead add it.
Fixing FluidSynth's threading issues, and doing it right, is likely
going to be a bit of a larger task than doing simple fixes. So it
might be good to try and address the more severe issues, while coming
up with a long term solution.