ALSA: pcm - Optimize the call of snd_pcm_update_hw_ptr() in read/write loop
[firefly-linux-kernel-4.4.55.git] / sound / core / pcm_lib.c
index 4d18941178e6e933cb0f80f969c4d705c4777caf..faedb1481b240d9195b097f1448f98df3dcb6912 100644 (file)
@@ -1894,6 +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;
+       snd_pcm_uframes_t avail;
        int err = 0;
 
        if (size == 0)
@@ -1917,13 +1918,12 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
        }
 
        runtime->twake = runtime->control->avail_min ? : 1;
+       if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
+               snd_pcm_update_hw_ptr(substream);
+       avail = snd_pcm_playback_avail(runtime);
        while (size > 0) {
                snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
-               snd_pcm_uframes_t avail;
                snd_pcm_uframes_t cont;
-               if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
-                       snd_pcm_update_hw_ptr(substream);
-               avail = snd_pcm_playback_avail(runtime);
                if (!avail) {
                        if (nonblock) {
                                err = -EAGAIN;
@@ -1971,6 +1971,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
                offset += frames;
                size -= frames;
                xfer += frames;
+               avail -= frames;
                if (runtime->status->state == SNDRV_PCM_STATE_PREPARED &&
                    snd_pcm_playback_hw_avail(runtime) >= (snd_pcm_sframes_t)runtime->start_threshold) {
                        err = snd_pcm_start(substream);
@@ -2111,6 +2112,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
        struct snd_pcm_runtime *runtime = substream->runtime;
        snd_pcm_uframes_t xfer = 0;
        snd_pcm_uframes_t offset = 0;
+       snd_pcm_uframes_t avail;
        int err = 0;
 
        if (size == 0)
@@ -2141,13 +2143,12 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
        }
 
        runtime->twake = runtime->control->avail_min ? : 1;
+       if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
+               snd_pcm_update_hw_ptr(substream);
+       avail = snd_pcm_capture_avail(runtime);
        while (size > 0) {
                snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
-               snd_pcm_uframes_t avail;
                snd_pcm_uframes_t cont;
-               if (runtime->status->state == SNDRV_PCM_STATE_RUNNING)
-                       snd_pcm_update_hw_ptr(substream);
-               avail = snd_pcm_capture_avail(runtime);
                if (!avail) {
                        if (runtime->status->state ==
                            SNDRV_PCM_STATE_DRAINING) {
@@ -2202,6 +2203,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
                offset += frames;
                size -= frames;
                xfer += frames;
+               avail -= frames;
        }
  _end_unlock:
        runtime->twake = 0;