]> git.alsa-project.org Git - alsa-utils.git/commitdiff
axfer: add an option to suppress event waiting
authorTakashi Sakamoto <o-takashi@sakamocchi.jp>
Tue, 13 Nov 2018 06:41:36 +0000 (15:41 +0900)
committerTakashi Iwai <tiwai@suse.de>
Tue, 13 Nov 2018 11:04:37 +0000 (12:04 +0100)
In aplay, '--test-nowait' is used to suppress calls of snd_pcm_wait()
when I/O operations return -EAGAIN or process truncated number of data
frames. This seems to be for debugging purpose. In this program, this
option is equivalent to suppress event waiting.

This commit adds support for this option.

Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
axfer/xfer-libasound-irq-mmap.c
axfer/xfer-libasound-irq-rw.c
axfer/xfer-libasound.c
axfer/xfer-libasound.h

index 87ef7e044f6441733753161079b446ad5189f0ea..18f6dfe7b3afd0f1dfb13537a50a3b61c1287cf4 100644 (file)
@@ -81,10 +81,12 @@ static int irq_mmap_process_frames(struct libasound_state *state,
        snd_pcm_sframes_t consumed_count;
        int err;
 
-       // Wait for hardware IRQ when no avail space in buffer.
-       err = snd_pcm_wait(state->handle, -1);
-       if (err < 0)
-               return err;
+       if (state->use_waiter) {
+               // Wait for hardware IRQ when no avail space in buffer.
+               err = snd_pcm_wait(state->handle, -1);
+               if (err < 0)
+                       return err;
+       }
 
        // Sync cache in user space to data in kernel space to calculate avail
        // frames according to the latest positions on PCM buffer.
index f05ac4b0e968d09643865cf96a11b29d8d9dda77..625c095d95b424964d43b938a98ce1c1fe0f7494 100644 (file)
@@ -133,10 +133,12 @@ static int r_process_frames_nonblocking(struct libasound_state *state,
                        goto error;
        }
 
-       // Wait for hardware IRQ when no available space.
-       err = snd_pcm_wait(state->handle, -1);
-       if (err < 0)
-               goto error;
+       if (state->use_waiter) {
+               // Wait for hardware IRQ when no available space.
+               err = snd_pcm_wait(state->handle, -1);
+               if (err < 0)
+                       goto error;
+       }
 
        // Check available space on the buffer.
        avail = snd_pcm_avail(state->handle);
@@ -286,10 +288,12 @@ static int w_process_frames_nonblocking(struct libasound_state *state,
        unsigned int avail_count;
        int err;
 
-       // Wait for hardware IRQ when no left space.
-       err = snd_pcm_wait(state->handle, -1);
-       if (err < 0)
-               goto error;
+       if (state->use_waiter) {
+               // Wait for hardware IRQ when no left space.
+               err = snd_pcm_wait(state->handle, -1);
+               if (err < 0)
+                       goto error;
+       }
 
        // Check available space on the buffer.
        avail = snd_pcm_avail(state->handle);
index c2e128224a75cf9371426251e8accd1e67a84524..61ae11512f15d6d79b371d3a7158ab6cb0541b99 100644 (file)
@@ -12,6 +12,7 @@
 enum no_short_opts {
         // 200 or later belong to non us-ascii character set.
        OPT_FATAL_ERRORS = 200,
+       OPT_TEST_NOWAIT,
 };
 
 #define S_OPTS "D:NM"
@@ -21,6 +22,7 @@ static const struct option l_opts[] = {
        {"mmap",                0, 0, 'M'},
        // For debugging.
        {"fatal-errors",        0, 0, OPT_FATAL_ERRORS},
+       {"test-nowait",         0, 0, OPT_TEST_NOWAIT},
 };
 
 static int xfer_libasound_init(struct xfer_context *xfer,
@@ -54,6 +56,8 @@ static int xfer_libasound_parse_opt(struct xfer_context *xfer, int key,
                state->mmap = true;
        else if (key == OPT_FATAL_ERRORS)
                state->finish_at_xrun = true;
+       else if (key == OPT_TEST_NOWAIT)
+               state->test_nowait = true;
        else
                err = -ENXIO;
 
@@ -80,6 +84,15 @@ int xfer_libasound_validate_opts(struct xfer_context *xfer)
                return -EINVAL;
        }
 
+       if (state->test_nowait) {
+               if (!state->nonblock && !state->mmap) {
+                       fprintf(stderr,
+                               "An option for nowait test should be used with "
+                               "nonblock or mmap options.\n");
+                       return -EINVAL;
+               }
+       }
+
        return err;
 }
 
@@ -124,6 +137,9 @@ static int open_handle(struct xfer_context *xfer)
                return err;
        }
 
+       if ((state->nonblock || state->mmap) && !state->test_nowait)
+               state->use_waiter = true;
+
        err = snd_pcm_hw_params_any(state->handle, state->hw_params);
        if (err < 0)
                return err;
index 550b1c2a325a659cbe21e7228aa66f036b52cfde..f3ce73f142ebbf19e7faddb5392f956e4be1326c 100644 (file)
@@ -33,6 +33,9 @@ struct libasound_state {
        bool finish_at_xrun:1;
        bool nonblock:1;
        bool mmap:1;
+       bool test_nowait:1;
+
+       bool use_waiter:1;
 };
 
 // For internal use in 'libasound' module.