• Android processgroup机制


            Android processgroup在init secondstate的SetupCgroupAction时进行初始化。

    初始化cgroups

    task_profiles

     task_profiles.json文件中记录了两种类型数据 -- Attributes和profiles。Attributes的格式为:

    1. {
    2. "Name": "LowCapacityCPUs",
    3. "Controller": "cpuset",
    4. "File": "background/cpus"
    5. },

    Name指当前的Attribute的名字,Controller是指所归属于哪个cgroups的subsystem,File是指该controller的VFS目录下的子节点路径。

    profiles的格式如下:

    1. {
    2. "Name": "HighEnergySaving",
    3. "Actions": [
    4. {
    5. "Name": "JoinCgroup",
    6. "Params":
    7. {
    8. "Controller": "schedtune",
    9. "Path": "background"
    10. }
    11. }
    12. ]
    13. },
    14. {
    15. "Name": "TimerSlackHigh",
    16. "Actions": [
    17. {
    18. "Name": "SetTimerSlack",
    19. "Params":
    20. {
    21. "Slack": "40000000"
    22. }
    23. }
    24. ]
    25. },
    26. {
    27. "Name": "LowMemoryUsage",
    28. "Actions": [
    29. {
    30. "Name": "SetAttribute",
    31. "Params":
    32. {
    33. "Name": "MemSoftLimit",
    34. "Value": "16MB"
    35. }
    36. },
    37. {
    38. "Name": "SetAttribute",
    39. "Params":
    40. {
    41. "Name": "MemSwappiness",
    42. "Value": "150"
    43. }
    44. }
    45. ]
    46. },
    47. {
    48. "Name": "PerfBoost",
    49. "Actions": [
    50. {
    51. "Name": "SetClamps",
    52. "Params":
    53. {
    54. "Boost": "50%",
    55. "Clamp": "0"
    56. }
    57. }
    58. ]
    59. },

    每个profile中都有一个name,然后剩下的字段就是Actions,每个profile可以有多个Actions,profile支持4种Action -- JoinCgroup、SetTimerSlack、SetAttribute以及SetClamps。

    JoinCgroup

    JoinCgroup只有两个参数 -- controller和Path,Controller仍是指cgroups的subsystem,path则是指该subsystem下的路径,也就是子group。这个Action的含义很明显,就是将设置成这个profile的process加入到该subsystem的子group中,受这个group的资源限制。

    而在源码中,其对应的处理方法是SetCgroupAction类。

    1. bool SetCgroupAction::AddTidToCgroup(int tid, int fd) {
    2. if (tid <= 0) {
    3. return true;
    4. }
    5. std::string value = std::to_string(tid);
    6. if (TEMP_FAILURE_RETRY(write(fd, value.c_str(), value.length())) < 0) {
    7. // If the thread is in the process of exiting, don't flag an error
    8. if (errno != ESRCH) {
    9. PLOG(ERROR) << "AddTidToCgroup failed to write '" << value << "'; fd=" << fd;
    10. return false;
    11. }
    12. }
    13. return true;
    14. }

    设置进程的cgroups也是很简单,只要将pid/tid写入到对应的cgroups下的cgroup.procs级可。

    SetTimerSlack

    setTimerSlack只有一个Slack参数值,这个参数对应了/proc//timerslack_ns。TimerSlack是Linux系统为了降低系统功耗,避免timer时间参差不齐,过于的频繁的唤醒cpu,而设置的一种对齐策略。也就是说,这个值是关系到进程的定时器,诸如select、epoll_wait、sleep等API的唤醒时间,具体可参考下面的案例:https://cloud.tencent.com/developer/article/1836285

    SetAttribute

    SetAttribute则跟task_profiles.json中的Attributes挂钩起来,对应了SetAttributeAction,SetAttribute有两个参数 -- Name是指前面Attributes所定义过的Attribute名字,Value则是往Attribute对应group子节点写入的值。

    1. bool SetAttributeAction::ExecuteForTask(int tid) const {
    2. std::string path;
    3. if (!attribute_->GetPathForTask(tid, &path)) {
    4. LOG(ERROR) << "Failed to find cgroup for tid " << tid;
    5. return false;
    6. }
    7. if (!WriteStringToFile(value_, path)) {
    8. PLOG(ERROR) << "Failed to write '" << value_ << "' to " << path;
    9. return false;
    10. }
    11. return true;
    12. }

    SetClamps

    预留的接口,未实现,待内核支持util_clamp。

    profiles的设置过程

    Start thread

    1. set_sched_policy: #00 pc 00000000000253ec /system/lib64/libprocessgroup.so (set_sched_policy+92)
    2. set_sched_policy: #00 pc 00000000000253ec /system/lib64/libprocessgroup.so (set_sched_policy+92)
    3. set_sched_policy: #01 pc 000000000001301c /system/lib64/libutils.so (thread_data_t::trampoline(thread_data_t const*)+92)
    4. set_sched_policy: #02 pc 00000000000e1100 /system/lib64/bootstrap/libc.so (__pthread_start(void*)+36)
    5. set_sched_policy: #03 pc 0000000000083ab0 /system/lib64/bootstrap/libc.so (__start_thread+64)

    android在创建线程时,根据创建线程时设置的priority(默认是ANDROID_PRIORITY_BACKGROUND)来设置processgroup:

    1. int androidCreateRawThreadEtc(android_thread_func_t entryFunction,
    2. void *userData,
    3. const char* threadName __android_unused,
    4. int32_t threadPriority,
    5. size_t threadStackSize,
    6. android_thread_id_t *threadId)
    7. {
    8. pthread_attr_t attr;
    9. pthread_attr_init(&attr);
    10. pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
    11. #if defined(__ANDROID__) /* valgrind is rejecting RT-priority create reqs */
    12. if (threadPriority != PRIORITY_DEFAULT || threadName != NULL) {
    13. // Now that the pthread_t has a method to find the associated
    14. // android_thread_id_t (pid) from pthread_t, it would be possible to avoid
    15. // this trampoline in some cases as the parent could set the properties
    16. // for the child. However, there would be a race condition because the
    17. // child becomes ready immediately, and it doesn't work for the name.
    18. // prctl(PR_SET_NAME) only works for self; prctl(PR_SET_THREAD_NAME) was
    19. // proposed but not yet accepted.
    20. thread_data_t* t = new thread_data_t;
    21. t->priority = threadPriority;
    22. t->threadName = threadName ? strdup(threadName) : NULL;
    23. t->entryFunction = entryFunction;
    24. t->userData = userData;
    25. entryFunction = (android_thread_func_t)&thread_data_t::trampoline;
    26. userData = t;
    27. }
    28. #endif
    29. ……
    30. }
    31. static int trampoline(const thread_data_t* t) {
    32. thread_func_t f = t->entryFunction;
    33. void* u = t->userData;
    34. int prio = t->priority;
    35. char * name = t->threadName;
    36. delete t;
    37. setpriority(PRIO_PROCESS, 0, prio);
    38. if (prio >= ANDROID_PRIORITY_BACKGROUND) {
    39. set_sched_policy(0, SP_BACKGROUND);
    40. } else {
    41. set_sched_policy(0, SP_FOREGROUND);
    42. }
    43. if (name) {
    44. androidSetThreadName(name);
    45. free(name);
    46. }
    47. return f(u);
    48. }

    Zygote SpecializeCommon

    1. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #00 pc 00000000000253ec /system/lib64/libprocessgroup.so (set_sched_policy+92)
    2. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #01 pc 00000000001ae994 /system/lib64/libandroid_runtime.so ((anonymous namespace)::SpecializeCommon(_JNIEnv*, unsigned int, unsigned int, _jintArray*, int, _jobjectArray*, long, long, int, _jstring*, _jstring*, bool, bool, _jstring*, _jstring*)+5728)
    3. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #02 pc 00000000001aaec8 /system/lib64/libandroid_runtime.so (android::com_android_internal_os_Zygote_nativeForkAndSpecialize(_JNIEnv*, _jclass*, int, int, _jintArray*, int, _jobjectArray*, int, _jstring*, _jstring*, _jintArray*, _jintArray*, unsigned char, _jstring*, _jstring*)+740)
    4. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #03 pc 00000000002c4300 /system/framework/arm64/boot-framework.oat (art_jni_trampoline+416)
    5. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #04 pc 00000000009aa8b8 /system/framework/arm64/boot-framework.oat (com.android.internal.os.Zygote.forkAndSpecialize+200)
    6. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #05 pc 00000000009aeb14 /system/framework/arm64/boot-framework.oat (com.android.internal.os.ZygoteConnection.processOneCommand+1844)
    7. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #06 pc 00000000009b4090 /system/framework/arm64/boot-framework.oat (com.android.internal.os.ZygoteServer.runSelectLoop+1600)
    8. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #07 pc 00000000009b0a14 /system/framework/arm64/boot-framework.oat (com.android.internal.os.ZygoteInit.main+2884)
    9. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #08 pc 00000000001365b8 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_static_stub+568)
    10. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #09 pc 000000000014508c /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+276)
    11. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #10 pc 00000000004a9b0c /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104)
    12. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #11 pc 00000000004a9778 /apex/com.android.runtime/lib64/libart.so (art::InvokeWithVarArgs(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+408)
    13. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #12 pc 00000000003b67f0 /apex/com.android.runtime/lib64/libart.so (art::JNI::CallStaticVoidMethodV(_JNIEnv*, _jclass*, _jmethodID*, std::__va_list)+628)
    14. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #13 pc 00000000000bf560 /system/lib64/libandroid_runtime.so (_JNIEnv::CallStaticVoidMethod(_jclass*, _jmethodID*, ...)+116)
    15. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #14 pc 00000000000c246c /system/lib64/libandroid_runtime.so (android::AndroidRuntime::start(char const*, android::Vector const&, bool)+912)
    16. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #15 pc 00000000000034e0 /system/bin/app_process64 (main+1168)
    17. 05-26 15:26:08.641 3147 3147 D set_sched_policy: #16 pc 000000000007d798 /apex/com.android.runtime/lib64/bionic/libc.so (__libc_init+108)

    zygote在fork一个应用出来时,就会默认设置了应用的profile值。

    ThreadPriorityBooster

    1. set_sched_policy: #00 pc 00000000000253ec /system/lib64/libprocessgroup.so (set_sched_policy+92)
    2. set_sched_policy: #01 pc 000000000001319c /system/lib64/libutils.so (androidSetThreadPriority+76)
    3. set_sched_policy: #02 pc 000000000014d068 /system/lib64/libandroid_runtime.so (android_os_Process_setThreadPriority(_JNIEnv*, _jobject*, int, int)+32)
    4. set_sched_policy: #03 pc 00000000002ab060 /system/framework/arm64/boot-framework.oat (art_jni_trampoline+160)
    5. set_sched_policy: #04 pc 00000000012ced1c /system/framework/oat/arm64/services.odex (com.android.server.ThreadPriorityBooster.boost+188)
    6. set_sched_policy: #05 pc 00000000015e65e0 /system/framework/oat/arm64/services.odex (com.android.server.am.ActivityManagerService.boostPriorityForLockedSection+64)
    7. set_sched_policy: #06 pc 0000000001612478 /system/framework/oat/arm64/services.odex (com.android.server.am.ActivityManagerService.registerReceiver+184)
    8. set_sched_policy: #07 pc 00000000004deb64 /system/framework/arm64/boot-framework.oat (android.app.ContextImpl.registerReceiverInternal+660)
    9. set_sched_policy: #08 pc 00000000004e4aa0 /system/framework/arm64/boot-framework.oat (android.app.ContextImpl.registerReceiver+128)
    10. set_sched_policy: #09 pc 00000000004e49ec /system/framework/arm64/boot-framework.oat (android.app.ContextImpl.registerReceiver+60)
    11. set_sched_policy: #10 pc 000000000004ad08 /system/priv-app/SettingsProvider/oat/arm64/SettingsProvider.odex (com.android.providers.settings.SettingsProvider.registerBroadcastReceivers+232)
    12. set_sched_policy: #11 pc 000000000004e95c /system/priv-app/SettingsProvider/oat/arm64/SettingsProvider.odex (com.android.providers.settings.SettingsProvider.lambda$onCreate$0$SettingsProvider+44)
    13. set_sched_policy: #12 pc 00000000000170e4 /system/priv-app/SettingsProvider/oat/arm64/SettingsProvider.odex (com.android.providers.settings.-$$Lambda$SettingsProvider$h_zJ8TmggsGxbxfR60fhjb7Ynw4.run+52)
    14. set_sched_policy: #13 pc 000000000073237c /system/framework/arm64/boot-framework.oat (android.os.Handler.dispatchMessage+76)
    15. set_sched_policy: #14 pc 0000000000735990 /system/framework/arm64/boot-framework.oat (android.os.Looper.loop+1440)
    16. set_sched_policy: #15 pc 00000000007343d0 /system/framework/arm64/boot-framework.oat (android.os.HandlerThread.run+544)
    17. set_sched_policy: #16 pc 0000000000136334 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548)
    18. set_sched_policy: #17 pc 000000000014506c /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244)
    19. set_sched_policy: #18 pc 00000000004a9b0c /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104)
    20. set_sched_policy: #19 pc 00000000004aaba0 /apex/com.android.runtime/lib64/libart.so (art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue const*)+416)
    21. set_sched_policy: #20 pc 00000000004ea93c /apex/com.android.runtime/lib64/libart.so (art::Thread::CreateCallback(void*)+1176)
    22. set_sched_policy: #21 pc 00000000000e1100 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+36)
    23. set_sched_policy: #22 pc 0000000000083ab0 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)

    根据堆栈对照源码来看,实际上我们是看不到相关的调用的,而是通过ASM插桩的方式加入到字节码中的,可参考:https://zhuanlan.zhihu.com/p/348548041

    通过反编译services.core.ja(out/soong/.intermediates/frameworks/base/services/core/services.core/android_common/combined/services.core.jar),可以看到插桩后的代码如下:

    1. public Intent registerReceiver(final IApplicationThread caller, String callerPackage, final IIntentReceiver receiver, final IntentFilter filter, final String permission, int userId, final int flags) {
    2. this.enforceNotIsolatedCaller("registerReceiver");
    3. ArrayList stickyIntents = null;
    4. ProcessRecord callerApp = null;
    5. final boolean visibleToInstantApps = (flags & 0x1) != 0x0;
    6. // monitorenter(this)
    7. int callingUid;
    8. int callingPid;
    9. boolean instantApp;
    10. try {
    11. boostPriorityForLockedSection();
    12. ……
    13. }
    14. finally {
    15. // monitorexit(this)
    16. resetPriorityAfterLockedSection();
    17. }
    18. }

    在所有synchronized(ActivityManagerService.this)的调用前后均使用try-finally包裹,并在执行前调用boostPriorityForLockedSection,执行后调用resetPriorityAfterLockedSection。

    applyOomAdjLocked

    1. set_sched_policy: #00 pc 00000000000253ec /system/lib64/libprocessgroup.so (set_sched_policy+92)
    2. set_sched_policy: #01 pc 000000000001301c /system/lib64/libutils.so (thread_data_t::trampoline(thread_data_t const*)+92)
    3. set_sched_policy: #02 pc 00000000000e1100 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+36)
    4. set_sched_policy: #03 pc 0000000000083ab0 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)
    5. set_sched_policy: #00 pc 00000000000253ec /system/lib64/libprocessgroup.so (set_sched_policy+92)
    6. set_sched_policy: #01 pc 000000000014c4b4 /system/lib64/libandroid_runtime.so (android_os_Process_setProcessGroup(_JNIEnv*, _jobject*, int, int)+328)
    7. set_sched_policy: #02 pc 00000000002ab060 /system/framework/arm64/boot-framework.oat (art_jni_trampoline+160)
    8. set_sched_policy: #03 pc 00000000006bb4e4 /system/framework/oat/arm64/services.odex (com.android.server.am.OomAdjuster.lambda$new$0+116)
    9. set_sched_policy: #04 pc 000000000067d554 /system/framework/oat/arm64/services.odex (com.android.server.am.-$$Lambda$OomAdjuster$OVkqAAacT5-taN3pgDzyZj3Ymvk.handleMessage+52)
    10. set_sched_policy: #05 pc 00000000007323b8 /system/framework/arm64/boot-framework.oat (android.os.Handler.dispatchMessage+136)
    11. set_sched_policy: #06 pc 0000000000735990 /system/framework/arm64/boot-framework.oat (android.os.Looper.loop+1440)
    12. set_sched_policy: #07 pc 00000000007343d0 /system/framework/arm64/boot-framework.oat (android.os.HandlerThread.run+544)
    13. set_sched_policy: #08 pc 00000000012ad6e4 /system/framework/oat/arm64/services.odex (com.android.server.ServiceThread.run+100)
    14. set_sched_policy: #09 pc 0000000000136334 /apex/com.android.runtime/lib64/libart.so (art_quick_invoke_stub+548)
    15. set_sched_policy: #10 pc 000000000014506c /apex/com.android.runtime/lib64/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+244)
    16. set_sched_policy: #11 pc 00000000004a9b0c /apex/com.android.runtime/lib64/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+104)
    17. set_sched_policy: #12 pc 00000000004aaba0 /apex/com.android.runtime/lib64/libart.so (art::InvokeVirtualOrInterfaceWithJValues(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, jvalue const*)+416)
    18. set_sched_policy: #13 pc 00000000004ea93c /apex/com.android.runtime/lib64/libart.so (art::Thread::CreateCallback(void*)+1176)
    19. set_sched_policy: #14 pc 00000000000e1100 /apex/com.android.runtime/lib64/bionic/libc.so (__pthread_start(void*)+36)
    20. set_sched_policy: #15 pc 0000000000083ab0 /apex/com.android.runtime/lib64/bionic/libc.so (__start_thread+64)

    AMS对于应用状态发生变化时,会触发OomAdj的值的修改,在此过程中,还会修改process的SchedulingGroup。

    新增一组profile

    针对一些场景,例如我们不想让某类进程(java层的应用)消耗过多的CPU资源,那么可以在cpuset上再创建一个子group,限制

    1.为cgroups的子系统创建一个子节点,在cpuset下创建一个test的子group:

    1. on init
    2. mkdir /dev/cpuset/test
    3. copy /dev/cpuset/cpus /dev/cpuset/test/cpus
    4. copy /dev/cpuset/mems /dev/cpuset/test/mems
    5. chown system system /dev/cpuset/test
    6. chown system system /dev/cpuset/test/tasks
    7. chmod 0664 /dev/cpuset/test/tasks

    2.修改task_profiles.json,增加一个profile类型:

    1. {
    2. "Name": "TestCapacity",
    3. "Actions": [
    4. {
    5. "Name": "JoinCgroup",
    6. "Params":
    7. {
    8. "Controller": "cpuset",
    9. "Path": "test"
    10. }
    11. }
    12. ]
    13. },

    3.libprocessgroup中增加对新增profile的处理:

    1. // system/core/libprocessgroup/include/processgroup/sched_policy.h
    2. typedef enum {
    3. SP_DEFAULT = -1,
    4. SP_BACKGROUND = 0,
    5. SP_FOREGROUND = 1,
    6. SP_SYSTEM = 2, // can't be used with set_sched_policy()
    7. SP_AUDIO_APP = 3,
    8. SP_AUDIO_SYS = 4,
    9. SP_TOP_APP = 5,
    10. SP_RT_APP = 6,
    11. SP_RESTRICTED = 7,
    12. SP_TEST = 8,
    13. SP_CNT,
    14. SP_MAX = SP_CNT - 1,
    15. SP_SYSTEM_DEFAULT = SP_FOREGROUND,
    16. } SchedPolicy;
    17. // system/core/libprocessgroup/sched_policy.cpp
    18. int set_cpuset_policy(int tid, SchedPolicy policy) {
    19. if (tid == 0) {
    20. tid = GetThreadId();
    21. }
    22. policy = _policy(policy);
    23. switch (policy) {
    24. case SP_BACKGROUND:
    25. return SetTaskProfiles(tid,
    26. {"HighEnergySaving", "ProcessCapacityLow", "LowIoPriority",
    27. "TimerSlackHigh"},
    28. true)
    29. ? 0
    30. : -1;
    31. case SP_FOREGROUND:
    32. case SP_AUDIO_APP:
    33. case SP_AUDIO_SYS:
    34. return SetTaskProfiles(tid,
    35. {"HighPerformance", "ProcessCapacityHigh", "HighIoPriority",
    36. "TimerSlackNormal"},
    37. true)
    38. ? 0
    39. : -1;
    40. case SP_TOP_APP:
    41. return SetTaskProfiles(tid,
    42. {"MaxPerformance", "ProcessCapacityMax", "MaxIoPriority",
    43. "TimerSlackNormal"},
    44. true)
    45. ? 0
    46. : -1;
    47. case SP_SYSTEM:
    48. return SetTaskProfiles(tid, {"ServiceCapacityLow", "TimerSlackNormal"}, true) ? 0 : -1;
    49. case SP_RESTRICTED:
    50. return SetTaskProfiles(tid, {"ServiceCapacityRestricted", "TimerSlackNormal"}, true)
    51. ? 0
    52. : -1;
    53. case SP_STEST:
    54. return SetTaskProfiles(tid, {"HighEnergySaving", "TestCapacity", "TimerSlackNormal"}, true) ? 0 : -1;
    55. default:
    56. break;
    57. }
    58. return 0;
    59. }

    4.修改AMS设置sched group的地方:

    1. // frameworks/base/core/java/android/os/Process.java
    2. public static final int THREAD_GROUP_TEST = 8;
    3. // frameworks/base/services/core/java/com/android/server/am/ProcessList.java
    4. static final int SCHED_GROUP_TEST_APP = 5;
    5. // frameworks/base/services/core/java/com/android/server/am/ProcessRecord.java
    6. void setCurrentSchedulingGroup(int curSchedGroup) {
    7. if (mTestApp && curSchedGroup < ProcessList.SCHED_GROUP_TOP_APP)
    8. curSchedGroup = ProcessList.SCHED_GROUP_TEST_APP;
    9. mCurSchedGroup = curSchedGroup;
    10. mWindowProcessController.setCurrentSchedulingGroup(curSchedGroup);
    11. }
    12. // frameworks/base/services/core/java/com/android/server/am/OomAdjuster.java
    13. private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
    14. long nowElapsed) {
    15. final int curSchedGroup = app.getCurrentSchedulingGroup();
    16. int processGroup;
    17. switch (curSchedGroup) {
    18. case ProcessList.SCHED_GROUP_BACKGROUND:
    19. processGroup = THREAD_GROUP_BG_NONINTERACTIVE;
    20. break;
    21. case ProcessList.SCHED_GROUP_TOP_APP:
    22. case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
    23. processGroup = THREAD_GROUP_TOP_APP;
    24. break;
    25. case ProcessList.SCHED_GROUP_RESTRICTED:
    26. processGroup = THREAD_GROUP_RESTRICTED;
    27. break;
    28. case ProcessList.SCHED_GROUP_TEST_APP:
    29. processGroup = THREAD_GROUP_TEST;
    30. break;
    31. default:
    32. processGroup = THREAD_GROUP_DEFAULT;
    33. break;
    34. }
    35. mProcessGroupHandler.sendMessage(mProcessGroupHandler.obtainMessage(
    36. 0 /* unused */, app.pid, processGroup));
    37. }

    参考

    ​https://tech.meituan.com/2015/03/31/cgroups.html

    ​​https://www.kernel.org/doc/html/latest/admin-guide/cgroup-v1/cgroups.html

    http://www.manongjc.com/detail/15-tmeltegfjkrokpe.html

    ​​https://www.modb.pro/db/233701​​​​​​​

  • 相关阅读:
    Arcgis克里金插值报错:ERROR 999999: 执行函数时出错。 表名无效。 空间参考不存在。 ERROR 010429: GRID IO 中存在错误
    2023校招C++开发oppo笔试
    presto搭建,并配置hive
    Conda 创建、激活、克隆、删除虚拟环境
    【IDEA】IDEA 单行注释开头添加空格
    Ubuntu20 安装 带cuda的opencv遇到的问题
    LeetCode-684. Redundant Connection [C++][Java]
    【优化模型】报童的诀窍
    【Zabbix监控一】zabbix的原理与安装
    WPF随笔收录-实时绘制心率曲线
  • 原文地址:https://blog.csdn.net/zcyxiaxi/article/details/125207750