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 "thread.h" 18 19 #include <sys/time.h> 20 #include <sys/resource.h> 21 #include <limits.h> 22 #include <errno.h> 23 24 #include <cutils/sched_policy.h> 25 #include <utils/threads.h> 26 27 #include "base/macros.h" 28 29 namespace art { 30 31 // Conversion map for "nice" values. 32 // 33 // We use Android thread priority constants to be consistent with the rest 34 // of the system. In some cases adjacent entries may overlap. 35 // 36 static const int kNiceValues[10] = { 37 ANDROID_PRIORITY_LOWEST, // 1 (MIN_PRIORITY) 38 ANDROID_PRIORITY_BACKGROUND + 6, 39 ANDROID_PRIORITY_BACKGROUND + 3, 40 ANDROID_PRIORITY_BACKGROUND, 41 ANDROID_PRIORITY_NORMAL, // 5 (NORM_PRIORITY) 42 ANDROID_PRIORITY_NORMAL - 2, 43 ANDROID_PRIORITY_NORMAL - 4, 44 ANDROID_PRIORITY_URGENT_DISPLAY + 3, 45 ANDROID_PRIORITY_URGENT_DISPLAY + 2, 46 ANDROID_PRIORITY_URGENT_DISPLAY // 10 (MAX_PRIORITY) 47 }; 48 49 void Thread::SetNativePriority(int newPriority) { 50 if (newPriority < 1 || newPriority > 10) { 51 LOG(WARNING) << "bad priority " << newPriority; 52 newPriority = 5; 53 } 54 55 int newNice = kNiceValues[newPriority-1]; 56 pid_t tid = GetTid(); 57 58 // TODO: b/18249098 The code below is broken. It uses getpriority() as a proxy for whether a 59 // thread is already in the SP_FOREGROUND cgroup. This is not necessarily true for background 60 // processes, where all threads are in the SP_BACKGROUND cgroup. This means that callers will 61 // have to call setPriority twice to do what they want : 62 // 63 // Thread.setPriority(Thread.MIN_PRIORITY); // no-op wrt to cgroups 64 // Thread.setPriority(Thread.MAX_PRIORITY); // will actually change cgroups. 65 if (newNice >= ANDROID_PRIORITY_BACKGROUND) { 66 set_sched_policy(tid, SP_BACKGROUND); 67 } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) { 68 set_sched_policy(tid, SP_FOREGROUND); 69 } 70 71 if (setpriority(PRIO_PROCESS, tid, newNice) != 0) { 72 PLOG(INFO) << *this << " setPriority(PRIO_PROCESS, " << tid << ", " << newNice << ") failed"; 73 } 74 } 75 76 int Thread::GetNativePriority() { 77 errno = 0; 78 int native_priority = getpriority(PRIO_PROCESS, 0); 79 if (native_priority == -1 && errno != 0) { 80 PLOG(WARNING) << "getpriority failed"; 81 return kNormThreadPriority; 82 } 83 84 int managed_priority = kMinThreadPriority; 85 for (size_t i = 0; i < arraysize(kNiceValues); i++) { 86 if (native_priority >= kNiceValues[i]) { 87 break; 88 } 89 managed_priority++; 90 } 91 if (managed_priority > kMaxThreadPriority) { 92 managed_priority = kMaxThreadPriority; 93 } 94 return managed_priority; 95 } 96 97 void Thread::SetUpAlternateSignalStack() { 98 // Bionic does this for us. 99 } 100 101 void Thread::TearDownAlternateSignalStack() { 102 // Bionic does this for us. 103 } 104 105 } // namespace art 106