diff options
author | Maneet Singh <mmaneetsingh@nvidia.com> | 2015-06-16 16:04:09 -0700 |
---|---|---|
committer | Glenn Kasten <gkasten@google.com> | 2015-06-22 11:41:59 -0700 |
commit | 8f8f400335c186185bc10ae28483129d6028410c (patch) | |
tree | 3ec99d283adc52a5d3d45b91df501660686e617a | |
parent | 0094c53eba6ae36486136417def4335fe7903c71 (diff) | |
download | flounder-8f8f400335c186185bc10ae28483129d6028410c.tar.gz |
audio: set smp affinity for FastMixer thread on T132
On T132, IPI latency is observed to be 100's of microseconds. This
change and corresponding kernel change for APB DMA interrupts will
ensure that audio interrupt and waking thread, FastMixer, both run
on same core, thereby eliminating IPI latency altogether.
Bug: 20226809
Change-Id: I6d3b7006acfaee4d21ea7ac89ad2cce3494a99eb
-rw-r--r-- | audio/hal/audio_hw.c | 53 | ||||
-rw-r--r-- | audio/hal/audio_hw.h | 3 |
2 files changed, 56 insertions, 0 deletions
diff --git a/audio/hal/audio_hw.c b/audio/hal/audio_hw.c index 07fe9bb..30404f0 100644 --- a/audio/hal/audio_hw.c +++ b/audio/hal/audio_hw.c @@ -23,6 +23,8 @@ #define ALOGVV(a...) do { } while(0) #endif +#define _GNU_SOURCE +#include <errno.h> #include <pthread.h> #include <stdint.h> #include <sys/time.h> @@ -2942,6 +2944,29 @@ static void *tfa9895_config_thread(void *context) return NULL; } +static int fast_set_affinity(pid_t tid) { + cpu_set_t cpu_set; + int cpu_num; + const char *irq_procfs = "/proc/asound/irq_affinity"; + FILE *fp; + + if ((fp = fopen(irq_procfs, "r")) == NULL) { + ALOGW("Procfs node %s not found", irq_procfs); + return -1; + } + + if (fscanf(fp, "%d", &cpu_num) != 1) { + ALOGW("Couldn't read CPU id from procfs node %s", irq_procfs); + fclose(fp); + return -1; + } + fclose(fp); + + CPU_ZERO(&cpu_set); + CPU_SET(cpu_num, &cpu_set); + return sched_setaffinity(tid, sizeof(cpu_set), &cpu_set); +} + static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, size_t bytes) { @@ -2959,8 +2984,20 @@ static ssize_t out_write(struct audio_stream_out *stream, const void *buffer, size_t out_frames = in_frames; struct stream_in *in = NULL; #endif + pid_t tid; + int err; lock_output_stream(out); + + if (out->usecase == USECASE_AUDIO_PLAYBACK && !out->is_fastmixer_affinity_set) { + tid = gettid(); + err = fast_set_affinity(tid); + if (err < 0) { + ALOGW("Couldn't set affinity for tid %d; error %d", tid, err); + } + out->is_fastmixer_affinity_set = true; + } + if (out->standby) { #ifdef PREPROCESSING_ENABLED pthread_mutex_unlock(&out->lock); @@ -3641,9 +3678,21 @@ static ssize_t in_read(struct audio_stream_in *stream, void *buffer, int read_and_process_successful = false; size_t frames_rq = bytes / audio_stream_in_frame_size(stream); + pid_t tid; + int err; /* no need to acquire adev->lock_inputs because API contract prevents a close */ lock_input_stream(in); + + if (in->usecase == USECASE_AUDIO_CAPTURE && !in->is_fastcapture_affinity_set) { + tid = gettid(); + err = fast_set_affinity(tid); + if (err < 0) { + ALOGW("Couldn't set affinity for tid %d; error %d", tid, err); + } + in->is_fastcapture_affinity_set = true; + } + if (in->standby) { pthread_mutex_unlock(&in->lock); pthread_mutex_lock(&adev->lock_inputs); @@ -3966,6 +4015,8 @@ static int adev_open_output_stream(struct audio_hw_device *dev, config->channel_mask = out->stream.common.get_channels(&out->stream.common); config->sample_rate = out->stream.common.get_sample_rate(&out->stream.common); + out->is_fastmixer_affinity_set = false; + *stream_out = &out->stream; ALOGV("%s: exit", __func__); return 0; @@ -4283,6 +4334,8 @@ static int adev_open_input_stream(struct audio_hw_device *dev, pthread_mutex_init(&in->lock, (const pthread_mutexattr_t *) NULL); pthread_mutex_init(&in->pre_lock, (const pthread_mutexattr_t *) NULL); + in->is_fastcapture_affinity_set = false; + *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 96e84c8..14669c9 100644 --- a/audio/hal/audio_hw.h +++ b/audio/hal/audio_hw.h @@ -306,6 +306,8 @@ struct stream_out { // always modified with audio device and stream mutex locked. int32_t echo_reference_generation; #endif + + bool is_fastmixer_affinity_set; }; struct stream_in { @@ -357,6 +359,7 @@ struct stream_in { #endif struct audio_device* dev; + bool is_fastcapture_affinity_set; }; struct mixer_card { |