Java Thread Implementation
On linux platform, jvm implement thread in native thread method, every jvm thread will map a native thread. And so on, native thread under the linux platform are implemented as processes that shared resources. The scheduler does not differentiate between a thread and a process.
All threads of all apps belong on the same thread group on the system, so every thread competes with all threads of all apps. Therefore, Thread.setPriority
should actually do the same as Process.setThreadPriority
.
Currently, CFS is the default scheduler for process or thread on linux platform. And also there is other schedule for real time task.
CFS Priority Scheduling
SCHED_NORMAL, SCHED_BATCH, SCHED_IDEL will be scheduled by CFS scheduler.
SCHED_RR and SCHED_FIFO will be scheduled by real time scheduler.
In Complete Fair Scheduler every task has the virtual time parameter to save the time that it had token cup time. And the system record the fair clock which is running in RealTime div TheNumberOfTask. Every task’s vtime will trbby to catch the fair clock. All task will save in RB tree with its vtime. In every sechuldeing happened, the sechudler will choose the left of RB tree which is has the most small vtime.
On the other hand, every task has seperated priority. If one task has two times priority than the other, the high priority task will get two times cup time than the other.
Android Thread Pirority Implementation
http://androidxref.com/4.2_r1/xref/dalvik/vm/os/android.cpp#481
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23void os_changeThreadPriority(Thread* thread, int newPriority) {
if (newPriority < 1 || newPriority > 10) {
ALOGW("bad priority %d", newPriority);
newPriority = 5;
}
int newNice = kNiceValues[newPriority-1];
pid_t pid = thread->systemTid;
if (newNice >= ANDROID_PRIORITY_BACKGROUND) {
set_sched_policy(dvmGetSysThreadId(), SP_BACKGROUND);
} else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
set_sched_policy(dvmGetSysThreadId(), SP_FOREGROUND);
}
if (setpriority(PRIO_PROCESS, pid, newNice) != 0) {
std::string threadName(dvmGetThreadName(thread));
ALOGI("setPriority(%d) '%s' to prio=%d(n=%d) failed: %s",
pid, threadName.c_str(), newPriority, newNice, strerror(errno));
} else {
ALOGV("setPriority(%d) to prio=%d(n=%d)", pid, newPriority, newNice);
}
}
http://androidxref.com/4.2_r1/xref/system/core/libcutils/sched_policy.c#312
1 | if (sys_supports_schedgroups) { |
http://lxr.linux.no/#linux+v3.13.5/kernel/sched/core.c#L3015
1 | /* Actually do priority change: must hold rq lock. */ |
http://lxr.linux.no/#linux+v3.13.5/kernel/sched/core.c#L2462
1 | static inline struct task_struct * |
Demo Time
https://github.com/simpleton/android_misc/tree/master/ThreadBenchmark
References
- http://lwn.net/Articles/3866/
- http://androidxref.com/source/xref/dalvik/vm/Thread.cpp
- http://stackoverflow.com/questions/1662185/do-linux-jvms-actually-implement-thread-priorities
- http://blog.csdn.net/innost/article/details/6940136
- https://www.ibm.com/developerworks/cn/linux/l-cfs/
- http://hi.baidu.com/_kouu/item/055bd19af9f6b9dc1f4271d1
- http://ck.wikia.com/wiki/SchedulingPolicies