aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core/pcm_lib.c
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2010-01-07 09:36:31 -0500
committerJaroslav Kysela <perex@perex.cz>2010-01-07 09:48:13 -0500
commit1250932e48d3b698415b1f04775433cf1da688d6 (patch)
tree58d25383b6fa4e083f24dfc9d51ad4339ff7dece /sound/core/pcm_lib.c
parentf240406babfe1526998e10583ea5eccc2676a433 (diff)
ALSA: pcm_lib - optimize wake_up() calls for PCM I/O
As noted by pl bossart <bossart.nospam@gmail.com>, the PCM I/O routines (snd_pcm_lib_write1, snd_pcm_lib_read1) should block wake_up() calls until all samples are not processed. Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/core/pcm_lib.c')
-rw-r--r--sound/core/pcm_lib.c30
1 files changed, 20 insertions, 10 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 70a4f7428d7..a63226232ef 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -263,8 +263,8 @@ static void xrun_log_show(struct snd_pcm_substream *substream)
263 263
264#endif 264#endif
265 265
266static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream, 266int snd_pcm_update_state(struct snd_pcm_substream *substream,
267 struct snd_pcm_runtime *runtime) 267 struct snd_pcm_runtime *runtime)
268{ 268{
269 snd_pcm_uframes_t avail; 269 snd_pcm_uframes_t avail;
270 270
@@ -285,7 +285,7 @@ static int snd_pcm_update_hw_ptr_post(struct snd_pcm_substream *substream,
285 return -EPIPE; 285 return -EPIPE;
286 } 286 }
287 } 287 }
288 if (avail >= runtime->control->avail_min) 288 if (!runtime->nowake && avail >= runtime->control->avail_min)
289 wake_up(&runtime->sleep); 289 wake_up(&runtime->sleep);
290 return 0; 290 return 0;
291} 291}
@@ -441,7 +441,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
441 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE) 441 if (runtime->tstamp_mode == SNDRV_PCM_TSTAMP_ENABLE)
442 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp); 442 snd_pcm_gettime(runtime, (struct timespec *)&runtime->status->tstamp);
443 443
444 return snd_pcm_update_hw_ptr_post(substream, runtime); 444 return snd_pcm_update_state(substream, runtime);
445} 445}
446 446
447/* CAUTION: call it with irq disabled */ 447/* CAUTION: call it with irq disabled */
@@ -1792,6 +1792,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1792 goto _end_unlock; 1792 goto _end_unlock;
1793 } 1793 }
1794 1794
1795 runtime->nowake = 1;
1795 while (size > 0) { 1796 while (size > 0) {
1796 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 1797 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1797 snd_pcm_uframes_t avail; 1798 snd_pcm_uframes_t avail;
@@ -1813,15 +1814,17 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1813 if (frames > cont) 1814 if (frames > cont)
1814 frames = cont; 1815 frames = cont;
1815 if (snd_BUG_ON(!frames)) { 1816 if (snd_BUG_ON(!frames)) {
1817 runtime->nowake = 0;
1816 snd_pcm_stream_unlock_irq(substream); 1818 snd_pcm_stream_unlock_irq(substream);
1817 return -EINVAL; 1819 return -EINVAL;
1818 } 1820 }
1819 appl_ptr = runtime->control->appl_ptr; 1821 appl_ptr = runtime->control->appl_ptr;
1820 appl_ofs = appl_ptr % runtime->buffer_size; 1822 appl_ofs = appl_ptr % runtime->buffer_size;
1821 snd_pcm_stream_unlock_irq(substream); 1823 snd_pcm_stream_unlock_irq(substream);
1822 if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0) 1824 err = transfer(substream, appl_ofs, data, offset, frames);
1823 goto _end;
1824 snd_pcm_stream_lock_irq(substream); 1825 snd_pcm_stream_lock_irq(substream);
1826 if (err < 0)
1827 goto _end_unlock;
1825 switch (runtime->status->state) { 1828 switch (runtime->status->state) {
1826 case SNDRV_PCM_STATE_XRUN: 1829 case SNDRV_PCM_STATE_XRUN:
1827 err = -EPIPE; 1830 err = -EPIPE;
@@ -1850,8 +1853,10 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1850 } 1853 }
1851 } 1854 }
1852 _end_unlock: 1855 _end_unlock:
1856 runtime->nowake = 0;
1857 if (xfer > 0 && err >= 0)
1858 snd_pcm_update_state(substream, runtime);
1853 snd_pcm_stream_unlock_irq(substream); 1859 snd_pcm_stream_unlock_irq(substream);
1854 _end:
1855 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; 1860 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
1856} 1861}
1857 1862
@@ -2009,6 +2014,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2009 goto _end_unlock; 2014 goto _end_unlock;
2010 } 2015 }
2011 2016
2017 runtime->nowake = 1;
2012 while (size > 0) { 2018 while (size > 0) {
2013 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 2019 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
2014 snd_pcm_uframes_t avail; 2020 snd_pcm_uframes_t avail;
@@ -2037,15 +2043,17 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2037 if (frames > cont) 2043 if (frames > cont)
2038 frames = cont; 2044 frames = cont;
2039 if (snd_BUG_ON(!frames)) { 2045 if (snd_BUG_ON(!frames)) {
2046 runtime->nowake = 0;
2040 snd_pcm_stream_unlock_irq(substream); 2047 snd_pcm_stream_unlock_irq(substream);
2041 return -EINVAL; 2048 return -EINVAL;
2042 } 2049 }
2043 appl_ptr = runtime->control->appl_ptr; 2050 appl_ptr = runtime->control->appl_ptr;
2044 appl_ofs = appl_ptr % runtime->buffer_size; 2051 appl_ofs = appl_ptr % runtime->buffer_size;
2045 snd_pcm_stream_unlock_irq(substream); 2052 snd_pcm_stream_unlock_irq(substream);
2046 if ((err = transfer(substream, appl_ofs, data, offset, frames)) < 0) 2053 err = transfer(substream, appl_ofs, data, offset, frames);
2047 goto _end;
2048 snd_pcm_stream_lock_irq(substream); 2054 snd_pcm_stream_lock_irq(substream);
2055 if (err < 0)
2056 goto _end_unlock;
2049 switch (runtime->status->state) { 2057 switch (runtime->status->state) {
2050 case SNDRV_PCM_STATE_XRUN: 2058 case SNDRV_PCM_STATE_XRUN:
2051 err = -EPIPE; 2059 err = -EPIPE;
@@ -2068,8 +2076,10 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2068 xfer += frames; 2076 xfer += frames;
2069 } 2077 }
2070 _end_unlock: 2078 _end_unlock:
2079 runtime->nowake = 0;
2080 if (xfer > 0 && err >= 0)
2081 snd_pcm_update_state(substream, runtime);
2071 snd_pcm_stream_unlock_irq(substream); 2082 snd_pcm_stream_unlock_irq(substream);
2072 _end:
2073 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err; 2083 return xfer > 0 ? (snd_pcm_sframes_t)xfer : err;
2074} 2084}
2075 2085