1 原理说明
这个方案有如下基本需求:
- 构建自定义CPUSET,/dev/cpuset中包含一个全新的cpuset分组。且可以通过set_cpuset_policy和set_sched_policy接口可以设置自定义CPUSET。
- 开机启动后可以通过zygote判定来对特定的应用进程设置CPUSET,并一直保持,且保证自定义CPUSET不受其他CPUSET影响,持续独立。
原理上因为修改代码涉及部分较多,因此共分3个部分:
- framework修改:添加SCHED GROUP和THREAD GROUP(THREAD_GROUP_对应SP_)的支持,且支持开机启动后直接设置。applyOomAdjLSP的判定保持不变。
- system修改:添加SP_CUSTOM的支持及set_cpuset_policy和set_sched_policy接口等支持,同时修改task_profiles.json,添加SP_CUSTOM CPUSET的支持。
- init.rc修改及编译部分调整:对自定义cpuset节点进行操作,vndk部分编译需要重新调整方案以及不修改VNDK如何保证编译通过。
由于修改中涉及代码量过大,这里拆分成两节进行展示。本章节主要针对第2部分和第3部分修改进行说明。上一篇文章👇
Android Framework 常见解决方案(25-1)定制CPUSET解决方案-framework部分修改
主要对第1部分修改进行说明。
2 修改方案(Android S)
2.1 system部分修改
针对system分区修改。具体修改方案如下(这里以S版本修改为主,Q和R有一些差异但原理不变):
在$AOSP/system/core/libprocessgroup/include/processgroup/sched_policy.h文件中修改:
/* Keep in sync with THREAD_GROUP_* in frameworks/base/core/java/android/os/Process.java */
typedef enum {
SP_DEFAULT = -1,
SP_BACKGROUND = 0,
SP_FOREGROUND = 1,
SP_SYSTEM = 2,
SP_AUDIO_APP = 3,
SP_AUDIO_SYS = 4,
SP_TOP_APP = 5,
SP_RT_APP = 6,
SP_RESTRICTED = 7,
+ SP_CUSTOM = 8,
SP_CNT,
SP_MAX = SP_CNT - 1,
SP_SYSTEM_DEFAULT = SP_FOREGROUND,
} SchedPolicy;
这里注意,按照顺序填写修改相对简单,因为后续会用到SP_CNT和SP_MAX这两个变量,代码中还会有许多的遍历操作,因此最好采用累加方案,不要设置其他值。
本方案的修改比较全面,即支持set_cpuset_policy,也兼容到set_sched_policy,在实际操作中,可根据需要只修改其中一个即可。
在$AOSP/system/core/libprocessgroup/sched_policy.cpp文件中修改:
//修改set_cpuset_policy,添加SP_CUSTOM的处理
int set_cpuset_policy(int tid, SchedPolicy policy) {
if (tid == 0) {
tid = GetThreadId();
}
policy = _policy(policy);
switch (policy) {
case SP_BACKGROUND:
return SetTaskProfiles(tid, {"CPUSET_SP_BACKGROUND", "BlkIOBackground"}, true) ? 0 : -1;
case SP_FOREGROUND:
return SetTaskProfiles(tid, {"CPUSET_SP_FOREGROUND", "BlkIOForeground"}, true) ? 0 : -1;
case SP_AUDIO_APP:
case SP_AUDIO_SYS:
return SetTaskProfiles(tid, {"