All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] ALSA: Reduce delay for a blocking pcm_drain.
@ 2013-09-28  3:59 Dylan Reid
  2013-09-30  8:26 ` Takashi Iwai
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Dylan Reid @ 2013-09-28  3:59 UTC (permalink / raw)
  To: alsa-devel; +Cc: tiwai, Dylan Reid

This patch addresses two issues related to calling snd_pcm_drain.

If no_period_wakeup is set, then snd_pcm_drain would wait
MAX_SCHEDULE_TIMEOUT jiffies, without a wakeup pending this will leave
the calling task blocked indefinitely.  Instead block for double the
buffer size played back at a low sample rate (4k chosen arbitrarily).

Also if the stream is running with period wakeups but with a long
period, the delay could be seconds.  If only a small part of the
buffer is being used, this is unnecessary.  Instead wait for the
remaining samples to play out, plus one millisecond.  This allows
systems that fill the buffer only part way to still do a blocking
drain before closing to avoid losing samples.

Change-Id: I84ee1a52d9bdf80ea6065fb9533e565d3e6c8021
Signed-off-by: Dylan Reid <dgreid@chromium.org>
---

This can be worked around in user space as well by using a nonblocking drain and
sleeping based on how many samples are queued.  Would that be the right thing to
do or is this (or something similar) worth fixing here.

To test this I opened a pcm and set no period wakeups, played a few samples and
then called drain, which hung indefinitely.  Using a USB headset with a
max period size of 128k but only 15ms of the buffer filled, having the
drain time shorter without losing samples makes a blocking call
feasible.

---
 sound/core/pcm_native.c | 17 +++++++----------
 1 file changed, 7 insertions(+), 10 deletions(-)

diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index f4aaf5a..a5f0695 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -1481,7 +1481,7 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
 	}
 
 	for (;;) {
-		long tout;
+		long tout, tout_ms;
 		struct snd_pcm_runtime *to_check;
 		if (signal_pending(current)) {
 			result = -ERESTARTSYS;
@@ -1505,16 +1505,13 @@ static int snd_pcm_drain(struct snd_pcm_substream *substream,
 		snd_pcm_stream_unlock_irq(substream);
 		up_read(&snd_pcm_link_rwsem);
 		snd_power_unlock(card);
-		if (runtime->no_period_wakeup)
-			tout = MAX_SCHEDULE_TIMEOUT;
-		else {
-			tout = 10;
-			if (runtime->rate) {
-				long t = runtime->period_size * 2 / runtime->rate;
-				tout = max(t, tout);
-			}
-			tout = msecs_to_jiffies(tout * 1000);
+		tout_ms = runtime->buffer_size * 2 * 1000 / 4000;
+		if (runtime->rate) {
+			snd_pcm_sframes_t hw_avail;
+			hw_avail = snd_pcm_playback_hw_avail(runtime);
+			tout_ms = 1 + hw_avail * 1000 / runtime->rate;
 		}
+		tout = msecs_to_jiffies(tout_ms);
 		tout = schedule_timeout_interruptible(tout);
 		snd_power_lock(card);
 		down_read(&snd_pcm_link_rwsem);
-- 
1.8.1.3.605.g02339dd

^ permalink raw reply related	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-09-30 16:20 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-09-28  3:59 [RFC] ALSA: Reduce delay for a blocking pcm_drain Dylan Reid
2013-09-30  8:26 ` Takashi Iwai
2013-09-30  8:45 ` Clemens Ladisch
2013-09-30 16:20   ` Dylan Reid
     [not found] ` <CAN8cciamcg3wqiDV75oZ6dms-aNtN2o-QMWg0n59otibpmfV7A@mail.gmail.com>
     [not found]   ` <CAN8ccia8VzuubtiOZETTN5DAm_LjmQdaxqDHQQ6iv8S_NvtSBg@mail.gmail.com>
2013-09-30 13:26     ` Raymond Yau
2013-09-30 14:13       ` Clemens Ladisch

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.