summaryrefslogtreecommitdiffstats
path: root/services/audioflinger/FastMixer.cpp
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 /services/audioflinger/FastMixer.cpp
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
Diffstat (limited to 'services/audioflinger/FastMixer.cpp')
-rw-r--r--services/audioflinger/FastMixer.cpp23
1 files changed, 19 insertions, 4 deletions
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.