summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorManeet Singh <mmaneetsingh@nvidia.com>2015-06-16 16:04:09 -0700
committerGlenn Kasten <gkasten@google.com>2015-06-22 11:41:59 -0700
commit8f8f400335c186185bc10ae28483129d6028410c (patch)
tree3ec99d283adc52a5d3d45b91df501660686e617a
parent0094c53eba6ae36486136417def4335fe7903c71 (diff)
downloadflounder-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.c53
-rw-r--r--audio/hal/audio_hw.h3
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 {