Android thread Scheduling

2022-05-13 18:48:44 浏览数 (1)

Normal scheduling

Android is based on Linux and uses the Linux kernel’s scheduling mechanisms for determining scheduling policies. This is also true for Java code and threads. The Linux’s time sliced scheduling policy combines static and dynamic priorities. Processes can be given an initial priority from 19 to -20 (very low to very high priority). This priority will assure that higher priority processes will get more CPU time when when needed. These level are however dynamic, low level priority tasks that do not consume their CPU time will fine their dynamic priority increased. This dynamic behaviour results is an overall better responsiveness.In terms of dynamic priorities it is ensured that lower priority processes will always have a lower dynamic priority than processes with real-time priorities.Android uses two different mechanisms when scheduling the Linux kernel to perform process level scheduling

Real-time scheduling

The standard Linux kernel provides two real-time scheduling policies, SCHED_FIFO and SCHED_RR. The main real-time policy is SCHED_FIFO. It implements a first-in, first-out scheduling algorithm. When a SCHED_FIFO task starts running, it continues to run until it voluntarily yields the processor, blocks or is preempted by a higher-priority real-time task. It has no timeslices. All other tasks of lower priority will not be scheduled until it relinquishes the CPU. Two equal-priority SCHED_FIFO tasks do not preempt each other. SCHED_RR is similar to SCHED_FIFO, except that such tasks are allotted timeslices based on their priority and run until they exhaust their timeslice. Non-real-time tasks use the SCHED_NORMAL scheduling policy (older kernels had a policy named SCHED_OTHER).

see Documentation/cgroups/cgroups.txt

http://www.kernel.org/doc/Documentation/scheduler/sched-rt-group.txt

The default Android kernel is configured to allow group scheduling of real time processes and the file system to control this is mounted under /dev/cpuctl.

Android uses two different scheduling classes (using linux cgroups) bg_non_interactive and default (foreground). The configuration is that bg_non_interactive is low priority and can maximum utilize ~5% of the cpu (including all background tasks) and foreground ~95%. Forground means either an Activity or a service that is started foregound. At startup Services are running in bg_non_interactive unless they have been elevated to foreground scheduling group using startForeground (HMI applications are always set to foreground).

Binder and priorities

The binder mechanism also propagates priorities. That is the binder process called will run with the same priority as the caller.

JVM thread and process scheduling

An Android system will have a set of unix processes running . Some are native processes but many will be processes that run a Java virtual machine. These processes usually will be multi threaded, All android threads are native pthreads (no green threads). There are two ways to change the priority handling one by Calling Thread.setPriority that is part of the standard Java API and contains a value from MIN_PRIORITY(1) to MAX_PRIORITY(10).As all threads are pthreads these priorities will be mapped to unix process priorities (MIN_PRIORITY being 19 and MAX_PRIORITY -8).

代码语言:javascript复制
-Combined dalvik/vm/Thread.c and  
-frameworks/base/include/utils/threads.h
Thread.priority , Java name    Android property name, Unix priority
1              MIN_PRIORITY,   ANDROID_PRIORITY_LOWEST, 19
2                              ANDROID_PRIORITY_BACKGROUND   6,16
3                              ANDROID_PRIORITY_BACKGROUND   3,13
4                              ANDROID_PRIORITY_BACKGROUND, 10
5              NORM_PRIORITY,  ANDROID_PRIORITY_NORMAL,0
6                              ANDROID_PRIORITY_NORMAL - 2 , -2
7                              ANDROID_PRIORITY_NORMAL - 4  , -4
8                             ANDROID_PRIORITY_URGENT_DISPLAY  3,-5
9                     ANDROID_PRIORITY_URGENT_DISPLAY   2 ,   -6
10         MAX_PRIORITY   ANDROID_PRIORITY_URGENT_DISPLAY ,    -8

The second way to set priorities is to call android.os.Process.setThreadPriority(). This allows to set the pririty to higer priorities for that Declare: in your AndroidManifest and call Process.setThreadPriority(Process.myTid(), Process.THREAD_PRIORITY_URGENT_DISPLAY )

代码语言:javascript复制
frameworks/base/include/utils/threads.h
    ANDROID_PRIORITY_LOWEST         =  19,

    /* use for background tasks */
    ANDROID_PRIORITY_BACKGROUND     =  10,

    /* most threads run at normal priority */
    ANDROID_PRIORITY_NORMAL         =   0,

    /* threads currently running a UI that the user is interacting with */
    ANDROID_PRIORITY_FOREGROUND     =  -2,

    /* the main UI thread has a slightly more favorable priority */
    ANDROID_PRIORITY_DISPLAY        =  -4,
    /* ui service treads might want to run at a urgent display (uncommon) */
    ANDROID_PRIORITY_URGENT_DISPLAY =  -8,

    /* all normal audio threads */
    ANDROID_PRIORITY_AUDIO          = -16,

    /* service audio threads (uncommon) */
    ANDROID_PRIORITY_URGENT_AUDIO   = -19,

    /* should never be used in practice. regular process might not
     * be allowed to use this level */
    ANDROID_PRIORITY_HIGHEST        = -20,

    ANDROID_PRIORITY_DEFAULT        = ANDROID_PRIORITY_NORMAL,
    ANDROID_PRIORITY_MORE_FAVORABLE = -1,
    ANDROID_PRIORITY_LESS_FAVORABLE =  1,

0 人点赞