diff options
author | Paul Hsia <paulhsia@google.com> | 2018-07-24 09:16:18 +0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2018-08-07 01:50:08 -0700 |
commit | 1ef46ee06cc610e139d834445837626686b41df4 (patch) | |
tree | cf03e3d0dd7c36611d92cf745c4d6903dd8dd8ee | |
parent | 62f13cff586f323f1116c81f1be3842b57e961cb (diff) | |
download | adhd-1ef46ee06cc610e139d834445837626686b41df4.tar.gz |
CRAS: Add busyloop event detection in audio_thread
Initialize audio thread monitor in cras_server.
Create a method - check_busyloop for detecting busyloop in audio thread
and take a snapshot for audio thread when busyloop occurs.
BUG=chromium:866240
TEST=audio_thread_unittest
Change-Id: Iab6a05e16e4b17d1b6740e43562bfe8c5d193ec8
Reviewed-on: https://chromium-review.googlesource.com/1148087
Commit-Ready: Chih-Yang Hsia <paulhsia@chromium.org>
Tested-by: Chih-Yang Hsia <paulhsia@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
-rw-r--r-- | cras/src/server/audio_thread.c | 23 | ||||
-rw-r--r-- | cras/src/server/cras_server.c | 3 | ||||
-rw-r--r-- | cras/src/tests/audio_thread_unittest.cc | 29 |
3 files changed, 55 insertions, 0 deletions
diff --git a/cras/src/server/audio_thread.c b/cras/src/server/audio_thread.c index 290bbff2..27f99275 100644 --- a/cras/src/server/audio_thread.c +++ b/cras/src/server/audio_thread.c @@ -14,6 +14,7 @@ #include <syslog.h> #include "audio_thread_log.h" +#include "cras_audio_thread_monitor.h" #include "cras_config.h" #include "cras_fmt_conv.h" #include "cras_iodev.h" @@ -28,6 +29,10 @@ #define MIN_PROCESS_TIME_US 500 /* 0.5ms - min amount of time to mix/src. */ #define SLEEP_FUZZ_FRAMES 10 /* # to consider "close enough" to sleep frames. */ #define MIN_READ_WAIT_US 2000 /* 2ms */ +/* + * # to check whether a busyloop event happens + */ +#define MAX_CONTINUOUS_ZERO_SLEEP_COUNT 2 /* Messages that can be sent from the main context to the audio thread. */ enum AUDIO_THREAD_COMMAND { @@ -861,6 +866,22 @@ static struct pollfd *add_pollfd(struct audio_thread *thread, return &thread->pollfds[thread->num_pollfds - 1]; } +static int continuous_zero_sleep_count = 0; +static void check_busyloop(struct timespec* wait_ts) +{ + if(wait_ts->tv_sec == 0 && wait_ts->tv_nsec == 0) + { + continuous_zero_sleep_count ++; + if(continuous_zero_sleep_count == + MAX_CONTINUOUS_ZERO_SLEEP_COUNT) + cras_audio_thread_busyloop(); + } + else + { + continuous_zero_sleep_count = 0; + } +} + /* For playback, fill the audio buffer when needed, for capture, pull out * samples when they are ready. * This thread will attempt to run at a high priority to allow for low latency @@ -947,6 +968,8 @@ restart_poll_loop: ATLOG(atlog, AUDIO_THREAD_SLEEP, wait_ts ? wait_ts->tv_sec : 0, wait_ts ? wait_ts->tv_nsec : 0, longest_wake.tv_nsec); + if(wait_ts) + check_busyloop(wait_ts); rc = ppoll(thread->pollfds, thread->num_pollfds, wait_ts, NULL); clock_gettime(CLOCK_MONOTONIC_RAW, &last_wake); ATLOG(atlog, AUDIO_THREAD_WAKE, rc, 0, 0); diff --git a/cras/src/server/cras_server.c b/cras/src/server/cras_server.c index f67ebe13..456fd1c0 100644 --- a/cras/src/server/cras_server.c +++ b/cras/src/server/cras_server.c @@ -34,6 +34,7 @@ #include "cras_telephony.h" #endif #include "cras_alert.h" +#include "cras_audio_thread_monitor.h" #include "cras_config.h" #include "cras_device_monitor.h" #include "cras_hotword_handler.h" @@ -430,6 +431,8 @@ int cras_server_run(unsigned int profile_disable_mask) cras_non_empty_audio_handler_init(); + cras_audio_thread_monitor_init(); + #ifdef CRAS_DBUS dbus_threads_init_default(); dbus_conn = cras_dbus_connect_system_bus(); diff --git a/cras/src/tests/audio_thread_unittest.cc b/cras/src/tests/audio_thread_unittest.cc index 5da25df6..1dda2e4d 100644 --- a/cras/src/tests/audio_thread_unittest.cc +++ b/cras/src/tests/audio_thread_unittest.cc @@ -14,6 +14,7 @@ extern "C" { #define BUFFER_SIZE 8192 #define FIRST_CB_LEVEL 480 +static int cras_audio_thread_busyloop_called; static unsigned int cras_rstream_dev_offset_called; static unsigned int cras_rstream_dev_offset_ret[MAX_CALLS]; static const struct cras_rstream *cras_rstream_dev_offset_rstream_val[MAX_CALLS]; @@ -690,6 +691,28 @@ TEST(AUdioThreadStreams, DrainStream) { EXPECT_EQ(0, thread_drain_stream_ms_remaining(&thread, &rstream)); } +TEST(BusyloopDetectSuite, CheckerTest) { + continuous_zero_sleep_count = 0; + cras_audio_thread_busyloop_called = 0; + timespec wait_ts; + wait_ts.tv_sec = 0; + wait_ts.tv_nsec = 0; + + check_busyloop(&wait_ts); + EXPECT_EQ(continuous_zero_sleep_count, 1); + EXPECT_EQ(cras_audio_thread_busyloop_called, 0); + check_busyloop(&wait_ts); + EXPECT_EQ(continuous_zero_sleep_count, 2); + EXPECT_EQ(cras_audio_thread_busyloop_called, 1); + check_busyloop(&wait_ts); + EXPECT_EQ(continuous_zero_sleep_count, 3); + EXPECT_EQ(cras_audio_thread_busyloop_called, 1); + + wait_ts.tv_sec = 1; + check_busyloop(&wait_ts); + EXPECT_EQ(continuous_zero_sleep_count, 0); + EXPECT_EQ(cras_audio_thread_busyloop_called, 1); +} extern "C" { @@ -1129,6 +1152,12 @@ void cras_apm_list_set_aec_dump(struct cras_apm_list *list, { } +int cras_audio_thread_busyloop() +{ + cras_audio_thread_busyloop_called ++; + return 0; +} + } // extern "C" int main(int argc, char **argv) { |