[PATCH] alsa: Avoid creating tiny memchunks on write iterations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



If the ALSA device supports granular pointer reporting, we end up in a
situation where we write out a bunch of data, iterate, and then find a
small amount of data available in the buffer (consumed while we were
writing data into the available buffer space). We do this 10 times
before quitting the write loop.

This is inefficient in itself, but can also have wider consequences. For
example, with module-combine-sink, this will end up pushing the same
small chunks to all other devices too.

Given both of these, it just makes sense to not try to write out data
unless a minimum threshold is available. This could potentially be a
fragment, but it's likely most robust to just work with a fraction of
the total available buffer size.
---
 src/modules/alsa/alsa-sink.c | 20 ++++++++++++++++++--
 1 file changed, 18 insertions(+), 2 deletions(-)

diff --git a/src/modules/alsa/alsa-sink.c b/src/modules/alsa/alsa-sink.c
index 886c735..43cd965 100644
--- a/src/modules/alsa/alsa-sink.c
+++ b/src/modules/alsa/alsa-sink.c
@@ -88,6 +88,8 @@
 #define DEFAULT_REWIND_SAFEGUARD_BYTES (256U) /* 1.33ms @48kHz, we'll never rewind less than this */
 #define DEFAULT_REWIND_SAFEGUARD_USEC (1330) /* 1.33ms, depending on channels/rate/sample we may rewind more than 256 above */
 
+#define DEFAULT_WRITE_ITERATION_THRESHOLD 0.03 /* don't iterate write if < 3% of the buffer is available */
+
 struct userdata {
     pa_core *core;
     pa_module *module;
@@ -580,12 +582,19 @@ static int mmap_write(struct userdata *u, pa_usec_t *sleep_usec, bool polled, bo
             break;
         }
 
-        if (++j > 10) {
+        j++;
+
+        if (j > 10) {
 #ifdef DEBUG_TIMING
             pa_log_debug("Not filling up, because already too many iterations.");
 #endif
 
             break;
+        } else if (j >= 1 && (n_bytes < (DEFAULT_WRITE_ITERATION_THRESHOLD * (u->hwbuf_size - u->hwbuf_unused)))) {
+#ifdef DEBUG_TIMING
+            pa_log_debug("Not filling up, because <%g%% available.", DEFAULT_WRITE_ITERATION_THRESHOLD * 100);
+#endif
+            break;
         }
 
         n_bytes -= u->hwbuf_unused;
@@ -754,12 +763,19 @@ static int unix_write(struct userdata *u, pa_usec_t *sleep_usec, bool polled, bo
             break;
         }
 
-        if (++j > 10) {
+        j++;
+
+        if (j > 10) {
 #ifdef DEBUG_TIMING
             pa_log_debug("Not filling up, because already too many iterations.");
 #endif
 
             break;
+        } else if (j >= 1 && (n_bytes < (DEFAULT_WRITE_ITERATION_THRESHOLD * (u->hwbuf_size - u->hwbuf_unused)))) {
+#ifdef DEBUG_TIMING
+            pa_log_debug("Not filling up, because <%g%% available.", DEFAULT_WRITE_ITERATION_THRESHOLD * 100);
+#endif
+            break;
         }
 
         n_bytes -= u->hwbuf_unused;
-- 
2.9.3



[Index of Archives]     [Linux Audio Users]     [AMD Graphics]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux