1/* 2 * Copyright (C) 2012 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17// The watchdog thread runs periodically. It has two functions: 18// (a) verify that adequate CPU time is available, and log 19// as soon as possible when there appears to be a CPU shortage 20// (b) monitor the other threads [not yet implemented] 21 22#ifndef AUDIO_WATCHDOG_H 23#define AUDIO_WATCHDOG_H 24 25#include <time.h> 26#include <utils/Thread.h> 27 28namespace android { 29 30// Keeps a cache of AudioWatchdog statistics that can be logged by dumpsys. 31// The usual caveats about atomicity of information apply. 32struct AudioWatchdogDump { 33 AudioWatchdogDump() : mUnderruns(0), mLogs(0), mMostRecent(0) { } 34 /*virtual*/ ~AudioWatchdogDump() { } 35 uint32_t mUnderruns; // total number of underruns 36 uint32_t mLogs; // total number of log messages 37 time_t mMostRecent; // time of most recent log 38 void dump(int fd); // should only be called on a stable copy, not the original 39}; 40 41class AudioWatchdog : public Thread { 42 43public: 44 AudioWatchdog(unsigned periodMs = 50) : Thread(false /*canCallJava*/), mPaused(false), 45 mPeriodNs(periodMs * 1000000), mMaxCycleNs(mPeriodNs * 2), 46 // mOldTs 47 // mLogTs initialized below 48 mOldTsValid(false), mUnderruns(0), mLogs(0), mDump(&mDummyDump) 49 { 50#define MIN_TIME_BETWEEN_LOGS_SEC 60 51 // force an immediate log on first underrun 52 mLogTs.tv_sec = MIN_TIME_BETWEEN_LOGS_SEC; 53 mLogTs.tv_nsec = 0; 54 } 55 virtual ~AudioWatchdog() { } 56 57 // Do not call Thread::requestExitAndWait() without first calling requestExit(). 58 // Thread::requestExitAndWait() is not virtual, and the implementation doesn't do enough. 59 virtual void requestExit(); 60 61 // FIXME merge API and implementation with AudioTrackThread 62 void pause(); // suspend thread from execution at next loop boundary 63 void resume(); // allow thread to execute, if not requested to exit 64 65 // Where to store the dump, or NULL to not update 66 void setDump(AudioWatchdogDump* dump); 67 68private: 69 virtual bool threadLoop(); 70 71 Mutex mMyLock; // Thread::mLock is private 72 Condition mMyCond; // Thread::mThreadExitedCondition is private 73 bool mPaused; // whether thread is currently paused 74 75 uint32_t mPeriodNs; // nominal period 76 uint32_t mMaxCycleNs; // maximum allowed time of one cycle before declaring underrun 77 struct timespec mOldTs; // monotonic time when threadLoop last ran 78 struct timespec mLogTs; // time since last log 79 bool mOldTsValid; // whether mOldTs is valid 80 uint32_t mUnderruns; // total number of underruns 81 uint32_t mLogs; // total number of logs 82 AudioWatchdogDump* mDump; // where to store the dump, always non-NULL 83 AudioWatchdogDump mDummyDump; // default area for dump in case setDump() is not called 84}; 85 86} // namespace android 87 88#endif // AUDIO_WATCHDOG_H 89