Android中关于cpu/cpuset/schedtune的应用
Android中关于cpu/cpuset/schedtune的应用都是基于进程优先级的,根据不同优先级划分进程类型。AMS(ActivityManagerService)和PMS(PackageManagerService)等通过class Process设置进程优先级、调度策略等;android/osProcess JNI通过调用libcutils.so/libutils.so执行getpriority/setpriority/sched_setscheduler/sched_getschedler系统调用或者直接操作CGroup文件节点以达到设置优先级,限制进程CPU资源的目的。
根据优先级,通过设置CGroup的cpu/cpuset/stune控制进程获得CPU执行时间、可调度CPU范围等,以达到对不同优先级进程的控制。

Android关于cpu/cpuset/schedtune的框架结构

进程优先级和调度策略从上到下贯穿其中,但是在不同的层级的名称有一些变化。下面逐一介绍。
class Process以及android/os/Process JNI
frameworks/base/core/java/android/os/Process.java
其他服务通过class Process来设置进程优先级、调度侧率等。
class Process中优先级划分:
|
public static final int THREAD_PRIORITY_DEFAULT = 0; 应用的默认优先级 /* public static final int THREAD_PRIORITY_LOWEST = 19; 线程的最低优先级 public static final int THREAD_PRIORITY_BACKGROUND = 10; 后台线程的默认优先级 public static final int THREAD_PRIORITY_FOREGROUND = -2; 前台进程的标准优先级 public static final int THREAD_PRIORITY_DISPLAY = -4; 系统用于显示功能的优先级 public static final int THREAD_PRIORITY_URGENT_DISPLAY = -8; 系统用于重要显示功能的优先级 public static final int THREAD_PRIORITY_AUDIO = -16; 音频线程默认优先级 public static final int THREAD_PRIORITY_URGENT_AUDIO = -19; 重要音频线程默认优先级 |
调度策略划分:
|
public static final int SCHED_OTHER = 0; 默认调度策略,对应CFS调度类 public static final int SCHED_FIFO = 1; FIFO调度策略,对应RT调度类 public static final int SCHED_RR = 2; RR调度策略,对应RT调度类 public static final int SCHED_BATCH = 3; 批调度策略,对应CFS调度类 public static final int SCHED_IDLE = 5; idle调度策略 |
class Process相关API,主要用于:
|
public static final native void setThreadPriority(int tid, int priority) public static final native void setThreadScheduler(int tid, int policy, int priority) public static final native void setThreadPriority(int tid, int priority) public static final native int getThreadPriority(int tid) public static final native int getThreadScheduler(int tid) public static final native void setThreadGroup(int tid, int group) public static final native void setProcessGroup(int pid, int group) |
frameworks/base/core/jni/android_util_Process.cpp
对应JNINativeMethod如下:
|
static const JNINativeMethod methods[] = { |
scheduler相关API直接调用sched_setscheduler/sched_getscheduler。
libcutils.so/libutils.so
在介绍这个函数之前先介绍一下此处所使用的优先级定义,可以看出和class Process中是完全的对应关系:
|
ANDROID_PRIORITY_LOWEST = 19, /* use for background tasks */ /* most threads run at normal priority */ /* threads currently running a UI that the user is interacting with */ /* the main UI thread has a slightly more favorable priority */ /* ui service treads might want to run at a urgent display (uncommon) */ /* all normal audio threads */ /* service audio threads (uncommon) */ /* should never be used in practice. regular process might not ANDROID_PRIORITY_DEFAULT = ANDROID_PRIORITY_NORMAL, |
还需要在研究一下,Sched Policy中使用的优先级映射关系:
|
/* Keep in sync with THREAD_GROUP_* in frameworks/base/core/java/android/os/Process.java */ |
Threads.cpp中定义了androidSetThreadPriority用于设置线程的优先级。
|
int androidSetThreadPriority(pid_t tid, int pri) if (pri >= ANDROID_PRIORITY_BACKGROUND) { 如果priority大于等于BACKGROUND,则设置为BACKGROUND类型的调度策略。 if (rc) { if (setpriority(PRIO_PROCESS, tid, pri) < 0) { 设置优先级 return rc; |
set_cpuset_policy根据SchedPolicy类型将tid写入cpuset和schedtune子系统中。
有下面的函数可以得出cpuset、schedtune和不同类型SchedPolicy之间的对应关系:
/dev/cpuset/foreground/tasks SP_FOREGROUND SP_AUDIO_APP SP_AUDIO_SYS
/dev/cpuset/background/tasks SP_BACKGROUND
/dev/cpuset/system-background/tasks SP_SYSTEM
/dev/cpuset/top-app/tasks SP_TOP_APP
/dev/stune/top-app/tasks SP_TOP_APP
/dev/stune/foreground/tasks SP_FOREGROUND SP_AUDIO_APP SP_AUDIO_SYS
/dev/stune/background/tasks SP_BACKGROUND
|
int set_cpuset_policy(int tid, SchedPolicy policy) int fd = -1; if (add_tid_to_cgroup(tid, fd) != 0) { #ifdef USE_SCHEDBOOST return 0; |
set_sched_policy设置cpu/schedtune两个子系统,子系统节点和SchedPolicy类型对应如下:
/dev/cpuctl/tasks SP_FOREGROUND SP_AUDIO_APP SP_AUDIO_SYS
/dev/cpuctl/bg_non_interactive/tasks SP_BACKGROUND
/dev/stune/top-app/tasks SP_TOP_APP
/dev/stune/foreground/tasks SP_FOREGROUND SP_AUDIO_APP SP_AUDIO_SYS
/dev/stune/background/tasks SP_BACKGROUND
|
int set_sched_policy(int tid, SchedPolicy policy) #if POLICY_DEBUG snprintf(statfile, sizeof(statfile), "/proc/%d/stat", tid); int fd = open(statfile, O_RDONLY | O_CLOEXEC); for (p = statline; *p != '('; p++); strncpy(thread_name, p, (q-p)); if (__sys_supports_schedgroups) { 是否使能schedtune CGroup if (add_tid_to_cgroup(tid, fd) != 0) { #ifdef USE_SCHEDBOOST param.sched_priority = 0; if (__sys_supports_timerslack) { return 0; |
上面的一系列转换可以用下图表示:

system\core\libcutils\Sched_policy.c中,对SP_*系列SchedPolicy转换成使用不同cpuctl、cpuset、stune句柄,将对应的pid、tid写入tasks中。
SP_BACKGROUND对应SCHED_BACH调度策略,其他对应SCHED_NORMAL。
SCHED_NORMAL:默认的调度策略,在旧版中为SCHED_OTHER。SCHED_BATCH:针对批处理进程。SCHED_IDLE:使用此调度侧率的进程优先级最低。
SCHED_NORMAL和SCHED_BATCH区别只是再唤醒时有区别,唤醒较频繁的进程不适合SCHED_BATCH。
如果使能__sys_supports_schedgroups,就不会调用sched_setscheduler去设置SchedulePolicy。
SCHED_NORMAL和SCHED_BACH区别
SP_BACKGROUND对应SCHED_BACH调度策略,其他对应SCHED_NORMAL。
SCHED_NORMAL:默认的调度策略,在旧版中为SCHED_OTHER。SCHED_BATCH:针对批处理进程。SCHED_IDLE:使用此调度侧率的进程优先级最低。
SCHED_NORMAL和SCHED_BATCH区别只是再唤醒时有区别,唤醒较频繁的进程不适合SCHED_BATCH。
如果使能__sys_supports_schedgroups,就不会调用sched_setscheduler去设置SchedulePolicy。
Android中的一个应用
cpu子系统:
|
# Create cgroup mount points for process groups mkdir /dev/cpuctl mount cgroup none /dev/cpuctl cpu chown system system /dev/cpuctl chown system system /dev/cpuctl/tasks chmod 0666 /dev/cpuctl/tasks write /dev/cpuctl/cpu.shares 1024 write /dev/cpuctl/cpu.rt_runtime_us 800000 write /dev/cpuctl/cpu.rt_period_us 1000000 mkdir /dev/cpuctl/bg_non_interactive chown system system /dev/cpuctl/bg_non_interactive/tasks chmod 0666 /dev/cpuctl/bg_non_interactive/tasks # 5.0 % write /dev/cpuctl/bg_non_interactive/cpu.shares 52 write /dev/cpuctl/bg_non_interactive/cpu.rt_runtime_us 700000 write /dev/cpuctl/bg_non_interactive/cpu.rt_period_us 1000000 |
cpuset子系统:
|
# sets up initial cpusets for ActivityManager mkdir /dev/cpuset mount cpuset none /dev/cpuset # this ensures that the cpusets are present and usable, but the device's # init.rc must actually set the correct cpus mkdir /dev/cpuset/foreground write /dev/cpuset/foreground/cpus 0 write /dev/cpuset/foreground/mems 0 mkdir /dev/cpuset/foreground/boost write /dev/cpuset/foreground/boost/cpus 0 write /dev/cpuset/foreground/boost/mems 0 mkdir /dev/cpuset/background write /dev/cpuset/background/cpus 0 write /dev/cpuset/background/mems 0 # system-background is for system tasks that should only run on # little cores, not on bigs # to be used only by init, so don't change system-bg permissions mkdir /dev/cpuset/system-background write /dev/cpuset/system-background/cpus 0 write /dev/cpuset/system-background/mems 0 mkdir /dev/cpuset/top-app write /dev/cpuset/top-app/cpus 0 write /dev/cpuset/top-app/mems 0 # change permissions for all cpusets we'll touch at runtime chown system system /dev/cpuset chown system system /dev/cpuset/foreground chown system system /dev/cpuset/foreground/boost chown system system /dev/cpuset/background chown system system /dev/cpuset/system-background chown system system /dev/cpuset/top-app chown system system /dev/cpuset/tasks chown system system /dev/cpuset/foreground/tasks chown system system /dev/cpuset/foreground/boost/tasks chown system system /dev/cpuset/background/tasks chown system system /dev/cpuset/system-background/tasks chown system system /dev/cpuset/top-app/tasks # set system-background to 0775 so SurfaceFlinger can touch it chmod 0775 /dev/cpuset/system-background chmod 0664 /dev/cpuset/foreground/tasks chmod 0664 /dev/cpuset/foreground/boost/tasks chmod 0664 /dev/cpuset/background/tasks chmod 0664 /dev/cpuset/system-background/tasks chmod 0664 /dev/cpuset/top-app/tasks chmod 0664 /dev/cpuset/tasks |
schedtune子系统:
|
# Create energy-aware scheduler tuning nodes mkdir /dev/stune mount cgroup none /dev/stune schedtune mkdir /dev/stune/foreground chown system system /dev/stune chown system system /dev/stune/foreground chown system system /dev/stune/tasks chown system system /dev/stune/foreground/tasks chmod 0664 /dev/stune/tasks chmod 0664 /dev/stune/foreground/tasks |
Android中关于cpu/cpuset/schedtune的应用的更多相关文章
- 【月入41万】Mono For Android中使用百度地图SDK
借助于Mono For Android技术,.Net开发者也可以使用自己熟悉的C#语言以及.Net来开发Android应用.由于Mono For Android把Android SDK中绝大部分类库都 ...
- Android 中关于static的使用问题
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/5251564.html 项目中,在不停地接收串口数据很长一段时间(几小时)后,会偶然性的报错.初步排除了oom ...
- android中的线程池学习笔记
阅读书籍: Android开发艺术探索 Android开发进阶从小工到专家 对线程池原理的简单理解: 创建多个线程并且进行管理,提交的任务会被线程池指派给其中的线程进行执行,通过线程池的统一调度和管理 ...
- 关于Android中ArrayMap/SparseArray比HashMap性能好的深入研究
由于网上有朋友对于这个问题已经有了很详细的研究,所以我就不班门弄斧了: 转载于:http://android-performance.com/android/2014/02/10/android-sp ...
- Android中Activity的生命周期
简介: 这个基本是必问的问题了,说一下你对Activity生命周期的理解,呵呵… onCreate, onStart, onResume, onPause, onStop, onDestroy, on ...
- Android中Handler 、Thread和Runnable之间的关系
在多线程编程的时候,我们经常会用到Handler,Thread和Runnable这三个类,我们来看看这三个类之间是怎么样的关系? 首先说明Android的CPU分配的最小单元是线程,Handler一般 ...
- Android中对Log日志文件的分析[转]
一,Bug出现了, 需要“干掉”它 bug一听挺吓人的,但是只要你懂了,android里的bug是很好解决的,因为android里提供了LOG机制,具体的底层代码,以后在来分析,只要你会看bug, a ...
- Android中Service(服务)详解
http://blog.csdn.net/ryantang03/article/details/7770939 Android中Service(服务)详解 标签: serviceandroidappl ...
- Android 中的 Service 全面总结(转载)
转载地址:http://www.cnblogs.com/newcj/archive/2011/05/30/2061370.html 感谢作者 Android 中的 Service 全面总结 1.Ser ...
随机推荐
- LCS记录
如题:求两个序列的最长公共序列.(如:"ABCBDAB"与"BCDB"最长公共序列为"BCDB")代码如下: #define MAX_SIZ ...
- 学C#之设计模式系列笔记(1)策略模式
一.借鉴说明 1.<Head First Design Patterns>(中文名<深入浅出设计模式>) 2.维基百科,策略模式,https://zh.wikipedia.or ...
- JSON总结(二)——google-gson
gson是一个google的开源项目,支持多种JSON方法,这里主要讲解如何使用gson将json转换成javaBean. maven坐标 <dependency> <groupId ...
- 【特种兵系列】String中的==和equals()
1. 小样示例 public static void main(String[] args) { String a = "a" + "b" + 123; Str ...
- css图片精灵
<ul> <li class="top"> <em>01</em> <p><a href="http:/ ...
- mui scroll和上拉加载/下拉刷新
mui中 scroll和上拉加载/下拉刷新同时存在会出现两个滚动条 把/* */ /* //mui页面鼠标拖动代码: mui('.mui-scroll-wrapper').scroll({ dec ...
- 无法解决“Microsoft.SharePoint.Security, Version=15.0.0.0,”与“Microsoft.SharePoint.Security, Version=14.0.0.0”之间的冲突
VisualStudio 2013创建控制台项目,.NetFramework选为4.5.生成目标平台:x64.然后添加对Microsoft.SharePoint.dll的引用. 生成项目时," ...
- 使用WebRTC搭建前端视频聊天室——数据通道篇
本文翻译自WebRTC data channels 在两个浏览器中,为聊天.游戏.或是文件传输等需求发送信息是十分复杂的.通常情况下,我们需要建立一台服务器来转发数据,当然规模比较大的情况下,会扩展成 ...
- iOS平台UDID方案比较
苹果在iOS6中禁用了[UIDevice uniqueIdentifier],在iOS7中又把mac地址的获取给堵上了.没办法,毕竟人家是老大,说不让你用,你也没办法.在这边总结一下现有的一部分UDI ...
- 一个高级的J2E工程师需要面对MySQL要有那些基本功夫呢<上>
1. MySQL的架构介绍1.1 MySQL简介: MySQL是一个关系型数据库管理系统,由瑞典MySQL AB公司开发,目前属于Oracle公司. MySQL是一种关联数据库管理系统,将数据保存在不 ...