[alsa-devel] [patch] snd_pcm_drain and lock-ups

Mike Gorse mgorse at mgorse.dhs.org
Sun Oct 7 19:40:44 CEST 2007


> >  I posted last week because I am getting lockups when portaudio calls
> >  snd_pcm_drain, and snd_pcm_rate_drain calls snd_pcm_wait on its slave.
> > 
> >  Now that I've looked at this more, I'm seeing that it involves dmix, 
> >  since
> >  a dmix plugin is behind the rate plugin.
> > 
> >  The dmix code in alsa-lib is setting a xrun state because
> >  snd_pcm_mmap_playback_avail returns a large value.
> > 
> >  snd_pcm_wait is then called on the slave of the rate pcm, which is a pcm
> >  with a type of SND_PCM_TYPE_ROUTE whose slave is the dmix, but the route
> >  pcm is returning a different value for snd_pcm_mmap_avail than the dmix
> >  pcm, so it is not triggering snd_pcm_wait to check for a xrun.
> >
>  I think that better fix is to change the code in snd_pcm_rate_drain(). You
>  can set avail_min to 1 there, so condition in snd_pcm_wait() will match.
>
>  Does this patch help?
>
>  diff -r 68d71239d651 src/pcm/pcm_rate.c
>  --- a/src/pcm/pcm_rate.c	Thu Sep 20 13:20:03 2007 +0200
>  +++ b/src/pcm/pcm_rate.c	Fri Sep 21 10:14:41 2007 +0200
> @@ -1076,10 +1076,10 @@ static int snd_pcm_rate_drain(snd_pcm_t
>    snd_pcm_uframes_t size, ofs, saved_avail_min;
>    snd_pcm_sw_params_t sw_params;
>
>  -		/* temporarily set avail_min to one period */
>  +		/* temporarily set avail_min to one */
>    sw_params = rate->sw_params;
>    saved_avail_min = sw_params.avail_min;
>  -		sw_params.avail_min = rate->gen.slave->period_size;
>  +		sw_params.avail_min = 1;
>    snd_pcm_sw_params(rate->gen.slave, &sw_params);
>
>    size = rate->appl_ptr - rate->last_commit_ptr;
>
>        Jaroslav

Unfortunately, I just discovered that this patch (now in alsa-lib 
1.0.15-rc3) does not always solve my problem.  It does most of the time, 
but snd_pcm_avail on the route occasionally returns 0, which is less than 
1, so once in a while I still get a lock-up.  I can't change the 1 to a 0 
in snd_pcm_drain since snd_pcm_sw_params aborts if sw_params->avail_min == 
0.

My original approach of checking for SND_PCM_TYPE_ROUTE in snd_pcm_wait() 
would still work.

It looks as though there is a buffer to fill which is included when 
snd_pcm_mmap_avail looks at the dmix pcm but not when it looks at the 
route in between the rate and the dmix.

-Mike G-


More information about the Alsa-devel mailing list