[alsa-devel] Races in alsa-lib with threads
B42341 at freescale.com
Tue Nov 13 21:55:30 CET 2012
At Tue, 13 Nov 2012 14:41:40 -0500,
Trent Piepho wrote:
> On Tue, Nov 13, 2012 at 8:50 AM, Takashi Iwai <tiwai at suse.de> wrote:
> > At Tue, 13 Nov 2012 13:39:24 +0000,
> > Krakora Robert-B42341 wrote:
> >> The way that the GStreamer ALSA Sink Plugin is using ALSA Lib assumes that it is thread safe. The fix crafted by one of Trent's colleagues (attached) seems to be the way to go. However, I don't know how it would impact other functionality within ALSA Lib.
> > No, sorry, we don't want to introduce pthread_lock in alsa-lib PCM
> > stuff.
> The problem with introduction serialization outside alsa-lib is that
> you must now serialize entire ALSA calls. The locks must be held for
> far too long.
> Consider snd_pcm_writei(), most of the time is usually spent blocked
> waiting for a period to elapse. It is perfectly ok to call
> snd_pcm_delay() during this time. But if one isn't allowed to make
> any other pcm calls during snd_pcm_writei() then this can't be done.
> It's a pretty big problem. Most code using blocking mode is going to
> write another period as soon as the writei call returns from the last
> write. It will spend almost all its time inside snd_pcm_writei() and
> thus will always be holding the app's pcm stream lock. As soon as it
> releases the lock it grabs it again for the next write. Another
> thread trying to call snd_pcm_delay() will virtually NEVER get a
> chance. Not only is it unnecessary stopped from getting the delay
> while another thread is blocked inside writei(), but it won't get a
> chance to call it between writei() calls either.
> But there doesn't need to be a conflict, since the actual critical
> section that needs locking is very small, far smaller than the time
> spent sleeping inside writei() or wait(). How can just the critical
> section be protected without placing the locking inside alsa-lib?
Well, in general it's no good idea to use a blocking write for
multi-thread programs. Most of codes I know use a direct poll() call
for a better control. The blocking mode is basically for dumb program
that doesn't need a control.
Though, I see your point, too. Of course it'd be better if there is
an atomic snd_pcm_delay() call. I think it's possible to give a
consistent value without locking. Here I meant a value that doesn't
express the exact position of the very current time, but at least a
position that is being processed. It'll likely end up calling
snd_pcm_mmap_avail(), and this won't involve with the sync / update
Well, just a thought, for now.
So, the "dumb program" is the GStreamer ALSA Sink plugin. What does an ALSA "poll" example look like?
More information about the Alsa-devel