diff options
author | Jaroslav Kysela <perex@perex.cz> | 2010-01-21 04:32:15 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2010-01-21 04:32:15 -0500 |
commit | c91a988dc6551c66418690e36b2a23cdb0255da8 (patch) | |
tree | cbb408377b15488d4b45feb2f3d88a616f159814 /sound/core | |
parent | d1db38c015a392b0ea8c15ab95abb3ee768b8d47 (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.c | 1 | ||||
-rw-r--r-- | sound/core/pcm_lib.c | 20 | ||||
-rw-r--r-- | sound/core/pcm_native.c | 3 |
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 | ||
924 | static struct action_ops snd_pcm_action_stop = { | 925 | static 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 | ||
1066 | static struct action_ops snd_pcm_action_suspend = { | 1069 | static struct action_ops snd_pcm_action_suspend = { |