summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGlenn Kasten <gkasten@google.com>2012-05-31 07:43:43 -0700
committerGlenn Kasten <gkasten@google.com>2012-06-03 14:49:11 -0700
commit1295bb4dcff7b29c75cd23746816df12a871d72c (patch)
tree81cf673d36c8aaf3d9d51a9f372a8425ee5fa49b
parentbf0d21fb1310e8677caa53b90e8c3aecebc7fc13 (diff)
downloadframeworks_av-1295bb4dcff7b29c75cd23746816df12a871d72c.zip
frameworks_av-1295bb4dcff7b29c75cd23746816df12a871d72c.tar.gz
frameworks_av-1295bb4dcff7b29c75cd23746816df12a871d72c.tar.bz2
Fast track dumpsys
Bug: 6591648 Change-Id: I696f51c682e7233ba690d97da26012084989b412
-rw-r--r--services/audioflinger/AudioFlinger.cpp4
-rw-r--r--services/audioflinger/FastMixer.cpp39
-rw-r--r--services/audioflinger/FastMixer.h4
3 files changed, 44 insertions, 3 deletions
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index dee67d0..a61b8ea 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -1605,6 +1605,7 @@ status_t AudioFlinger::PlaybackThread::dumpInternals(int fd, const Vector<String
snprintf(buffer, SIZE, "mix buffer : %p\n", mMixBuffer);
result.append(buffer);
write(fd, result.string(), result.size());
+ fdprintf(fd, "Fast track availMask=%#x\n", mFastTrackAvailMask);
dumpBase(fd, args);
@@ -2847,7 +2848,8 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac
// Determine whether the track is currently in underrun condition,
// and whether it had a recent underrun.
- FastTrackUnderruns underruns = mFastMixerDumpState.mTracks[j].mUnderruns;
+ FastTrackDump *ftDump = &mFastMixerDumpState.mTracks[j];
+ FastTrackUnderruns underruns = ftDump->mUnderruns;
uint32_t recentFull = (underruns.mBitFields.mFull -
track->mObservedUnderruns.mBitFields.mFull) & UNDERRUN_MASK;
uint32_t recentPartial = (underruns.mBitFields.mPartial -
diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp
index b0af6ed..d8bed40 100644
--- a/services/audioflinger/FastMixer.cpp
+++ b/services/audioflinger/FastMixer.cpp
@@ -239,6 +239,7 @@ bool FastMixer::threadLoop()
// check for change in active track set
unsigned currentTrackMask = current->mTrackMask;
+ dumpState->mTrackMask = currentTrackMask;
if (current->mFastTracksGen != fastTracksGen) {
ALOG_ASSERT(mixBuffer != NULL);
int name;
@@ -387,6 +388,7 @@ bool FastMixer::threadLoop()
mixer->enable(name);
}
ftDump->mUnderruns = underruns;
+ ftDump->mFramesReady = framesReady;
}
// process() is CPU-bound
mixer->process(AudioBufferProvider::kInvalidPTS);
@@ -562,7 +564,8 @@ bool FastMixer::threadLoop()
FastMixerDumpState::FastMixerDumpState() :
mCommand(FastMixerState::INITIAL), mWriteSequence(0), mFramesWritten(0),
mNumTracks(0), mWriteErrors(0), mUnderruns(0), mOverruns(0),
- mSampleRate(0), mFrameCount(0), /* mMeasuredWarmupTs({0, 0}), */ mWarmupCycles(0)
+ mSampleRate(0), mFrameCount(0), /* mMeasuredWarmupTs({0, 0}), */ mWarmupCycles(0),
+ mTrackMask(0)
#ifdef FAST_MIXER_STATISTICS
, mBounds(0)
#endif
@@ -671,6 +674,40 @@ void FastMixerDumpState::dump(int fd)
" mean=%.1f min=%.1f max=%.1f stddev=%.1f\n",
loadMHz.mean(), loadMHz.minimum(), loadMHz.maximum(), loadMHz.stddev());
#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.
+ // Instead we always display all tracks, with an indication
+ // of whether we think the track is active.
+ uint32_t trackMask = mTrackMask;
+ fdprintf(fd, "Fast tracks: kMaxFastTracks=%u activeMask=%#x\n",
+ FastMixerState::kMaxFastTracks, trackMask);
+ fdprintf(fd, "Index Active Full Partial Empty Recent Ready\n");
+ for (uint32_t i = 0; i < FastMixerState::kMaxFastTracks; ++i, trackMask >>= 1) {
+ bool isActive = trackMask & 1;
+ const FastTrackDump *ftDump = &mTracks[i];
+ const FastTrackUnderruns& underruns = ftDump->mUnderruns;
+ const char *mostRecent;
+ switch (underruns.mBitFields.mMostRecent) {
+ case UNDERRUN_FULL:
+ mostRecent = "full";
+ break;
+ case UNDERRUN_PARTIAL:
+ mostRecent = "partial";
+ break;
+ case UNDERRUN_EMPTY:
+ mostRecent = "empty";
+ break;
+ default:
+ mostRecent = "?";
+ break;
+ }
+ fdprintf(fd, "%5u %6s %4u %7u %5u %7s %5u\n", i, isActive ? "yes" : "no",
+ (underruns.mBitFields.mFull) & UNDERRUN_MASK,
+ (underruns.mBitFields.mPartial) & UNDERRUN_MASK,
+ (underruns.mBitFields.mEmpty) & UNDERRUN_MASK,
+ mostRecent, ftDump->mFramesReady);
+ }
}
} // namespace android
diff --git a/services/audioflinger/FastMixer.h b/services/audioflinger/FastMixer.h
index e95abf6..06e76d5 100644
--- a/services/audioflinger/FastMixer.h
+++ b/services/audioflinger/FastMixer.h
@@ -72,9 +72,10 @@ private:
// Represents the dump state of a fast track
struct FastTrackDump {
- FastTrackDump() { }
+ FastTrackDump() : mFramesReady(0) { }
/*virtual*/ ~FastTrackDump() { }
FastTrackUnderruns mUnderruns;
+ size_t mFramesReady; // most recent value only; no long-term statistics kept
};
// The FastMixerDumpState keeps a cache of FastMixer statistics that can be logged by dumpsys.
@@ -100,6 +101,7 @@ struct FastMixerDumpState {
size_t mFrameCount;
struct timespec mMeasuredWarmupTs; // measured warmup time
uint32_t mWarmupCycles; // number of loop cycles required to warmup
+ uint32_t mTrackMask; // mask of active tracks
FastTrackDump mTracks[FastMixerState::kMaxFastTracks];
#ifdef FAST_MIXER_STATISTICS