14cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten/*
24cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten * Copyright (C) 2014 The Android Open Source Project
34cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten *
44cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten * Licensed under the Apache License, Version 2.0 (the "License");
54cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten * you may not use this file except in compliance with the License.
64cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten * You may obtain a copy of the License at
74cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten *
84cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten *      http://www.apache.org/licenses/LICENSE-2.0
94cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten *
104cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten * Unless required by applicable law or agreed to in writing, software
114cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten * distributed under the License is distributed on an "AS IS" BASIS,
124cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten * See the License for the specific language governing permissions and
144cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten * limitations under the License.
154cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten */
164cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten
174cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten#ifndef ANDROID_AUDIO_FAST_THREAD_H
184cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten#define ANDROID_AUDIO_FAST_THREAD_H
194cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten
202234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten#include "Configuration.h"
212234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten#ifdef CPU_FREQUENCY_STATISTICS
222234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten#include <cpustats/ThreadCpuUsage.h>
232234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten#endif
244cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten#include <utils/Thread.h>
252234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten#include "FastThreadState.h"
264cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten
274cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kastennamespace android {
284cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten
294cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten// FastThread is the common abstract base class of FastMixer and FastCapture
304cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kastenclass FastThread : public Thread {
314cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten
324cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kastenpublic:
33f9715e43ea73361321663514c44129c939c5db2fGlenn Kasten            FastThread(const char *cycleMs, const char *loadUs);
342234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten    virtual ~FastThread();
352234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten
362234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kastenprivate:
372234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten    // implement Thread::threadLoop()
382234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten    virtual bool threadLoop();
394cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten
404cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kastenprotected:
412234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten    // callouts to subclass in same lexical order as they were in original FastMixer.cpp
422234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten    // FIXME need comments
432234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten    virtual const FastThreadState *poll() = 0;
442234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten    virtual void setLog(NBLog::Writer *logWriter __unused) { }
452234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten    virtual void onIdle() = 0;
462234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten    virtual void onExit() = 0;
472234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten    virtual bool isSubClassCommand(FastThreadState::Command command) = 0;
482234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten    virtual void onStateChange() = 0;
492234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten    virtual void onWork() = 0;
502234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten
51e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    // FIXME these former local variables need comments
52e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    const FastThreadState*  mPrevious;
53e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    const FastThreadState*  mCurrent;
54e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    struct timespec mOldTs;
55e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    bool            mOldTsValid;
56e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    long            mSleepNs;       // -1: busy wait, 0: sched_yield, > 0: nanosleep
57e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    long            mPeriodNs;      // expected period; the time required to render one mix buffer
58e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    long            mUnderrunNs;    // underrun likely when write cycle is greater than this value
59e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    long            mOverrunNs;     // overrun likely when write cycle is less than this value
60e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    long            mForceNs;       // if overrun detected,
61e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten                                    // force the write cycle to take this much time
62e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    long            mWarmupNsMin;   // warmup complete when write cycle is greater than or equal to
63e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten                                    // this value
64e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    long            mWarmupNsMax;   // and less than or equal to this value
65e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    FastThreadDumpState* mDummyDumpState;
66e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    FastThreadDumpState* mDumpState;
67e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    bool            mIgnoreNextOverrun;     // used to ignore initial overrun and first after an
68e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten                                            // underrun
69214b406c813e5baca3e4b5cdc1d986de35f09bbbGlenn Kasten#ifdef FAST_THREAD_STATISTICS
70e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    struct timespec mOldLoad;       // previous value of clock_gettime(CLOCK_THREAD_CPUTIME_ID)
71e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    bool            mOldLoadValid;  // whether oldLoad is valid
72e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    uint32_t        mBounds;
73e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    bool            mFull;          // whether we have collected at least mSamplingN samples
742234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten#ifdef CPU_FREQUENCY_STATISTICS
75e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    ThreadCpuUsage  mTcu;           // for reading the current CPU clock frequency in kHz
762234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten#endif
772234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten#endif
78e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    unsigned        mColdGen;       // last observed mColdGen
79e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    bool            mIsWarm;        // true means ready to mix,
80e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten                                    // false means wait for warmup before mixing
81e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    struct timespec mMeasuredWarmupTs;  // how long did it take for warmup to complete
82e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    uint32_t        mWarmupCycles;  // counter of number of loop cycles during warmup phase
83e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    uint32_t        mWarmupConsecutiveInRangeCycles;    // number of consecutive cycles in range
84e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    NBLog::Writer   mDummyLogWriter;
85e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    NBLog::Writer*  mLogWriter;
86e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    status_t        mTimestampStatus;
872234002b0710c8db73f82d397cb945cd541c6bbbGlenn Kasten
88e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    FastThreadState::Command mCommand;
89e4a7ce250cb94a00aa2f76e5edca1c4479dc5401Glenn Kasten    bool            mAttemptedWrite;
904cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten
91f9715e43ea73361321663514c44129c939c5db2fGlenn Kasten    char            mCycleMs[16];   // cycle_ms + suffix
92f9715e43ea73361321663514c44129c939c5db2fGlenn Kasten    char            mLoadUs[16];    // load_us + suffix
93f9715e43ea73361321663514c44129c939c5db2fGlenn Kasten
944cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten};  // class FastThread
954cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten
964cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten}   // android
974cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten
984cd161b5bf7a8008d684db4b217ed84d1704e683Glenn Kasten#endif  // ANDROID_AUDIO_FAST_THREAD_H
99