From d2123e631834a887c2d8600c3ac43dda02d47cb9 Mon Sep 17 00:00:00 2001 From: Glenn Kasten Date: Thu, 29 Jan 2015 10:02:44 -0800 Subject: Warmup cycles must be in range and consecutive Change-Id: Ie8a40ec3547bdd62a1e2e05b11fb107c25841784 --- services/audioflinger/FastCapture.cpp | 6 ++++-- services/audioflinger/FastMixer.cpp | 6 ++++-- services/audioflinger/FastThread.cpp | 20 ++++++++++++++++---- services/audioflinger/FastThread.h | 6 ++++-- 4 files changed, 28 insertions(+), 10 deletions(-) (limited to 'services') diff --git a/services/audioflinger/FastCapture.cpp b/services/audioflinger/FastCapture.cpp index 1c4f670..255496e 100644 --- a/services/audioflinger/FastCapture.cpp +++ b/services/audioflinger/FastCapture.cpp @@ -138,13 +138,15 @@ void FastCapture::onStateChange() underrunNs = (frameCount * 1750000000LL) / sampleRate; // 1.75 overrunNs = (frameCount * 500000000LL) / sampleRate; // 0.50 forceNs = (frameCount * 950000000LL) / sampleRate; // 0.95 - warmupNs = (frameCount * 500000000LL) / sampleRate; // 0.50 + warmupNsMin = (frameCount * 750000000LL) / sampleRate; // 0.75 + warmupNsMax = (frameCount * 1250000000LL) / sampleRate; // 1.25 } else { periodNs = 0; underrunNs = 0; overrunNs = 0; forceNs = 0; - warmupNs = 0; + warmupNsMin = 0; + warmupNsMax = LONG_MAX; } readBufferState = -1; dumpState->mFrameCount = frameCount; diff --git a/services/audioflinger/FastMixer.cpp b/services/audioflinger/FastMixer.cpp index 67e2e6e..8b12f28 100644 --- a/services/audioflinger/FastMixer.cpp +++ b/services/audioflinger/FastMixer.cpp @@ -195,13 +195,15 @@ void FastMixer::onStateChange() underrunNs = (frameCount * 1750000000LL) / sampleRate; // 1.75 overrunNs = (frameCount * 500000000LL) / sampleRate; // 0.50 forceNs = (frameCount * 950000000LL) / sampleRate; // 0.95 - warmupNs = (frameCount * 500000000LL) / sampleRate; // 0.50 + warmupNsMin = (frameCount * 750000000LL) / sampleRate; // 0.75 + warmupNsMax = (frameCount * 1250000000LL) / sampleRate; // 1.25 } else { periodNs = 0; underrunNs = 0; overrunNs = 0; forceNs = 0; - warmupNs = 0; + warmupNsMin = 0; + warmupNsMax = LONG_MAX; } mMixerBufferState = UNDEFINED; #if !LOG_NDEBUG diff --git a/services/audioflinger/FastThread.cpp b/services/audioflinger/FastThread.cpp index 3e12cca..b69cc85 100644 --- a/services/audioflinger/FastThread.cpp +++ b/services/audioflinger/FastThread.cpp @@ -29,7 +29,8 @@ #define FAST_DEFAULT_NS 999999999L // ~1 sec: default time to sleep #define FAST_HOT_IDLE_NS 1000000L // 1 ms: time to sleep while hot idling -#define MIN_WARMUP_CYCLES 2 // minimum number of loop cycles to wait for warmup +#define MIN_WARMUP_CYCLES 2 // minimum number of consecutive in-range loop cycles + // to wait for warmup #define MAX_WARMUP_CYCLES 10 // maximum number of loop cycles to wait for warmup namespace android { @@ -44,7 +45,8 @@ FastThread::FastThread() : Thread(false /*canCallJava*/), underrunNs(0), overrunNs(0), forceNs(0), - warmupNs(0), + warmupNsMin(0), + warmupNsMax(LONG_MAX), // re-initialized to &dummyDumpState by subclass constructor mDummyDumpState(NULL), dumpState(NULL), @@ -60,6 +62,7 @@ FastThread::FastThread() : Thread(false /*canCallJava*/), isWarm(false), /* measuredWarmupTs({0, 0}), */ warmupCycles(0), + warmupConsecutiveInRangeCycles(0), // dummyLogWriter logWriter(&dummyLogWriter), timestampStatus(INVALID_OPERATION), @@ -169,6 +172,7 @@ bool FastThread::threadLoop() measuredWarmupTs.tv_sec = 0; measuredWarmupTs.tv_nsec = 0; warmupCycles = 0; + warmupConsecutiveInRangeCycles = 0; sleepNs = -1; coldGen = current->mColdGen; #ifdef FAST_MIXER_STATISTICS @@ -222,7 +226,8 @@ bool FastThread::threadLoop() // To avoid an initial underrun on fast tracks after exiting standby, // do not start pulling data from tracks and mixing until warmup is complete. // Warmup is considered complete after the earlier of: - // MIN_WARMUP_CYCLES write() attempts and last one blocks for at least warmupNs + // MIN_WARMUP_CYCLES consecutive in-range write() attempts, + // where "in-range" means warmupNsMin <= cycle time <= warmupNsMax // MAX_WARMUP_CYCLES write() attempts. // This is overly conservative, but to get better accuracy requires a new HAL API. if (!isWarm && attemptedWrite) { @@ -233,7 +238,14 @@ bool FastThread::threadLoop() measuredWarmupTs.tv_nsec -= 1000000000; } ++warmupCycles; - if ((nsec > warmupNs && warmupCycles >= MIN_WARMUP_CYCLES) || + if (warmupNsMin <= nsec && nsec <= warmupNsMax) { + ALOGV("warmup cycle %d in range: %.03f ms", warmupCycles, nsec * 1e-9); + ++warmupConsecutiveInRangeCycles; + } else { + ALOGV("warmup cycle %d out of range: %.03f ms", warmupCycles, nsec * 1e-9); + warmupConsecutiveInRangeCycles = 0; + } + if ((warmupConsecutiveInRangeCycles >= MIN_WARMUP_CYCLES) || (warmupCycles >= MAX_WARMUP_CYCLES)) { isWarm = true; dumpState->mMeasuredWarmupTs = measuredWarmupTs; diff --git a/services/audioflinger/FastThread.h b/services/audioflinger/FastThread.h index 1330334..cb32e9d 100644 --- a/services/audioflinger/FastThread.h +++ b/services/audioflinger/FastThread.h @@ -58,7 +58,8 @@ protected: long underrunNs; // underrun likely when write cycle is greater than this value long overrunNs; // overrun likely when write cycle is less than this value long forceNs; // if overrun detected, force the write cycle to take this much time - long warmupNs; // warmup complete when write cycle is greater than to this value + long warmupNsMin; // warmup complete when write cycle is greater than or equal to this value + long warmupNsMax; // and less than or equal to this value FastThreadDumpState *mDummyDumpState; FastThreadDumpState *dumpState; bool ignoreNextOverrun; // used to ignore initial overrun and first after an underrun @@ -74,7 +75,8 @@ protected: unsigned coldGen; // last observed mColdGen bool isWarm; // true means ready to mix, false means wait for warmup before mixing struct timespec measuredWarmupTs; // how long did it take for warmup to complete - uint32_t warmupCycles; // counter of number of loop cycles required to warmup + uint32_t warmupCycles; // counter of number of loop cycles during warmup phase + uint32_t warmupConsecutiveInRangeCycles; // number of consecutive cycles in range NBLog::Writer dummyLogWriter; NBLog::Writer *logWriter; status_t timestampStatus; -- cgit v1.1