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