From 08725b7c1f376ff93bdaf374dadaf7bf477fcb13 Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Wed, 13 Feb 2013 14:46:45 -0800 Subject: [PATCH] Temporary additional logging to investigate bug The bug appears related to continuing to use an invalid buffer provider in fast mixer after track destruction, so focus the added logs in that area. Also includes a bug fix: was calling log in an unsafe place near Threads.cpp AudioFlinger::PlaybackThread::createTrack_l line 1250. Details: - include caller pid or client pid where appropriate - increase log buffer size - log mFastIndex when AudioMixer sees an invalid bufferProvider. - log both potentially modified and actually modified tracks in FastMixer. - fix benign bug where sq->end() was called more than once. - log StateQueue push() call and return. - increase StateQueue size from 4 to 8 entries - log mixer->enable(), bufferProvider, and currentTrackMask - log buffer provider addresses - increase fast mixer log buffer again - check logf format vs. argument list compatibility - add logging to AudioMixer - add checking of magic field in AudioMixer to detect overwrites - add bool AudioMixer::enabled() Bug: 6490974 Change-Id: I1f3f18aa62d9fbd35bc32285b669f5ba40efe28e --- include/media/nbaio/NBLog.h | 4 ++-- services/audioflinger/AudioFlinger.h | 2 +- services/audioflinger/AudioMixer.cpp | 46 +++++++++++++++++++++++++++++++++--- services/audioflinger/AudioMixer.h | 22 +++++++++++++++-- services/audioflinger/FastMixer.cpp | 45 +++++++++++++++++++++++++++++++++-- services/audioflinger/StateQueue.h | 2 +- services/audioflinger/Threads.cpp | 30 ++++++++++++++++++----- services/audioflinger/Threads.h | 4 ++-- services/audioflinger/Tracks.cpp | 14 +++++++---- 9 files changed, 146 insertions(+), 23 deletions(-) diff --git a/include/media/nbaio/NBLog.h b/include/media/nbaio/NBLog.h index 8fc417f9f2..107ba66fb9 100644 --- a/include/media/nbaio/NBLog.h +++ b/include/media/nbaio/NBLog.h @@ -115,7 +115,7 @@ public: virtual ~Writer() { } virtual void log(const char *string); - virtual void logf(const char *fmt, ...); + virtual void logf(const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); virtual void logvf(const char *fmt, va_list ap); virtual void logTimestamp(); virtual void logTimestamp(const struct timespec& ts); @@ -149,7 +149,7 @@ public: LockedWriter(size_t size, void *shared); virtual void log(const char *string); - virtual void logf(const char *fmt, ...); + virtual void logf(const char *fmt, ...) __attribute__ ((format (printf, 2, 3))); virtual void logvf(const char *fmt, va_list ap); virtual void logTimestamp(); virtual void logTimestamp(const struct timespec& ts); diff --git a/services/audioflinger/AudioFlinger.h b/services/audioflinger/AudioFlinger.h index c3f08f64ba..e8852fbd7a 100644 --- a/services/audioflinger/AudioFlinger.h +++ b/services/audioflinger/AudioFlinger.h @@ -227,7 +227,7 @@ public: sp newWriter_l(size_t size, const char *name); void unregisterWriter(const sp& writer); private: - static const size_t kLogMemorySize = 10 * 1024; + static const size_t kLogMemorySize = 30 * 1024; sp mLogMemoryDealer; // == 0 when NBLog is disabled public: diff --git a/services/audioflinger/AudioMixer.cpp b/services/audioflinger/AudioMixer.cpp index 08325ad939..529d1b579d 100644 --- a/services/audioflinger/AudioMixer.cpp +++ b/services/audioflinger/AudioMixer.cpp @@ -98,7 +98,7 @@ effect_descriptor_t AudioMixer::dwnmFxDesc; AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTracks) : mTrackNames(0), mConfiguredNames((maxNumTracks >= 32 ? 0 : 1 << maxNumTracks) - 1), - mSampleRate(sampleRate) + mSampleRate(sampleRate), mLog(&mDummyLog) { // AudioMixer is not yet capable of multi-channel beyond stereo COMPILE_TIME_ASSERT_FUNCTION_SCOPE(2 == MAX_NUM_CHANNELS); @@ -122,6 +122,7 @@ AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTr mState.hook = process__nop; mState.outputTemp = NULL; mState.resampleTemp = NULL; + mState.mLog = &mDummyLog; // mState.reserved // FIXME Most of the following initialization is probably redundant since @@ -131,6 +132,7 @@ AudioMixer::AudioMixer(size_t frameCount, uint32_t sampleRate, uint32_t maxNumTr for (unsigned i=0 ; i < MAX_NUM_TRACKS ; i++) { t->resampler = NULL; t->downmixerBufferProvider = NULL; + t->magic = track_t::kMagic; t++; } @@ -169,6 +171,12 @@ AudioMixer::~AudioMixer() delete [] mState.resampleTemp; } +void AudioMixer::setLog(NBLog::Writer *log) +{ + mLog = log; + mState.mLog = log; +} + int AudioMixer::getTrackName(audio_channel_mask_t channelMask, int sessionId) { uint32_t names = (~mTrackNames) & mConfiguredNames; @@ -209,9 +217,12 @@ int AudioMixer::getTrackName(audio_channel_mask_t channelMask, int sessionId) t->mainBuffer = NULL; t->auxBuffer = NULL; t->downmixerBufferProvider = NULL; + t->fastIndex = -1; + // t->magic unchanged status_t status = initTrackDownmix(&mState.tracks[n], n, channelMask); if (status == OK) { + mLog->logf("getTrackName %d", n); return TRACK0 + n; } ALOGE("AudioMixer::getTrackName(0x%x) failed, error preparing track for downmix", @@ -366,9 +377,11 @@ void AudioMixer::deleteTrackName(int name) { ALOGV("AudioMixer::deleteTrackName(%d)", name); name -= TRACK0; + mLog->logf("deleteTrackName %d", name); ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); ALOGV("deleteTrackName(%d)", name); track_t& track(mState.tracks[ name ]); + track.checkMagic(); if (track.enabled) { track.enabled = false; invalidateState(1<logf("enable %d", name); track.enabled = true; ALOGV("enable(%d)", name); invalidateState(1 << name); @@ -400,19 +415,32 @@ void AudioMixer::disable(int name) name -= TRACK0; ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); track_t& track = mState.tracks[name]; + track.checkMagic(); if (track.enabled) { + mLog->logf("disable %d", name); track.enabled = false; ALOGV("disable(%d)", name); invalidateState(1 << name); } } +bool AudioMixer::enabled(int name) +{ + name -= TRACK0; + ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); + track_t& track = mState.tracks[name]; + track.checkMagic(); + + return track.enabled; +} + void AudioMixer::setParameter(int name, int target, int param, void *value) { name -= TRACK0; ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); track_t& track = mState.tracks[name]; + track.checkMagic(); int valueInt = (int)value; int32_t *valueBuf = (int32_t *)value; @@ -455,6 +483,9 @@ void AudioMixer::setParameter(int name, int target, int param, void *value) // for a specific track? or per mixer? /* case DOWNMIX_TYPE: break */ + case FAST_INDEX: + track.fastIndex = valueInt; + break; default: LOG_FATAL("bad param"); } @@ -540,6 +571,7 @@ void AudioMixer::setParameter(int name, int target, int param, void *value) bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate) { + checkMagic(); if (value != devSampleRate || resampler != NULL) { if (sampleRate != value) { sampleRate = value; @@ -572,6 +604,7 @@ bool AudioMixer::track_t::setResampler(uint32_t value, uint32_t devSampleRate) inline void AudioMixer::track_t::adjustVolumeRamp(bool aux) { + checkMagic(); for (uint32_t i=0 ; i0) && (((prevVolume[i]+volumeInc[i])>>16) >= volume[i])) || ((volumeInc[i]<0) && (((prevVolume[i]+volumeInc[i])>>16) <= volume[i]))) { @@ -600,8 +633,10 @@ size_t AudioMixer::getUnreleasedFrames(int name) const void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider) { name -= TRACK0; + mLog->logf("bp %d-%p", name, bufferProvider); ALOG_ASSERT(uint32_t(name) < MAX_NUM_TRACKS, "bad track name %d", name); + mState.tracks[name].checkMagic(); if (mState.tracks[name].downmixerBufferProvider != NULL) { // update required? if (mState.tracks[name].downmixerBufferProvider->mTrackBufferProvider != bufferProvider) { @@ -623,6 +658,9 @@ void AudioMixer::setBufferProvider(int name, AudioBufferProvider* bufferProvider void AudioMixer::process(int64_t pts) { + if (mState.needsChanged) { + mLog->logf("process needs=%#x", mState.needsChanged); + } mState.hook(&mState, pts); } @@ -647,6 +685,7 @@ void AudioMixer::process__validate(state_t* state, int64_t pts) } state->enabledTracks &= ~disabled; state->enabledTracks |= enabled; + state->mLog->logf("process_validate ena=%#x", state->enabledTracks); // compute everything we need... int countActiveTracks = 0; @@ -1103,6 +1142,7 @@ void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts) // acquire each track's buffer uint32_t enabledTracks = state->enabledTracks; + state->mLog->logf("process_gNR ena=%#x", enabledTracks); uint32_t e0 = enabledTracks; while (e0) { const int i = 31 - __builtin_clz(e0); @@ -1111,8 +1151,8 @@ void AudioMixer::process__genericNoResampling(state_t* state, int64_t pts) t.buffer.frameCount = state->frameCount; int valid = t.bufferProvider->getValid(); if (valid != AudioBufferProvider::kValid) { - ALOGE("invalid bufferProvider=%p name=%d frameCount=%d valid=%#x enabledTracks=%#x", - t.bufferProvider, i, t.buffer.frameCount, valid, enabledTracks); + ALOGE("invalid bufferProvider=%p name=%d fastIndex=%d frameCount=%d valid=%#x enabledTracks=%#x", + t.bufferProvider, i, t.fastIndex, t.buffer.frameCount, valid, enabledTracks); // expect to crash } t.bufferProvider->getNextBuffer(&t.buffer, pts); diff --git a/services/audioflinger/AudioMixer.h b/services/audioflinger/AudioMixer.h index fd21fda013..f0ccd8e252 100644 --- a/services/audioflinger/AudioMixer.h +++ b/services/audioflinger/AudioMixer.h @@ -28,6 +28,7 @@ #include #include +#include namespace android { @@ -76,6 +77,7 @@ public: MAIN_BUFFER = 0x4002, AUX_BUFFER = 0x4003, DOWNMIX_TYPE = 0X4004, + FAST_INDEX = 0x4005, // for debugging only // for target RESAMPLE SAMPLE_RATE = 0x4100, // Configure sample rate conversion on this track name; // parameter 'value' is the new sample rate in Hz. @@ -106,6 +108,7 @@ public: // Enable or disable an allocated track by name void enable(int name); void disable(int name); + bool enabled(int name); void setParameter(int name, int target, int param, void *value); @@ -200,7 +203,10 @@ private: int32_t sessionId; - int32_t padding[2]; + int32_t fastIndex; + int32_t magic; + static const int kMagic = 0x54637281; + //int32_t padding[1]; // 16-byte boundary @@ -210,6 +216,12 @@ private: void adjustVolumeRamp(bool aux); size_t getUnreleasedFrames() const { return resampler != NULL ? resampler->getUnreleasedFrames() : 0; }; + void checkMagic() { + if (magic != kMagic) { + ALOGE("magic=%#x fastIndex=%d", magic, fastIndex); + } + } + }; // pad to 32-bytes to fill cache line @@ -220,7 +232,8 @@ private: void (*hook)(state_t* state, int64_t pts); // one of process__*, never NULL int32_t *outputTemp; int32_t *resampleTemp; - int32_t reserved[2]; + NBLog::Writer* mLog; + int32_t reserved[1]; // FIXME allocate dynamically to save some memory when maxNumTracks < MAX_NUM_TRACKS track_t tracks[MAX_NUM_TRACKS]; __attribute__((aligned(32))); }; @@ -247,6 +260,11 @@ private: const uint32_t mSampleRate; + NBLog::Writer* mLog; + NBLog::Writer mDummyLog; +public: + void setLog(NBLog::Writer* log); +private: state_t mState __attribute__((aligned(32))); // effect descriptor for the downmixer used by the mixer diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp index 80e37ca3ac..5811771f4f 100644 --- a/services/audioflinger/FastMixer.cpp +++ b/services/audioflinger/FastMixer.cpp @@ -120,12 +120,16 @@ bool FastMixer::threadLoop() FastMixerState::Command command = next->mCommand; if (next != current) { + logWriter->logTimestamp(); logWriter->log("next != current"); // As soon as possible of learning of a new dump area, start using it dumpState = next->mDumpState != NULL ? next->mDumpState : &dummyDumpState; teeSink = next->mTeeSink; logWriter = next->mNBLogWriter != NULL ? next->mNBLogWriter : &dummyLogWriter; + if (mixer != NULL) { + mixer->setLog(logWriter); + } // We want to always have a valid reference to the previous (non-idle) state. // However, the state queue only guarantees access to current and previous states. @@ -300,13 +304,21 @@ bool FastMixer::threadLoop() addedTracks &= ~(1 << i); const FastTrack* fastTrack = ¤t->mFastTracks[i]; AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider; + logWriter->logf("bp %d i=%d %p", __LINE__, i, bufferProvider); ALOG_ASSERT(bufferProvider != NULL && fastTrackNames[i] == -1); + if (bufferProvider == NULL || + bufferProvider->getValid() != AudioBufferProvider::kValid) { + logWriter->logTimestamp(); + logWriter->logf("added invalid %#x", i); + } if (mixer != NULL) { // calling getTrackName with default channel mask and a random invalid // sessionId (no effects here) name = mixer->getTrackName(AUDIO_CHANNEL_OUT_STEREO, -555); ALOG_ASSERT(name >= 0); fastTrackNames[i] = name; + mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FAST_INDEX, + (void *) i); mixer->setBufferProvider(name, bufferProvider); mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::MAIN_BUFFER, (void *) mixBuffer); @@ -317,27 +329,40 @@ bool FastMixer::threadLoop() } mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::CHANNEL_MASK, (void *) fastTrack->mChannelMask); + if (!mixer->enabled(name)) { + logWriter->logf("enable %d i=%d name=%d", __LINE__, i, name); + } mixer->enable(name); } generations[i] = fastTrack->mGeneration; } - // finally process modified tracks; these use the same slot + // finally process (potentially) modified tracks; these use the same slot // but may have a different buffer provider or volume provider unsigned modifiedTracks = currentTrackMask & previousTrackMask; if (modifiedTracks) { - logWriter->logf("modified %#x", modifiedTracks); + logWriter->logf("pot. mod. %#x", modifiedTracks); } + unsigned actuallyModifiedTracks = 0; while (modifiedTracks != 0) { i = __builtin_ctz(modifiedTracks); modifiedTracks &= ~(1 << i); const FastTrack* fastTrack = ¤t->mFastTracks[i]; if (fastTrack->mGeneration != generations[i]) { + actuallyModifiedTracks |= 1 << i; AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider; + logWriter->logf("bp %d i=%d %p", __LINE__, i, bufferProvider); ALOG_ASSERT(bufferProvider != NULL); + if (bufferProvider == NULL || + bufferProvider->getValid() != AudioBufferProvider::kValid) { + logWriter->logTimestamp(); + logWriter->logf("modified invalid %#x", i); + } if (mixer != NULL) { name = fastTrackNames[i]; ALOG_ASSERT(name >= 0); + mixer->setParameter(name, AudioMixer::TRACK, AudioMixer::FAST_INDEX, + (void *) i); mixer->setBufferProvider(name, bufferProvider); if (fastTrack->mVolumeProvider == NULL) { mixer->setParameter(name, AudioMixer::VOLUME, AudioMixer::VOLUME0, @@ -360,6 +385,9 @@ bool FastMixer::threadLoop() generations[i] = fastTrack->mGeneration; } } + if (actuallyModifiedTracks) { + logWriter->logf("act. mod. %#x", actuallyModifiedTracks); + } fastTracksGen = current->mFastTracksGen; @@ -377,6 +405,7 @@ bool FastMixer::threadLoop() ALOG_ASSERT(mixBuffer != NULL); // for each track, update volume and check for underrun unsigned currentTrackMask = current->mTrackMask; + logWriter->logf("ctm %#x", currentTrackMask); while (currentTrackMask != 0) { i = __builtin_ctz(currentTrackMask); currentTrackMask &= ~(1 << i); @@ -414,15 +443,27 @@ bool FastMixer::threadLoop() // allow mixing partial buffer underruns.mBitFields.mPartial++; underruns.mBitFields.mMostRecent = UNDERRUN_PARTIAL; + if (!mixer->enabled(name)) { + logWriter->logf("enable %d i=%d name=%d", __LINE__, i, name); + } mixer->enable(name); } } else { underruns.mBitFields.mFull++; underruns.mBitFields.mMostRecent = UNDERRUN_FULL; + if (!mixer->enabled(name)) { + logWriter->logf("enable %d i=%d name=%d", __LINE__, i, name); + } mixer->enable(name); } ftDump->mUnderruns = underruns; ftDump->mFramesReady = framesReady; + AudioBufferProvider *bufferProvider = fastTrack->mBufferProvider; + if (bufferProvider == NULL || + bufferProvider->getValid() != AudioBufferProvider::kValid) { + logWriter->logTimestamp(); + logWriter->logf("mixing invalid %#x", i); + } } int64_t pts; diff --git a/services/audioflinger/StateQueue.h b/services/audioflinger/StateQueue.h index e33b3c64e4..313330f2ba 100644 --- a/services/audioflinger/StateQueue.h +++ b/services/audioflinger/StateQueue.h @@ -174,7 +174,7 @@ public: #endif private: - static const unsigned kN = 4; // values < 4 are not supported by this code + static const unsigned kN = 8; // values < 4 are not supported by this code T mStates[kN]; // written by mutator, read by observer // "volatile" is meaningless with SMP, but here it indicates that we're using atomic ops diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp index ba848d7ec5..a19c5f46ed 100644 --- a/services/audioflinger/Threads.cpp +++ b/services/audioflinger/Threads.cpp @@ -1196,6 +1196,8 @@ sp AudioFlinger::PlaybackThread::createTrac { // scope for mLock Mutex::Autolock _l(mLock); + mNBLogWriter->logf("createTrack_l isFast=%d caller=%d", + (*flags & IAudioFlinger::TRACK_FAST) != 0, IPCThreadState::self()->getCallingPid()); // all tracks in same audio session must share the same routing strategy otherwise // conflicts will happen when tracks are moved from one output to another by audio policy @@ -1249,7 +1251,6 @@ Exit: if (status) { *status = lStatus; } - mNBLogWriter->logf("createTrack_l"); return track; } @@ -1317,7 +1318,8 @@ float AudioFlinger::PlaybackThread::streamVolume(audio_stream_type_t stream) con // addTrack_l() must be called with ThreadBase::mLock held status_t AudioFlinger::PlaybackThread::addTrack_l(const sp& track) { - mNBLogWriter->logf("addTrack_l mName=%d", track->mName); + mNBLogWriter->logf("addTrack_l mName=%d mFastIndex=%d caller=%d", track->mName, + track->mFastIndex, IPCThreadState::self()->getCallingPid()); status_t status = ALREADY_EXISTS; // set retry count for buffer fill @@ -1351,7 +1353,9 @@ status_t AudioFlinger::PlaybackThread::addTrack_l(const sp& track) // destroyTrack_l() must be called with ThreadBase::mLock held void AudioFlinger::PlaybackThread::destroyTrack_l(const sp& track) { - mNBLogWriter->logf("destroyTrack_l mName=%d", track->mName); + mNBLogWriter->logTimestamp(); + mNBLogWriter->logf("destroyTrack_l mName=%d mFastIndex=%d mClientPid=%d", track->mName, + track->mFastIndex, track->mClient != 0 ? track->mClient->pid() : -1); track->mState = TrackBase::TERMINATED; // active tracks are removed by threadLoop() if (mActiveTracks.indexOf(track) < 0) { @@ -1361,7 +1365,9 @@ void AudioFlinger::PlaybackThread::destroyTrack_l(const sp& track) void AudioFlinger::PlaybackThread::removeTrack_l(const sp& track) { - mNBLogWriter->logf("removeTrack_l mName=%d", track->mName); + mNBLogWriter->logTimestamp(); + mNBLogWriter->logf("removeTrack_l mName=%d mFastIndex=%d clientPid=%d", track->mName, + track->mFastIndex, track->mClient != 0 ? track->mClient->pid() : -1); track->triggerEvents(AudioSystem::SYNC_EVENT_PRESENTATION_COMPLETE); mTracks.remove(track); deleteTrackName_l(track->name()); @@ -2149,6 +2155,7 @@ AudioFlinger::MixerThread::MixerThread(const sp& audioFlinger, Aud FastTrack *fastTrack = &state->mFastTracks[0]; // wrap the source side of the MonoPipe to make it an AudioBufferProvider fastTrack->mBufferProvider = new SourceAudioBufferProvider(new MonoPipeReader(monoPipe)); + mNBLogWriter->logf("ft0 bp %p", fastTrack->mBufferProvider); fastTrack->mVolumeProvider = NULL; fastTrack->mGeneration++; state->mFastTracksGen++; @@ -2553,6 +2560,7 @@ AudioFlinger::PlaybackThread::mixer_state AudioFlinger::MixerThread::prepareTrac // was it previously inactive? if (!(state->mTrackMask & (1 << j))) { ExtendedAudioBufferProvider *eabp = track; + mNBLogWriter->logf("j=%d bp %p", j, eabp); VolumeProvider *vp = track; fastTrack->mBufferProvider = eabp; fastTrack->mVolumeProvider = vp; @@ -2839,11 +2847,19 @@ track_is_ready: ; block = FastMixerStateQueue::BLOCK_UNTIL_ACKED; pauseAudioWatchdog = true; } - sq->end(); } if (sq != NULL) { + unsigned trackMask = state->mTrackMask; sq->end(didModify); + if (didModify) { + mNBLogWriter->logTimestamp(); + mNBLogWriter->logf("push trackMask=%#x block=%d", trackMask, block); + } sq->push(block); + if (didModify) { + mNBLogWriter->logTimestamp(); + mNBLogWriter->log("pushed"); + } } #ifdef AUDIO_WATCHDOG if (pauseAudioWatchdog && mAudioWatchdog != 0) { @@ -2870,7 +2886,9 @@ track_is_ready: ; if (CC_UNLIKELY(count)) { for (size_t i=0 ; i& track = tracksToRemove->itemAt(i); - mNBLogWriter->logf("prepareTracks_l remove name=%u", track->name()); + mNBLogWriter->logTimestamp(); + mNBLogWriter->logf("prepareTracks_l remove name=%u mFastIndex=%d", track->name(), + track->mFastIndex); mActiveTracks.remove(track); if (track->mainBuffer() != mMixBuffer) { chain = getEffectChain_l(track->sessionId()); diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h index fa1e3364a8..3cd5c2cf33 100644 --- a/services/audioflinger/Threads.h +++ b/services/audioflinger/Threads.h @@ -315,7 +315,7 @@ protected: // keyed by session ID, the second by type UUID timeLow field KeyedVector< int, KeyedVector< int, sp > > mSuspendedSessions; - static const size_t kLogSize = 512; + static const size_t kLogSize = 4096; sp mNBLogWriter; }; @@ -546,7 +546,7 @@ private: sp mTeeSink; sp mTeeSource; uint32_t mScreenState; // cached copy of gScreenState - static const size_t kFastMixerLogSize = 8 * 1024; + static const size_t kFastMixerLogSize = 16 * 1024; sp mFastMixerNBLogWriter; public: virtual bool hasFastMixer() const = 0; diff --git a/services/audioflinger/Tracks.cpp b/services/audioflinger/Tracks.cpp index 315cbbcd61..f679751c3e 100644 --- a/services/audioflinger/Tracks.cpp +++ b/services/audioflinger/Tracks.cpp @@ -351,6 +351,7 @@ AudioFlinger::PlaybackThread::Track::Track( // Read the initial underruns because this field is never cleared by the fast mixer mObservedUnderruns = thread->getFastTrackUnderruns(i); thread->mFastTrackAvailMask &= ~(1 << i); + thread->mNBLogWriter->logf("new Track mName=%d mFastIndex=%d", mName, mFastIndex); } } ALOGV("Track constructor name %d, calling pid %d", mName, @@ -360,6 +361,7 @@ AudioFlinger::PlaybackThread::Track::Track( AudioFlinger::PlaybackThread::Track::~Track() { ALOGV("PlaybackThread::Track destructor"); + // FIXME not sure if safe to log here, would need a lock on thread to do it } void AudioFlinger::PlaybackThread::Track::destroy() @@ -569,7 +571,8 @@ status_t AudioFlinger::PlaybackThread::Track::start(AudioSystem::sync_event_t ev sp thread = mThread.promote(); if (thread != 0) { Mutex::Autolock _l(thread->mLock); - thread->mNBLogWriter->logf("start mName=%d", mName); + thread->mNBLogWriter->logf("start mName=%d mFastIndex=%d caller=%d", mName, mFastIndex, + IPCThreadState::self()->getCallingPid()); track_state state = mState; // here the track could be either new, or restarted // in both cases "unstop" the track @@ -612,7 +615,8 @@ void AudioFlinger::PlaybackThread::Track::stop() sp thread = mThread.promote(); if (thread != 0) { Mutex::Autolock _l(thread->mLock); - thread->mNBLogWriter->logf("stop mName=%d", mName); + thread->mNBLogWriter->logf("stop mName=%d mFastIndex=%d caller=%d", mName, mFastIndex, + IPCThreadState::self()->getCallingPid()); track_state state = mState; if (state == RESUMING || state == ACTIVE || state == PAUSING || state == PAUSED) { // If the track is not active (PAUSED and buffers full), flush buffers @@ -649,7 +653,8 @@ void AudioFlinger::PlaybackThread::Track::pause() sp thread = mThread.promote(); if (thread != 0) { Mutex::Autolock _l(thread->mLock); - thread->mNBLogWriter->logf("pause mName=%d", mName); + thread->mNBLogWriter->logf("pause mName=%d mFastIndex=%d caller=%d", mName, mFastIndex, + IPCThreadState::self()->getCallingPid()); if (mState == ACTIVE || mState == RESUMING) { mState = PAUSING; ALOGV("ACTIVE/RESUMING => PAUSING (%d) on thread %p", mName, thread.get()); @@ -673,7 +678,8 @@ void AudioFlinger::PlaybackThread::Track::flush() sp thread = mThread.promote(); if (thread != 0) { Mutex::Autolock _l(thread->mLock); - thread->mNBLogWriter->logf("flush mName=%d", mName); + thread->mNBLogWriter->logf("flush mName=%d mFastIndex=%d caller=%d", mName, mFastIndex, + IPCThreadState::self()->getCallingPid()); if (mState != STOPPING_1 && mState != STOPPING_2 && mState != STOPPED && mState != PAUSED && mState != PAUSING && mState != IDLE && mState != FLUSHED) { return; -- 2.11.0