18daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes/*
28daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Copyright (C) 2011 The Android Open Source Project
38daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes *
48daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License");
58daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * you may not use this file except in compliance with the License.
68daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * You may obtain a copy of the License at
78daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes *
88daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes *      http://www.apache.org/licenses/LICENSE-2.0
98daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes *
108daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * Unless required by applicable law or agreed to in writing, software
118daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS,
128daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
138daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * See the License for the specific language governing permissions and
148daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes * limitations under the License.
158daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes */
168daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
178daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include "thread.h"
188daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
198daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include <sys/time.h>
208daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include <sys/resource.h>
218daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include <limits.h>
228daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include <errno.h>
238daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
248daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include <cutils/sched_policy.h>
258daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes#include <utils/threads.h>
268daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
27761600567d73b23324ae0251e871c15d6849ffd8Elliott Hughes#include "base/macros.h"
288daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
298daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesnamespace art {
308daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
3100e446e5d912100b831fdcdbc276e7c31447f0c4Elliott Hughes// Conversion map for "nice" values.
3200e446e5d912100b831fdcdbc276e7c31447f0c4Elliott Hughes//
3300e446e5d912100b831fdcdbc276e7c31447f0c4Elliott Hughes// We use Android thread priority constants to be consistent with the rest
3400e446e5d912100b831fdcdbc276e7c31447f0c4Elliott Hughes// of the system.  In some cases adjacent entries may overlap.
3500e446e5d912100b831fdcdbc276e7c31447f0c4Elliott Hughes//
368daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesstatic const int kNiceValues[10] = {
3700e446e5d912100b831fdcdbc276e7c31447f0c4Elliott Hughes  ANDROID_PRIORITY_LOWEST,                // 1 (MIN_PRIORITY)
388daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  ANDROID_PRIORITY_BACKGROUND + 6,
398daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  ANDROID_PRIORITY_BACKGROUND + 3,
408daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  ANDROID_PRIORITY_BACKGROUND,
4100e446e5d912100b831fdcdbc276e7c31447f0c4Elliott Hughes  ANDROID_PRIORITY_NORMAL,                // 5 (NORM_PRIORITY)
428daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  ANDROID_PRIORITY_NORMAL - 2,
438daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  ANDROID_PRIORITY_NORMAL - 4,
448daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  ANDROID_PRIORITY_URGENT_DISPLAY + 3,
458daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  ANDROID_PRIORITY_URGENT_DISPLAY + 2,
4600e446e5d912100b831fdcdbc276e7c31447f0c4Elliott Hughes  ANDROID_PRIORITY_URGENT_DISPLAY         // 10 (MAX_PRIORITY)
478daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes};
488daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
498daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesvoid Thread::SetNativePriority(int newPriority) {
508daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  if (newPriority < 1 || newPriority > 10) {
518daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    LOG(WARNING) << "bad priority " << newPriority;
528daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    newPriority = 5;
538daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
548daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
558daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  int newNice = kNiceValues[newPriority-1];
568daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  pid_t tid = GetTid();
578daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
581bd326a5e2aaff06a5bcae9cb2c42a4e8de31401Narayan Kamath  // TODO: b/18249098 The code below is broken. It uses getpriority() as a proxy for whether a
591bd326a5e2aaff06a5bcae9cb2c42a4e8de31401Narayan Kamath  // thread is already in the SP_FOREGROUND cgroup. This is not necessarily true for background
601bd326a5e2aaff06a5bcae9cb2c42a4e8de31401Narayan Kamath  // processes, where all threads are in the SP_BACKGROUND cgroup. This means that callers will
611bd326a5e2aaff06a5bcae9cb2c42a4e8de31401Narayan Kamath  // have to call setPriority twice to do what they want :
621bd326a5e2aaff06a5bcae9cb2c42a4e8de31401Narayan Kamath  //
631bd326a5e2aaff06a5bcae9cb2c42a4e8de31401Narayan Kamath  //     Thread.setPriority(Thread.MIN_PRIORITY);  // no-op wrt to cgroups
641bd326a5e2aaff06a5bcae9cb2c42a4e8de31401Narayan Kamath  //     Thread.setPriority(Thread.MAX_PRIORITY);  // will actually change cgroups.
658daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  if (newNice >= ANDROID_PRIORITY_BACKGROUND) {
668daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    set_sched_policy(tid, SP_BACKGROUND);
678daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  } else if (getpriority(PRIO_PROCESS, tid) >= ANDROID_PRIORITY_BACKGROUND) {
688daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    set_sched_policy(tid, SP_FOREGROUND);
698daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
708daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
718daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  if (setpriority(PRIO_PROCESS, tid, newNice) != 0) {
728daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    PLOG(INFO) << *this << " setPriority(PRIO_PROCESS, " << tid << ", " << newNice << ") failed";
738daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
748daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes}
758daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
768daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughesint Thread::GetNativePriority() {
778daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  errno = 0;
788daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  int native_priority = getpriority(PRIO_PROCESS, 0);
798daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  if (native_priority == -1 && errno != 0) {
808daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    PLOG(WARNING) << "getpriority failed";
8134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes    return kNormThreadPriority;
828daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
838daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
8434e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  int managed_priority = kMinThreadPriority;
858daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  for (size_t i = 0; i < arraysize(kNiceValues); i++) {
868daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    if (native_priority >= kNiceValues[i]) {
878daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes      break;
888daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    }
898daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes    managed_priority++;
908daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
9134e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes  if (managed_priority > kMaxThreadPriority) {
9234e069606d6f1698cd3c33b39e72b79ae27e1c7bElliott Hughes    managed_priority = kMaxThreadPriority;
938daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  }
948daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes  return managed_priority;
958daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes}
968daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes
97d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughesvoid Thread::SetUpAlternateSignalStack() {
98d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  // Bionic does this for us.
99d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes}
100d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes
101d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughesvoid Thread::TearDownAlternateSignalStack() {
102d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes  // Bionic does this for us.
103d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes}
104d6a23bd327c38b08aaf6846d426fd6824fe9780bElliott Hughes
1058daa0929f08a3080ea64dbd4e997e72f411e6fc9Elliott Hughes}  // namespace art
106