[alsa-devel] ALSA calling pcm_pointer excessively?
Clemens Ladisch
clemens at ladisch.de
Thu May 10 19:13:59 CEST 2012
I wrote:
> This (untested) patch tries to avoid too many busy looping.
Oops, off-by-one error (avail == avail_min should not wait).
Regards,
Clemens
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -1894,7 +1894,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
struct snd_pcm_runtime *runtime = substream->runtime;
snd_pcm_uframes_t xfer = 0;
snd_pcm_uframes_t offset = 0;
- int err = 0;
+ int busy_loops = 0, err = 0;
if (size == 0)
return 0;
@@ -1919,12 +1919,17 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
runtime->twake = runtime->control->avail_min ? : 1;
while (size > 0) {
snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
- snd_pcm_uframes_t avail;
+ snd_pcm_uframes_t avail, avail_nowait_min;
snd_pcm_uframes_t cont;
+
+ if (busy_loops < 5)
+ avail_nowait_min = 1;
+ else
+ avail_nowait_min = min(runtime->control->avail_min, size);
if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
snd_pcm_update_hw_ptr(substream);
avail = snd_pcm_playback_avail(runtime);
- if (!avail) {
+ if (avail < avail_nowait_min) {
if (nonblock) {
err = -EAGAIN;
goto _end_unlock;
@@ -1934,6 +1939,9 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
err = wait_for_avail(substream, &avail);
if (err < 0)
goto _end_unlock;
+ busy_loops = 0;
+ } else {
+ busy_loops++;
}
frames = size > avail ? avail : size;
cont = runtime->buffer_size - runtime->control->appl_ptr % runtime->buffer_size;
More information about the Alsa-devel
mailing list