diff options
author | Wu-Cheng Li <wuchengli@google.com> | 2017-11-08 22:24:13 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-11-09 07:46:33 -0800 |
commit | 6991c5aac3411ec5b4b12e3f48c05d1b06fd8cf1 (patch) | |
tree | c057055f1fc6c34af5ce2ec2e9c7968c2e814b12 | |
parent | 375868455a36cbdaf632bc8c5ab937dc0aba0eb8 (diff) | |
download | adhd-6991c5aac3411ec5b4b12e3f48c05d1b06fd8cf1.tar.gz |
CRAS: alsa-plugin - remove snd_pcm_cras_delay
PCM functions became thread-safe in 1.1.2. Some functions like
snd_pcm_delay and snd_pcm_sw_params_current will hold a lock.
snd_pcm_cras_delay is called by snd_pcm_delay, but
snd_pcm_cras_delay calls snd_pcm_sw_params_current. This causes
a deadlock.
There are several options that are not good:
(1) Define --disable-thread-safety in alsa-lib. This will be
inconsistent with upstream alsa-lib.
(2) Set snd_pcm_t.need_lock=0. need_lock is in pcm_local.h
and it's not easy to build with it. Also, need_lock means
the plugin is thread safe and doesn't need locking in
alsa-lib. Our plugin is not thread safe.
(3) Not to call snd_pcm_sw_params_current in snd_pcm_cras_delay.
Calling snd_pcm_sw_params_current in .start introduces a
similar deadlock. Also it's more accurate to get the latest
boundary in .delay.
I don't see a good solution. Let's remove snd_pcm_cras_delay.
BUG=chromium:779936
TEST=Run loopback_latency -n 4000 and it does not hang.
Change-Id: I69b143aee2e95f8ef8f1a2c0f1604064255d0017
Reviewed-on: https://chromium-review.googlesource.com/758796
Commit-Ready: Wu-Cheng Li <wuchengli@chromium.org>
Tested-by: Wu-Cheng Li <wuchengli@chromium.org>
Reviewed-by: Cheng-Yi Chiang <cychiang@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
-rw-r--r-- | cras/src/alsa_plugin/pcm_cras.c | 86 |
1 files changed, 0 insertions, 86 deletions
diff --git a/cras/src/alsa_plugin/pcm_cras.c b/cras/src/alsa_plugin/pcm_cras.c index 93b61a31..5591a115 100644 --- a/cras/src/alsa_plugin/pcm_cras.c +++ b/cras/src/alsa_plugin/pcm_cras.c @@ -228,29 +228,6 @@ static int snd_pcm_cras_prepare(snd_pcm_ioplug_t *io) return cras_client_connect(pcm_cras->client); } -/* Get the pcm boundary value. */ -static int get_boundary(snd_pcm_t *pcm, snd_pcm_uframes_t *boundary) -{ - snd_pcm_sw_params_t *sw_params; - int rc; - - snd_pcm_sw_params_alloca(&sw_params); - - rc = snd_pcm_sw_params_current(pcm, sw_params); - if (rc < 0) { - fprintf(stderr, "sw_params_current: %s\n", snd_strerror(rc)); - return rc; - } - - rc = snd_pcm_sw_params_get_boundary(sw_params, boundary); - if (rc < 0) { - fprintf(stderr, "get_boundary: %s\n", snd_strerror(rc)); - return rc; - } - - return 0; -} - /* Called when an ALSA stream is started. */ static int snd_pcm_cras_start(snd_pcm_ioplug_t *io) { @@ -300,71 +277,8 @@ error_out: return rc; } -static int snd_pcm_cras_delay(snd_pcm_ioplug_t *io, snd_pcm_sframes_t *delayp) -{ - snd_pcm_uframes_t limit; - int rc; - struct snd_pcm_cras *pcm_cras; - struct timespec latency; - - pcm_cras = (struct snd_pcm_cras *)io->private_data; - - rc = get_boundary(io->pcm, &limit); - if ((rc < 0) || (limit == 0)) { - *delayp = 0; - return -EINVAL; - } - - /* To get the delay, first calculate the latency between now and the - * playback/capture sample time for the old hw_ptr we tracked, note that - * for playback path this latency could be negative. Then add it up with - * the difference between appl_ptr and the old hw_ptr. - */ - if (io->stream == SND_PCM_STREAM_PLAYBACK) { - /* Do not compute latency if playback_sample_time is not set */ - if (pcm_cras->playback_sample_time.tv_sec == 0 && - pcm_cras->playback_sample_time.tv_nsec == 0) { - latency.tv_sec = 0; - latency.tv_nsec = 0; - } else { - cras_client_calc_playback_latency( - &pcm_cras->playback_sample_time, - &latency); - } - - *delayp = limit + - io->appl_ptr - - pcm_cras->playback_sample_index + - latency.tv_sec * io->rate + - latency.tv_nsec / (1000000000L / (long)io->rate); - } else { - /* Do not compute latency if capture_sample_time is not set */ - if (pcm_cras->capture_sample_time.tv_sec == 0 && - pcm_cras->capture_sample_time.tv_nsec == 0) { - latency.tv_sec = 0; - latency.tv_nsec = 0; - } else { - cras_client_calc_capture_latency( - &pcm_cras->capture_sample_time, - &latency); - } - - *delayp = limit + - pcm_cras->capture_sample_index - - io->appl_ptr + - latency.tv_sec * io->rate + - latency.tv_nsec / (1000000000L / (long)io->rate); - } - - /* Both appl and hw pointers wrap at the pcm boundary. */ - *delayp %= limit; - - return 0; -} - static snd_pcm_ioplug_callback_t cras_pcm_callback = { .close = snd_pcm_cras_close, - .delay = snd_pcm_cras_delay, .start = snd_pcm_cras_start, .stop = snd_pcm_cras_stop, .pointer = snd_pcm_cras_pointer, |