summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Laurent <elaurent@google.com>2015-09-22 02:30:17 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-09-22 02:30:17 +0000
commit2cb23e903de5dd2db0a45dd89a158a7eac5052bd (patch)
treeeaac20105c06bb647b38fce15408d4120ad92cd6
parente9ef478adc4690c9d074c2dc063f9dc40ef81451 (diff)
parenta1478073c18fbdecd6510452304270d2149ae5b6 (diff)
downloadandroid_hardware_qcom_audio-2cb23e903de5dd2db0a45dd89a158a7eac5052bd.tar.gz
android_hardware_qcom_audio-2cb23e903de5dd2db0a45dd89a158a7eac5052bd.tar.bz2
android_hardware_qcom_audio-2cb23e903de5dd2db0a45dd89a158a7eac5052bd.zip
am a1478073: Revert "Revert "audio HAL: fix thread starvation""
* commit 'a1478073c18fbdecd6510452304270d2149ae5b6': Revert "Revert "audio HAL: fix thread starvation""
-rw-r--r--hal/audio_hw.c55
-rw-r--r--hal/audio_hw.h2
2 files changed, 39 insertions, 18 deletions
diff --git a/hal/audio_hw.c b/hal/audio_hw.c
index 86072c0c..ca86d75b 100644
--- a/hal/audio_hw.c
+++ b/hal/audio_hw.c
@@ -849,6 +849,20 @@ error_config:
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);
+}
+
/* must be called with out->lock locked */
static int send_offload_cmd_l(struct stream_out* out, int command)
{
@@ -889,7 +903,7 @@ static void *offload_thread_loop(void *context)
prctl(PR_SET_NAME, (unsigned long)"Offload Callback", 0, 0, 0);
ALOGV("%s", __func__);
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
for (;;) {
struct offload_cmd *cmd = NULL;
stream_callback_event_t event;
@@ -948,7 +962,7 @@ static void *offload_thread_loop(void *context)
ALOGE("%s unknown command received: %d", __func__, cmd->cmd);
break;
}
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
out->offload_thread_blocked = false;
pthread_cond_signal(&out->cond);
if (send_callback) {
@@ -980,7 +994,7 @@ static int create_offload_callback_thread(struct stream_out *out)
static int destroy_offload_callback_thread(struct stream_out *out)
{
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
stop_compressed_output_l(out);
send_offload_cmd_l(out, OFFLOAD_CMD_EXIT);
@@ -1315,7 +1329,7 @@ static int out_standby(struct audio_stream *stream)
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) {
if (adev->adm_deregister_stream)
adev->adm_deregister_stream(adev->adm_data, out->handle);
@@ -1404,7 +1418,7 @@ static int out_set_parameters(struct audio_stream *stream, const char *kvpairs)
ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_ROUTING, value, sizeof(value));
if (ret >= 0) {
val = atoi(value);
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
pthread_mutex_lock(&adev->lock);
/*
@@ -1568,7 +1582,7 @@ static ssize_t out_write_for_no_output(struct audio_stream_out *stream,
/* No Output device supported other than BT for playback.
* Sleep for the amount of buffer duration
*/
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
usleep(bytes * 1000000 / audio_stream_frame_size(&out->stream.common) /
out_get_sample_rate(&out->stream.common));
pthread_mutex_unlock(&out->lock);
@@ -1583,7 +1597,7 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer,
struct audio_device *adev = out->dev;
ssize_t ret = 0;
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (out->standby) {
out->standby = false;
pthread_mutex_lock(&adev->lock);
@@ -1660,7 +1674,7 @@ static int out_get_render_position(const struct audio_stream_out *stream,
struct stream_out *out = (struct stream_out *)stream;
*dsp_frames = 0;
if ((out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) && (dsp_frames != NULL)) {
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (out->compr != NULL) {
compress_get_tstamp(out->compr, (unsigned long *)dsp_frames,
&out->sample_rate);
@@ -1698,7 +1712,7 @@ static int out_get_presentation_position(const struct audio_stream_out *stream,
int ret = -1;
unsigned long dsp_frames;
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
if (out->compr != NULL) {
@@ -1742,7 +1756,7 @@ static int out_set_callback(struct audio_stream_out *stream,
struct stream_out *out = (struct stream_out *)stream;
ALOGV("%s", __func__);
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
out->offload_callback = callback;
out->offload_cookie = cookie;
pthread_mutex_unlock(&out->lock);
@@ -1755,7 +1769,7 @@ static int out_pause(struct audio_stream_out* stream)
int status = -ENOSYS;
ALOGV("%s", __func__);
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PLAYING) {
status = compress_pause(out->compr);
out->offload_state = OFFLOAD_STATE_PAUSED;
@@ -1772,7 +1786,7 @@ static int out_resume(struct audio_stream_out* stream)
ALOGV("%s", __func__);
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
status = 0;
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (out->compr != NULL && out->offload_state == OFFLOAD_STATE_PAUSED) {
status = compress_resume(out->compr);
out->offload_state = OFFLOAD_STATE_PLAYING;
@@ -1788,7 +1802,7 @@ static int out_drain(struct audio_stream_out* stream, audio_drain_type_t type )
int status = -ENOSYS;
ALOGV("%s", __func__);
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
if (type == AUDIO_DRAIN_EARLY_NOTIFY)
status = send_offload_cmd_l(out, OFFLOAD_CMD_PARTIAL_DRAIN);
else
@@ -1803,7 +1817,7 @@ static int out_flush(struct audio_stream_out* stream)
struct stream_out *out = (struct stream_out *)stream;
ALOGV("%s", __func__);
if (out->usecase == USECASE_AUDIO_PLAYBACK_OFFLOAD) {
- pthread_mutex_lock(&out->lock);
+ lock_output_stream(out);
stop_compressed_output_l(out);
pthread_mutex_unlock(&out->lock);
return 0;
@@ -1855,7 +1869,8 @@ static int in_standby(struct audio_stream *stream)
struct audio_device *adev = in->dev;
int status = 0;
ALOGV("%s: enter", __func__);
- pthread_mutex_lock(&in->lock);
+
+ lock_input_stream(in);
if (!in->standby && in->is_st_session) {
ALOGD("%s: sound trigger pcm stop lab", __func__);
@@ -1903,7 +1918,8 @@ static int in_set_parameters(struct audio_stream *stream, const char *kvpairs)
ret = str_parms_get_str(parms, AUDIO_PARAMETER_STREAM_INPUT_SOURCE, value, sizeof(value));
- pthread_mutex_lock(&in->lock);
+ lock_input_stream(in);
+
pthread_mutex_lock(&adev->lock);
if (ret >= 0) {
val = atoi(value);
@@ -1951,7 +1967,8 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer,
struct audio_device *adev = in->dev;
int i, ret = -1;
- pthread_mutex_lock(&in->lock);
+ lock_input_stream(in);
+
if (in->is_st_session) {
ALOGVV(" %s: reading on st session bytes=%d", __func__, bytes);
/* Read from sound trigger HAL */
@@ -2023,7 +2040,7 @@ static int add_remove_audio_effect(const struct audio_stream *stream,
if (status != 0)
return status;
- pthread_mutex_lock(&in->lock);
+ lock_input_stream(in);
pthread_mutex_lock(&in->dev->lock);
if ((in->source == AUDIO_SOURCE_VOICE_COMMUNICATION) &&
in->enable_aec != enable &&
@@ -2274,6 +2291,7 @@ static int adev_open_output_stream(struct audio_hw_device *dev,
/* 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);
@@ -2521,6 +2539,7 @@ static int adev_open_input_stream(struct audio_hw_device *dev,
in = (struct stream_in *)calloc(1, sizeof(struct stream_in));
pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL);
+ pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL);
in->stream.common.get_sample_rate = in_get_sample_rate;
in->stream.common.set_sample_rate = in_set_sample_rate;
diff --git a/hal/audio_hw.h b/hal/audio_hw.h
index e6ce5dcb..8c07b6d5 100644
--- a/hal/audio_hw.h
+++ b/hal/audio_hw.h
@@ -125,6 +125,7 @@ struct offload_cmd {
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 compr_config compr_config;
@@ -163,6 +164,7 @@ struct stream_out {
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 pcm *pcm;
int standby;