Android 12 Watchdog monitor实现
Posted pecuyu
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android 12 Watchdog monitor实现相关的知识,希望对你有一定的参考价值。
文章托管在gitee上 Android Notes , 同步csdn
这一篇看一些系统模块的monitor实现。接下来看3个比较典型的场景:
- ActivityManagerService的monitor实现
- InputManagerService的monitor实现,涉及native检查
- Binder线程的monitor实现
Watchdog.Monitor定义如下,实现该接口的类,可以注册到Watchdog作为一个被监听的对象:
public interface Monitor
void monitor();
ActivityManagerService的monitor实现
首先看一下AMS的实现,从继承结构看,它需要继承Watchdog.Monitor
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock
注册到Watchdog
public ActivityManagerService(Context systemContext, ActivityTaskManagerService atm)
...
mHandlerThread = new ServiceThread(TAG,
THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
mHandlerThread.start();
mHandler = new MainHandler(mHandlerThread.getLooper());
...
Watchdog.getInstance().addMonitor(this); // 添加AMS到监控队列
Watchdog.getInstance().addThread(mHandler); // 添加线程到Watchdog监控列表mHandlerCheckers
...
添加monitor对象和监控线程:
// 添加monitor对象
public void addMonitor(Monitor monitor)
synchronized (mLock)
// 添加到mMonitorChecker,在每轮检查的时候在HandlerChecker的run会调用Monitor#monitor
mMonitorChecker.addMonitorLocked(monitor);
// 添加线程监控,通过handler向消息队列投递消息,监测线程是否畅通
public void addThread(Handler thread)
addThread(thread, DEFAULT_TIMEOUT);
public void addThread(Handler thread, long timeoutMillis)
synchronized (mLock)
final String name = thread.getLooper().getThread().getName();
// 对于没有线程都会创建一个HandlerChecker
mHandlerCheckers.add(new HandlerChecker(thread, name, timeoutMillis));
AMS#monitor
接下来看monitor方法的实现。AMS的monitor方法比较简单,就是在方法里面尝试获取同步锁,此处的锁对象就是AMS对象本身。如果锁空闲,则此调用会很快返回,如果锁对象被其他地方使用,则此处会卡住。当卡住过久,那么Watchdog会检查到AMS卡了,则会执行重启。
/** In this method we try to acquire our lock to make sure that we have not deadlocked */
public void monitor()
synchronized (this)
InputManagerService的monitor实现
和AMS类似,也是继承Watchdog.Monitor,并且在其start方法中注册自身到Watchdog
/*
* Wraps the C++ InputManager and provides its callbacks.
*/
public class InputManagerService extends IInputManager.Stub
implements Watchdog.Monitor
public void start()
Slog.i(TAG, "Starting input manager");
nativeStart(mPtr);
// Add ourself to the Watchdog monitors.
Watchdog.getInstance().addMonitor(this); // 注册到Watchdog
IMS#monitor
接下来直接看其monitor实现,它的实现比AMS稍复杂,除了检查Java同步锁,还会调用native方法去检查底层的运行状态。
// Called by the heartbeat to ensure locks are not held indefinitely (for deadlock detection).
@Override
public void monitor()
synchronized (mInputFilterLock)
synchronized (mAssociationsLock) /* Test if blocked by associations lock. */
synchronized (mLidSwitchLock) /* Test if blocked by lid switch lock. */
nativeMonitor(mPtr); // 检查native
nativeMonitor 的native实现
nativeMonitor 是一个 native 方法,它的jni层实现在 com_android_server_input_InputManagerService.cpp
/// @frameworks/base/services/core/jni/com_android_server_input_InputManagerService.cpp
static void nativeMonitor(JNIEnv* /* env */, jclass /* clazz */, jlong ptr)
NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
im->getInputManager()->getReader()->monitor(); // 检查 InputReader 的状态
im->getInputManager()->getDispatcher()->monitor(); // 检查 InputDispatcher 的状态
InputReader 状态检查,比如判断是否出现死锁
void InputReader::monitor()
// Acquire and release the lock to ensure that the reader has not deadlocked.
std::unique_lock<std::mutex> lock(mLock);
mEventHub->wake();
mReaderIsAliveCondition.wait(lock);
// Check the EventHub
mEventHub->monitor(); // EventHub 状态检查
EventHub 状态检查
void EventHub::monitor()
// Acquire and release the lock to ensure that the event hub has not deadlocked.
std::unique_lock<std::mutex> lock(mLock);
InputDispatcher 状态检查, 判断是否出现死锁
void InputDispatcher::monitor()
// Acquire and release the lock to ensure that the dispatcher has not deadlocked.
std::unique_lock _l(mLock);
mLooper->wake();
mDispatcherIsAlive.wait(_l);
Binder 线程监控
接下来是系统进程的binder线程的监控实现。BinderThreadMonitor类也是继承自Watchdog.Monitor,通过调用其monitor方法,来测试binder线程状态
/** Monitor for checking the availability of binder threads. The monitor will block until
* there is a binder thread available to process in coming IPCs to make sure other processes
* can still communicate with the service.
*/
private static final class BinderThreadMonitor implements Watchdog.Monitor
@Override
public void monitor()
Binder.blockUntilThreadAvailable(); // 调用native方法
blockUntilThreadAvailable是native方法,是用来检查正在执行的线程数是否小于最大允许的数量,防止binder线程长时间处于starve状态。
/**
* Call blocks until the number of executing binder threads is less
* than the maximum number of binder threads allowed for this process.
* @hide
*/
public static final native void blockUntilThreadAvailable();
它的实现在 android_util_Binder.cpp , 下面是其jni注册信息。
/// frameworks/base/core/jni/android_util_Binder.cpp
"blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable ,
根据jni注册信息可知其对应的jni函数是 android_os_Binder_blockUntilThreadAvailable。
static void android_os_Binder_blockUntilThreadAvailable(JNIEnv* env, jobject clazz)
return IPCThreadState::self()->blockUntilThreadAvailable();
接下来看 IPCThreadState::blockUntilThreadAvailable,从实现可知,当binder线程数处于满载状态,则检测线程会处于wait状态,当长时间处于wait状态则会触发Watchdog。
void IPCThreadState::blockUntilThreadAvailable()
pthread_mutex_lock(&mProcess->mThreadCountLock);
mProcess->mWaitingForThreads++;
while (mProcess->mExecutingThreadsCount >= mProcess->mMaxThreads) // 判断正在执行的线程数是否小于最大数
ALOGW("Waiting for thread to be free. mExecutingThreadsCount=%lu mMaxThreads=%lu\\n",
static_cast<unsigned long>(mProcess->mExecutingThreadsCount),
static_cast<unsigned long>(mProcess->mMaxThreads));
// 如果在执行的线程已满载运行,则会等待有空闲线程
pthread_cond_wait(&mProcess->mThreadCountDecrement, &mProcess->mThreadCountLock);
mProcess->mWaitingForThreads--;
pthread_mutex_unlock(&mProcess->mThreadCountLock);
以上是关于Android 12 Watchdog monitor实现的主要内容,如果未能解决你的问题,请参考以下文章