Merge "audio HAL: fix thread starvation" into mnc-dr-ryu-dev
diff --git a/audio/hal/audio_hw.c b/audio/hal/audio_hw.c
index ff785b2..83a623d 100644
--- a/audio/hal/audio_hw.c
+++ b/audio/hal/audio_hw.c
@@ -1245,6 +1245,20 @@
return ret;
}
+void lock_input_stream(struct stream_in *in)
+{
+ pthread_mutex_lock(&in->pre_lock);
+ pthread_mutex_lock(&in->lock);
+ pthread_mutex_unlock(&in->pre_lock);
+}
+
+void lock_output_stream(struct stream_out *out)
+{
+ pthread_mutex_lock(&out->pre_lock);
+ pthread_mutex_lock(&out->lock);
+ pthread_mutex_unlock(&out->pre_lock);
+}
+
static int uc_release_pcm_devices(struct audio_usecase *usecase)
{
struct stream_out *out = (struct stream_out *)usecase->stream;
@@ -1629,7 +1643,7 @@
ALOGV("%s: enter: usecase(%d: %s)", __func__,
out->usecase, use_case_table[out->usecase]);
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (!out->standby) {
pthread_mutex_lock(&adev->lock);
do_out_standby_l(out);
@@ -1669,7 +1683,7 @@
if (ret >= 0) {
val = atoi(value);
pthread_mutex_lock(&adev->lock_inputs);
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
pthread_mutex_lock(&adev->lock);
if (val != 0) {
out->devices = val;
@@ -1815,7 +1829,7 @@
unsigned char *data = NULL;
struct pcm_config config;
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (out->standby) {
pthread_mutex_lock(&adev->lock);
ret = start_output_stream(out);
@@ -1932,7 +1946,7 @@
int ret = -1;
unsigned long dsp_frames;
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
/* FIXME: which device to read from? */
if (!list_empty(&out->pcm_dev_list)) {
@@ -2056,7 +2070,7 @@
{
struct audio_device *adev = in->dev;
int status = 0;
- pthread_mutex_lock(&in->lock);
+ lock_input_stream(in);
if (!in->standby) {
pthread_mutex_lock(&adev->lock);
status = do_in_standby_l(in);
@@ -2107,7 +2121,7 @@
ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
pthread_mutex_lock(&adev->lock_inputs);
- pthread_mutex_lock(&in->lock);
+ lock_input_stream(in);
pthread_mutex_lock(&adev->lock);
if (ret >= 0) {
val = atoi(value);
@@ -2202,11 +2216,11 @@
size_t frames_rq = bytes / audio_stream_in_frame_size(stream);
/* no need to acquire adev->lock_inputs because API contract prevents a close */
- pthread_mutex_lock(&in->lock);
+ lock_input_stream(in);
if (in->standby) {
pthread_mutex_unlock(&in->lock);
pthread_mutex_lock(&adev->lock_inputs);
- pthread_mutex_lock(&in->lock);
+ lock_input_stream(in);
if (!in->standby) {
pthread_mutex_unlock(&adev->lock_inputs);
goto false_alarm;
@@ -2358,6 +2372,7 @@
/* out->written = 0; by calloc() */
pthread_mutex_init(&out->lock, (const pthread_mutexattr_t *) NULL);
+ pthread_mutex_init(&out->pre_lock, (const pthread_mutexattr_t *) NULL);
pthread_cond_init(&out->cond, (const pthread_condattr_t *) NULL);
config->format = out->stream.common.get_format(&out->stream.common);
@@ -2662,6 +2677,9 @@
}
in->usecase_type = usecase_type;
+ pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
+ pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
+
*stream_in = &in->stream;
ALOGV("%s: exit", __func__);
return 0;
diff --git a/audio/hal/audio_hw.h b/audio/hal/audio_hw.h
index 775df1b..92aff51 100644
--- a/audio/hal/audio_hw.h
+++ b/audio/hal/audio_hw.h
@@ -206,6 +206,7 @@
struct stream_out {
struct audio_stream_out stream;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
+ pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by playback thread */
pthread_cond_t cond;
struct pcm_config config;
struct listnode pcm_dev_list;
@@ -234,6 +235,8 @@
struct stream_in {
struct audio_stream_in stream;
pthread_mutex_t lock; /* see note below on mutex acquisition order */
+ pthread_mutex_t pre_lock; /* acquire before lock to avoid DOS by
+ capture thread */
struct pcm_config config;
struct listnode pcm_dev_list;
int standby;