hidl hwbinder和binder混合使用相关的joinThreadPool问题解答

背景:

今天一个学员在群里有个提问如下图,怎么有两个joinThread,会执行么?joinThread不是死循环等待数据吗?
/frameworks/av/media/mediaserver/main_mediaserver.cpp
hidl hwbinder和binder混合使用相关的joinThreadPool问题解答_第1张图片当开始看到这个时候确实也觉得最后的hw的join根本不会执行哈

为了验证我加入了如下日志:
看看主线程执行到哪了:
hidl hwbinder和binder混合使用相关的joinThreadPool问题解答_第2张图片看看joinThreadPool是否会退出:
hidl hwbinder和binder混合使用相关的joinThreadPool问题解答_第3张图片
结果执行如下:
明显log看到没有任何执行::android::hardware::joinRpcThreadpool()
在这里插入图片描述

为啥会有这个的joinRpcThreadpool

这里就得查一下相关的提交日志了
相关提交如下:

commit a4c39654219a7ed7ee6bb3ef5acbb1afd32a4a48
Author: Pawin Vongmasa <[email protected]>
Date:   Tue Jun 30 09:30:58 2020 -0700

    mediaserver: add more hwbinder threads
    
    Since we're now using HIDL IGraphicBufferSource in CCodec, the
    existence of a callstack with mixed binder and hwbinder calls can cause
    a stall when all threads are in use. (b/35283480) The recommended
    workaround was to increase the number of threads. This CL does that.
    
    Test: atest CtsMediaTestCases
    Test: atest CtsCameraTestCases
    
    Bug: 153828976
    Change-Id: I37f02b6237ad032e311a8219b209713d2e4463a6

 #include 
 #include 
 #include 
+#include 
 #include 
 #include "RegisterExtensions.h"
 
@@ -42,6 +43,8 @@ int main(int argc __unused, char **argv __unused)
     MediaPlayerService::instantiate();
     ResourceManagerService::instantiate();
     registerExtensions();
+    ::android::hardware::configureRpcThreadpool(16, false);
     ProcessState::self()->startThreadPool();
     IPCThreadState::self()->joinThreadPool();
+    ::android::hardware::joinRpcThreadpool();
 }

可以明显看出这个joinRpcThreadpool只是为了和前面的configureRpcThreadpool成对出现加入的,并没说添加这个joinRpcThreadpool是为了单独修复什么。明显这个地方的::android::hardware::joinRpcThreadpool()方法并没有见到他的执行,故这个地方的::android::hardware::joinRpcThreadpool()显得很多余

扩展hwbinder相关的joinRpcThreadpool如何进入

上面代码是显式调用进入hwbinder的循环接受消息,上面joinRpcThreadpool代码居然没有执行,那么疑问来了?请问又是在哪里进入的循环接受消息呢?
比如拿SurfaceFlinger来举例,SurfaceFlinger代码中也从来没见到有调用joinRpcThreadpool,但是他依然可以hidl通讯,抓取trace还发现有对于的hwbinder线程,比如硬件vsync的校准

在这里插入图片描述

这到底是为啥?都没有见到有Hwbinder的IPCThreadState.joinRpcThreadpool和ProcessState.startThreadPool的调用,哪来的hw线binder程。。。。死活找不到对于的代码调用端啊。
(IPCThreadState.joinRpcThreadpool和ProcessState.startThreadPool为啥启动线程,这个可以看马哥的跨进程专题课程)

哈哈,这里马哥本来想去Hwbinder的IPCThreadState或ProcessState中加个CallStack不就好了么。。。可以使理想很美好,实际发现libutilscallstack库加入不进去,会导致一堆bp编译错误。。。哎,懒着折腾这个编译相关错误,这个方便堆栈路封死了。。。那么就只能采用其他线索摸索啦,终于经过漫长摸索发现在hidl的自动生成代码中有相关的线索:
hidl hwbinder和binder混合使用相关的joinThreadPool问题解答_第4张图片
这里可以经过日志和额外加trace可以确定就是这个地方启动了hwbinder线程池:
hidl hwbinder和binder混合使用相关的joinThreadPool问题解答_第5张图片
上面是不是展示了在跨进程调用HIDL::IComposerClient::registerCallback::client方法时候进行的hwbinder线程池启动

总结

所以很多时候并不需要在自己的业务代码中显式调用的相关的joinRpcThreadpool和startThreadPool相关方法,因为在hidl相关生成的代码中会调用相关读取hwbinder线程池启动。所以大家在看代码时候发现自己业务代码中没有hwbinder相关的线程池启动,但实际有相关hwbinder线程则可以考虑去相关的hidl生成代码中查找

更多framework干货课程如下(需要的可以私聊马哥 获取优惠 +V :androidframework007):
在这里插入图片描述

你可能感兴趣的:(hal,binder,车载,车机,hal,hidl,跨进程,framework)