Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d2123e63 authored by Glenn Kasten's avatar Glenn Kasten
Browse files

Warmup cycles must be in range and consecutive

Change-Id: Ie8a40ec3547bdd62a1e2e05b11fb107c25841784
parent ad8510a3
Loading
Loading
Loading
Loading
+4 −2
Original line number Diff line number Diff line
@@ -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;
+4 −2
Original line number Diff line number Diff line
@@ -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
+16 −4
Original line number Diff line number Diff line
@@ -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;
+4 −2
Original line number Diff line number Diff line
@@ -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;