Android 12 Watchdog(3) 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);
}
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值