OSDN Git Service

Merge "More consistent JNI error reporting."
[android-x86/dalvik.git] / vm / os / android.cpp
1 /*
2  * Copyright (C) 2011 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 #include "os.h"
18
19 #include "Dalvik.h"
20
21 #include <sys/time.h>
22 #include <sys/resource.h>
23 #include <limits.h>
24 #include <errno.h>
25
26 #include <cutils/sched_policy.h>
27 #include <utils/threads.h>
28
29 /*
30  * Conversion map for "nice" values.
31  *
32  * We use Android thread priority constants to be consistent with the rest
33  * of the system.  In some cases adjacent entries may overlap.
34  */
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) */
46 };
47
48 void os_changeThreadPriority(Thread* thread, int newPriority)
49 {
50     if (newPriority < 1 || newPriority > 10) {
51         ALOGW("bad priority %d", newPriority);
52         newPriority = 5;
53     }
54
55     int newNice = kNiceValues[newPriority-1];
56     pid_t pid = thread->systemTid;
57
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);
62     }
63
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));
68     } else {
69         ALOGV("setPriority(%d) to prio=%d(n=%d)", pid, newPriority, newNice);
70     }
71 }
72
73 int os_getThreadPriorityFromSystem()
74 {
75     errno = 0;
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;
80     }
81
82     int jprio = THREAD_MIN_PRIORITY;
83     for (int i = 0; i < NELEM(kNiceValues); i++) {
84         if (sysprio >= kNiceValues[i]) {
85             break;
86         }
87         jprio++;
88     }
89     if (jprio > THREAD_MAX_PRIORITY) {
90         jprio = THREAD_MAX_PRIORITY;
91     }
92     return jprio;
93 }
94
95 int os_raiseThreadPriority()
96 {
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.
100      */
101     errno = 0;
102     int oldThreadPriority = getpriority(PRIO_PROCESS, 0);
103     if (errno != 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.
108          */
109         if (oldThreadPriority >= ANDROID_PRIORITY_BACKGROUND) {
110             set_sched_policy(dvmGetSysThreadId(), SP_FOREGROUND);
111         }
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);
115         } else {
116             /*
117              * The priority has been elevated.  Return the old value
118              * so the caller can restore it later.
119              */
120             ALOGV("Elevating priority from %d to %d",
121                     oldThreadPriority, ANDROID_PRIORITY_NORMAL);
122             return oldThreadPriority;
123         }
124     }
125     return INT_MAX;
126 }
127
128 void os_lowerThreadPriority(int oldThreadPriority)
129 {
130     if (setpriority(PRIO_PROCESS, 0, oldThreadPriority) != 0) {
131         ALOGW("Unable to reset priority to %d: %s",
132                 oldThreadPriority, strerror(errno));
133     } else {
134         ALOGV("Reset priority to %d", oldThreadPriority);
135     }
136     if (oldThreadPriority >= ANDROID_PRIORITY_BACKGROUND) {
137         set_sched_policy(dvmGetSysThreadId(), SP_BACKGROUND);
138     }
139 }