2 * Copyright (C) 2011 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include <sys/resource.h>
26 #include <cutils/sched_policy.h>
27 #include <utils/threads.h>
30 * Conversion map for "nice" values.
32 * We use Android thread priority constants to be consistent with the rest
33 * of the system. In some cases adjacent entries may overlap.
35 static const int kNiceValues[10] = {
36 ANDROID_PRIORITY_LOWEST, /* 1 (MIN_PRIORITY) */
37 ANDROID_PRIORITY_BACKGROUND + 6,
38 ANDROID_PRIORITY_BACKGROUND + 3,
39 ANDROID_PRIORITY_BACKGROUND,
40 ANDROID_PRIORITY_NORMAL, /* 5 (NORM_PRIORITY) */
41 ANDROID_PRIORITY_NORMAL - 2,
42 ANDROID_PRIORITY_NORMAL - 4,
43 ANDROID_PRIORITY_URGENT_DISPLAY + 3,
44 ANDROID_PRIORITY_URGENT_DISPLAY + 2,
45 ANDROID_PRIORITY_URGENT_DISPLAY /* 10 (MAX_PRIORITY) */
48 void os_changeThreadPriority(Thread* thread, int newPriority)
50 if (newPriority < 1 || newPriority > 10) {
51 ALOGW("bad priority %d", newPriority);
55 int newNice = kNiceValues[newPriority-1];
56 pid_t pid = thread->systemTid;
58 if (newNice >= ANDROID_PRIORITY_BACKGROUND) {
59 set_sched_policy(dvmGetSysThreadId(), SP_BACKGROUND);
60 } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
61 set_sched_policy(dvmGetSysThreadId(), SP_FOREGROUND);
64 if (setpriority(PRIO_PROCESS, pid, newNice) != 0) {
65 std::string threadName(dvmGetThreadName(thread));
66 ALOGI("setPriority(%d) '%s' to prio=%d(n=%d) failed: %s",
67 pid, threadName.c_str(), newPriority, newNice, strerror(errno));
69 ALOGV("setPriority(%d) to prio=%d(n=%d)", pid, newPriority, newNice);
73 int os_getThreadPriorityFromSystem()
76 int sysprio = getpriority(PRIO_PROCESS, 0);
77 if (sysprio == -1 && errno != 0) {
78 ALOGW("getpriority() failed: %s", strerror(errno));
79 return THREAD_NORM_PRIORITY;
82 int jprio = THREAD_MIN_PRIORITY;
83 for (int i = 0; i < NELEM(kNiceValues); i++) {
84 if (sysprio >= kNiceValues[i]) {
89 if (jprio > THREAD_MAX_PRIORITY) {
90 jprio = THREAD_MAX_PRIORITY;
95 int os_raiseThreadPriority()
97 /* Get the priority (the "nice" value) of the current thread. The
98 * getpriority() call can legitimately return -1, so we have to
99 * explicitly test errno.
102 int oldThreadPriority = getpriority(PRIO_PROCESS, 0);
104 ALOGI("getpriority(self) failed: %s", strerror(errno));
105 } else if (oldThreadPriority > ANDROID_PRIORITY_NORMAL) {
106 /* Current value is numerically greater than "normal", which
107 * in backward UNIX terms means lower priority.
109 if (oldThreadPriority >= ANDROID_PRIORITY_BACKGROUND) {
110 set_sched_policy(dvmGetSysThreadId(), SP_FOREGROUND);
112 if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL) != 0) {
113 ALOGI("Unable to elevate priority from %d to %d",
114 oldThreadPriority, ANDROID_PRIORITY_NORMAL);
117 * The priority has been elevated. Return the old value
118 * so the caller can restore it later.
120 ALOGV("Elevating priority from %d to %d",
121 oldThreadPriority, ANDROID_PRIORITY_NORMAL);
122 return oldThreadPriority;
128 void os_lowerThreadPriority(int oldThreadPriority)
130 if (setpriority(PRIO_PROCESS, 0, oldThreadPriority) != 0) {
131 ALOGW("Unable to reset priority to %d: %s",
132 oldThreadPriority, strerror(errno));
134 ALOGV("Reset priority to %d", oldThreadPriority);
136 if (oldThreadPriority >= ANDROID_PRIORITY_BACKGROUND) {
137 set_sched_policy(dvmGetSysThreadId(), SP_BACKGROUND);