summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Hsia <paulhsia@google.com>2018-07-24 09:16:18 +0800
committerchrome-bot <chrome-bot@chromium.org>2018-08-07 01:50:08 -0700
commit1ef46ee06cc610e139d834445837626686b41df4 (patch)
treecf03e3d0dd7c36611d92cf745c4d6903dd8dd8ee
parent62f13cff586f323f1116c81f1be3842b57e961cb (diff)
downloadadhd-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.c23
-rw-r--r--cras/src/server/cras_server.c3
-rw-r--r--cras/src/tests/audio_thread_unittest.cc29
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) {