aboutsummaryrefslogtreecommitdiffstats
path: root/sound/core
diff options
context:
space:
mode:
authorJaroslav Kysela <perex@perex.cz>2010-01-21 04:32:15 -0500
committerJaroslav Kysela <perex@perex.cz>2010-01-21 04:32:15 -0500
commitc91a988dc6551c66418690e36b2a23cdb0255da8 (patch)
treecbb408377b15488d4b45feb2f3d88a616f159814 /sound/core
parentd1db38c015a392b0ea8c15ab95abb3ee768b8d47 (diff)
ALSA: pcm_core: Fix wake_up() optimization
This change fixes the "ALSA: pcm_lib - optimize wake_up() calls for PCM I/O" commit. New sleeping queue is introduced to separate user space and kernel space wake_ups. runtime->nowake is renamed to twake (transfer wake). Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/core')
-rw-r--r--sound/core/pcm.c1
-rw-r--r--sound/core/pcm_lib.c20
-rw-r--r--sound/core/pcm_native.c3
3 files changed, 14 insertions, 10 deletions
diff --git a/sound/core/pcm.c b/sound/core/pcm.c
index df57a0e30bf2..0d428d0896db 100644
--- a/sound/core/pcm.c
+++ b/sound/core/pcm.c
@@ -894,6 +894,7 @@ int snd_pcm_attach_substream(struct snd_pcm *pcm, int stream,
894 memset((void*)runtime->control, 0, size); 894 memset((void*)runtime->control, 0, size);
895 895
896 init_waitqueue_head(&runtime->sleep); 896 init_waitqueue_head(&runtime->sleep);
897 init_waitqueue_head(&runtime->tsleep);
897 898
898 runtime->status->state = SNDRV_PCM_STATE_OPEN; 899 runtime->status->state = SNDRV_PCM_STATE_OPEN;
899 900
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 5417f7dce834..e2a817eac2a9 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -285,8 +285,8 @@ int snd_pcm_update_state(struct snd_pcm_substream *substream,
285 return -EPIPE; 285 return -EPIPE;
286 } 286 }
287 } 287 }
288 if (!runtime->nowake && avail >= runtime->control->avail_min) 288 if (avail >= runtime->control->avail_min)
289 wake_up(&runtime->sleep); 289 wake_up(runtime->twake ? &runtime->tsleep : &runtime->sleep);
290 return 0; 290 return 0;
291} 291}
292 292
@@ -1692,7 +1692,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream,
1692 long tout; 1692 long tout;
1693 1693
1694 init_waitqueue_entry(&wait, current); 1694 init_waitqueue_entry(&wait, current);
1695 add_wait_queue(&runtime->sleep, &wait); 1695 add_wait_queue(&runtime->tsleep, &wait);
1696 for (;;) { 1696 for (;;) {
1697 if (signal_pending(current)) { 1697 if (signal_pending(current)) {
1698 err = -ERESTARTSYS; 1698 err = -ERESTARTSYS;
@@ -1735,7 +1735,7 @@ static int wait_for_avail_min(struct snd_pcm_substream *substream,
1735 break; 1735 break;
1736 } 1736 }
1737 _endloop: 1737 _endloop:
1738 remove_wait_queue(&runtime->sleep, &wait); 1738 remove_wait_queue(&runtime->tsleep, &wait);
1739 *availp = avail; 1739 *availp = avail;
1740 return err; 1740 return err;
1741} 1741}
@@ -1794,7 +1794,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1794 goto _end_unlock; 1794 goto _end_unlock;
1795 } 1795 }
1796 1796
1797 runtime->nowake = 1; 1797 runtime->twake = 1;
1798 while (size > 0) { 1798 while (size > 0) {
1799 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 1799 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
1800 snd_pcm_uframes_t avail; 1800 snd_pcm_uframes_t avail;
@@ -1816,7 +1816,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1816 if (frames > cont) 1816 if (frames > cont)
1817 frames = cont; 1817 frames = cont;
1818 if (snd_BUG_ON(!frames)) { 1818 if (snd_BUG_ON(!frames)) {
1819 runtime->nowake = 0; 1819 runtime->twake = 0;
1820 snd_pcm_stream_unlock_irq(substream); 1820 snd_pcm_stream_unlock_irq(substream);
1821 return -EINVAL; 1821 return -EINVAL;
1822 } 1822 }
@@ -1855,7 +1855,7 @@ static snd_pcm_sframes_t snd_pcm_lib_write1(struct snd_pcm_substream *substream,
1855 } 1855 }
1856 } 1856 }
1857 _end_unlock: 1857 _end_unlock:
1858 runtime->nowake = 0; 1858 runtime->twake = 0;
1859 if (xfer > 0 && err >= 0) 1859 if (xfer > 0 && err >= 0)
1860 snd_pcm_update_state(substream, runtime); 1860 snd_pcm_update_state(substream, runtime);
1861 snd_pcm_stream_unlock_irq(substream); 1861 snd_pcm_stream_unlock_irq(substream);
@@ -2016,7 +2016,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2016 goto _end_unlock; 2016 goto _end_unlock;
2017 } 2017 }
2018 2018
2019 runtime->nowake = 1; 2019 runtime->twake = 1;
2020 while (size > 0) { 2020 while (size > 0) {
2021 snd_pcm_uframes_t frames, appl_ptr, appl_ofs; 2021 snd_pcm_uframes_t frames, appl_ptr, appl_ofs;
2022 snd_pcm_uframes_t avail; 2022 snd_pcm_uframes_t avail;
@@ -2045,7 +2045,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2045 if (frames > cont) 2045 if (frames > cont)
2046 frames = cont; 2046 frames = cont;
2047 if (snd_BUG_ON(!frames)) { 2047 if (snd_BUG_ON(!frames)) {
2048 runtime->nowake = 0; 2048 runtime->twake = 0;
2049 snd_pcm_stream_unlock_irq(substream); 2049 snd_pcm_stream_unlock_irq(substream);
2050 return -EINVAL; 2050 return -EINVAL;
2051 } 2051 }
@@ -2078,7 +2078,7 @@ static snd_pcm_sframes_t snd_pcm_lib_read1(struct snd_pcm_substream *substream,
2078 xfer += frames; 2078 xfer += frames;
2079 } 2079 }
2080 _end_unlock: 2080 _end_unlock:
2081 runtime->nowake = 0; 2081 runtime->twake = 0;
2082 if (xfer > 0 && err >= 0) 2082 if (xfer > 0 && err >= 0)
2083 snd_pcm_update_state(substream, runtime); 2083 snd_pcm_update_state(substream, runtime);
2084 snd_pcm_stream_unlock_irq(substream); 2084 snd_pcm_stream_unlock_irq(substream);
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index 27284f628361..56ec35e8510b 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -919,6 +919,7 @@ static void snd_pcm_post_stop(struct snd_pcm_substream *substream, int state)
919 runtime->status->state = state; 919 runtime->status->state = state;
920 } 920 }
921 wake_up(&runtime->sleep); 921 wake_up(&runtime->sleep);
922 wake_up(&runtime->tsleep);
922} 923}
923 924
924static struct action_ops snd_pcm_action_stop = { 925static struct action_ops snd_pcm_action_stop = {
@@ -1004,6 +1005,7 @@ static void snd_pcm_post_pause(struct snd_pcm_substream *substream, int push)
1004 SNDRV_TIMER_EVENT_MPAUSE, 1005 SNDRV_TIMER_EVENT_MPAUSE,
1005 &runtime->trigger_tstamp); 1006 &runtime->trigger_tstamp);
1006 wake_up(&runtime->sleep); 1007 wake_up(&runtime->sleep);
1008 wake_up(&runtime->tsleep);
1007 } else { 1009 } else {
1008 runtime->status->state = SNDRV_PCM_STATE_RUNNING; 1010 runtime->status->state = SNDRV_PCM_STATE_RUNNING;
1009 if (substream->timer) 1011 if (substream->timer)
@@ -1061,6 +1063,7 @@ static void snd_pcm_post_suspend(struct snd_pcm_substream *substream, int state)
1061 runtime->status->suspended_state = runtime->status->state; 1063 runtime->status->suspended_state = runtime->status->state;
1062 runtime->status->state = SNDRV_PCM_STATE_SUSPENDED; 1064 runtime->status->state = SNDRV_PCM_STATE_SUSPENDED;
1063 wake_up(&runtime->sleep); 1065 wake_up(&runtime->sleep);
1066 wake_up(&runtime->tsleep);
1064} 1067}
1065 1068
1066static struct action_ops snd_pcm_action_suspend = { 1069static struct action_ops snd_pcm_action_suspend = {