For playback I am using the ALSA callback to wake up a thread that then feeds the ALSA ring buffer with a period-worth of samples using snd_pcm_writei(). I've set snd_pcm_sw_params_set_avail_min() to one period. The problem is that most of the time when my thread wakes up and tries to write the data, snd_pcm_writei() fails with -EAGAIN, and I must retry until it works.
Presumably this write failure is because there is not enough space in the ring buffer, but then why did the ALSA callback fire in the first place? As it stands my retries are eating needless amounts of CPU.
No definitive help. I don't know the internals, but I have a guess. It probably leads the amount so that on busy systems, underruns don't occur. You could try setting it to 2 buffer min and still writing only a single buffer. That way, you have a buffer of slack.
It seems to make no difference what snd_pcm_sw_set_avail_min() value I use. I tried setting it from twice to many times the period size. I still get ALSA callbacks very often. When I check available space at each callback invocation using snd_pcm_avail_update(), I almost always get much less than this setting. Indeed most usually much less than a single period size.
You might have better luck trying this on the alsa-devel list. The developers live there and they know the internals. It is possible they will answer.
Good idea. I am cross-posting this email. (Hopefully to no-one's annoyance...)
I went and looked at the function you are using. (snip) Are you using a buffer size compatible with your card. It is possible it is using the closest one and that is less than the buffer size you have defined. Just a thought.
To set buffer sizes, I am using set_buffer/period_time_near() and taking whatever the card gives me - I read them back with the get functions. One weird thing I noticed is that my card give me a period size of 470 frames *always*, regardless of whatever desired buffer and period time I ask for. I don't think this issue is related to the async behavior weirdness though.
Thanks for your help.