summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2012-06-13 14:58:49 -0700
committerGlenn Kasten <gkasten@google.com>2012-06-14 17:49:31 -0700
commit0a14c4ce1a41bc09eb7855fa531a3af629a69139 (patch)
treedfde5cdadeea7bbbdb8e50477ca35ac4768693f0
parent362ebcbf100f7fccd37551c77e67c4faa7241b63 (diff)
downloadframeworks_av-0a14c4ce1a41bc09eb7855fa531a3af629a69139.zip
frameworks_av-0a14c4ce1a41bc09eb7855fa531a3af629a69139.tar.gz
frameworks_av-0a14c4ce1a41bc09eb7855fa531a3af629a69139.tar.bz2
Make CPU frequency statistics optional
Certain CPUs with dynamic cluster swapping and hotplug don't report CPU frequency accurately. The file descriptors used to read the frequency become stale and report bogus data. So make this feature a build time option for debugging only. This will also improve performance of the fast mixer loop. Change-Id: I602f81ec3281a37992769208be08084ed1469e8c
-rw-r--r--services/audioflinger/Android.mk3
-rw-r--r--services/audioflinger/FastMixer.cpp23
-rw-r--r--services/audioflinger/FastMixer.h2
3 files changed, 24 insertions, 4 deletions
diff --git a/services/audioflinger/Android.mk b/services/audioflinger/Android.mk
index f32d90f..8473fab 100644
--- a/services/audioflinger/Android.mk
+++ b/services/audioflinger/Android.mk
@@ -84,6 +84,9 @@ LOCAL_SRC_FILES += FastMixer.cpp FastMixerState.cpp
LOCAL_CFLAGS += -DFAST_MIXER_STATISTICS
+# uncomment to display CPU load adjusted for CPU frequency
+# LOCAL_CFLAGS += -DCPU_FREQUENCY_STATISTICS
+
LOCAL_CFLAGS += -DSTATE_QUEUE_INSTANTIATIONS='"StateQueueInstantiations.cpp"'
LOCAL_CFLAGS += -DHAVE_REQUEST_PRIORITY -UFAST_TRACKS_AT_NON_NATIVE_SAMPLE_RATE -USOAKER
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index 3fe50dc..19ee9b3 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -24,8 +24,10 @@
#include <system/audio.h>
#ifdef FAST_MIXER_STATISTICS
#include <cpustats/CentralTendencyStatistics.h>
+#ifdef CPU_FREQUENCY_STATISTICS
#include <cpustats/ThreadCpuUsage.h>
#endif
+#endif
#include "AudioMixer.h"
#include "FastMixer.h"
@@ -71,8 +73,10 @@ bool FastMixer::threadLoop()
bool oldLoadValid = false; // whether oldLoad is valid
uint32_t bounds = 0;
bool full = false; // whether we have collected at least kSamplingN samples
+#ifdef CPU_FREQUENCY_STATISTICS
ThreadCpuUsage tcu; // for reading the current CPU clock frequency in kHz
#endif
+#endif
unsigned coldGen = 0; // last observed mColdGen
bool isWarm = false; // true means ready to mix, false means wait for warmup before mixing
struct timespec measuredWarmupTs = {0, 0}; // how long did it take for warmup to complete
@@ -527,16 +531,20 @@ bool FastMixer::threadLoop()
}
oldLoad = newLoad;
}
+#ifdef CPU_FREQUENCY_STATISTICS
// get the absolute value of CPU clock frequency in kHz
int cpuNum = sched_getcpu();
uint32_t kHz = tcu.getCpukHz(cpuNum);
kHz = (kHz << 4) | (cpuNum & 0xF);
+#endif
// save values in FIFO queues for dumpsys
// these stores #1, #2, #3 are not atomic with respect to each other,
// or with respect to store #4 below
dumpState->mMonotonicNs[i] = monotonicNs;
dumpState->mLoadNs[i] = loadNs;
+#ifdef CPU_FREQUENCY_STATISTICS
dumpState->mCpukHz[i] = kHz;
+#endif
// this store #4 is not atomic with respect to stores #1, #2, #3 above, but
// the newest open and oldest closed halves are atomic with respect to each other
dumpState->mBounds = bounds;
@@ -579,7 +587,9 @@ FastMixerDumpState::FastMixerDumpState() :
// so clearing reduces chance for dumpsys to read random uninitialized samples
memset(&mMonotonicNs, 0, sizeof(mMonotonicNs));
memset(&mLoadNs, 0, sizeof(mLoadNs));
+#ifdef CPU_FREQUENCY_STATISTICS
memset(&mCpukHz, 0, sizeof(mCpukHz));
+#endif
}
FastMixerDumpState::~FastMixerDumpState()
@@ -643,18 +653,20 @@ void FastMixerDumpState::dump(int fd)
}
// statistics for monotonic (wall clock) time, thread raw CPU load in time, CPU clock frequency,
// and adjusted CPU load in MHz normalized for CPU clock frequency
- CentralTendencyStatistics wall, loadNs, kHz, loadMHz;
- // only compute adjusted CPU load in Hz if current CPU number and CPU clock frequency are stable
- bool valid = false;
+ CentralTendencyStatistics wall, loadNs;
+#ifdef CPU_FREQUENCY_STATISTICS
+ CentralTendencyStatistics kHz, loadMHz;
uint32_t previousCpukHz = 0;
+#endif
// loop over all the samples
for (; n > 0; --n) {
size_t i = oldestClosed++ & (kSamplingN - 1);
uint32_t wallNs = mMonotonicNs[i];
wall.sample(wallNs);
uint32_t sampleLoadNs = mLoadNs[i];
- uint32_t sampleCpukHz = mCpukHz[i];
loadNs.sample(sampleLoadNs);
+#ifdef CPU_FREQUENCY_STATISTICS
+ uint32_t sampleCpukHz = mCpukHz[i];
// skip bad kHz samples
if ((sampleCpukHz & ~0xF) != 0) {
kHz.sample(sampleCpukHz >> 4);
@@ -665,6 +677,7 @@ void FastMixerDumpState::dump(int fd)
}
}
previousCpukHz = sampleCpukHz;
+#endif
}
fdprintf(fd, "Simple moving statistics over last %.1f seconds:\n", wall.n() * mixPeriodSec);
fdprintf(fd, " wall clock time in ms per mix cycle:\n"
@@ -674,6 +687,7 @@ void FastMixerDumpState::dump(int fd)
" mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
loadNs.mean()*1e-3, loadNs.minimum()*1e-3, loadNs.maximum()*1e-3,
loadNs.stddev()*1e-3);
+#ifdef CPU_FREQUENCY_STATISTICS
fdprintf(fd, " CPU clock frequency in MHz:\n"
" mean=%.0f min=%.0f max=%.0f stddev=%.0f\n",
kHz.mean()*1e-3, kHz.minimum()*1e-3, kHz.maximum()*1e-3, kHz.stddev()*1e-3);
@@ -681,6 +695,7 @@ void FastMixerDumpState::dump(int fd)
" mean=%.1f min=%.1f max=%.1f stddev=%.1f\n",
loadMHz.mean(), loadMHz.minimum(), loadMHz.maximum(), loadMHz.stddev());
#endif
+#endif
// The active track mask and track states are updated non-atomically.
// So if we relied on isActive to decide whether to display,
// then we might display an obsolete track or omit an active track.
diff --git a/services/audioflinger/FastMixer.h b/services/audioflinger/FastMixer.h
index 06e76d5..462739b 100644
--- a/services/audioflinger/FastMixer.h
+++ b/services/audioflinger/FastMixer.h
@@ -116,8 +116,10 @@ struct FastMixerDumpState {
// The elements in the *Ns arrays are in units of nanoseconds <= 3999999999.
uint32_t mMonotonicNs[kSamplingN]; // delta monotonic (wall clock) time
uint32_t mLoadNs[kSamplingN]; // delta CPU load in time
+#ifdef CPU_FREQUENCY_STATISTICS
uint32_t mCpukHz[kSamplingN]; // absolute CPU clock frequency in kHz, bits 0-3 are CPU#
#endif
+#endif
};
} // namespace android