Fix setting/getting the native priority of a thread.
Bug: 138415922
Test: 720-thread-priority
Change-Id: I6e1f34fce3838b7904281be00f315e5b7ade0c78
(cherry picked from commit fa595885339140c3507f26d93cdc6b99081e23c5)
diff --git a/runtime/thread.cc b/runtime/thread.cc
index 70ed7c8..be0e30a 100644
--- a/runtime/thread.cc
+++ b/runtime/thread.cc
@@ -1833,8 +1833,11 @@
group_name_field->GetObject(thread_group)->AsString();
group_name = (group_name_string != nullptr) ? group_name_string->ToModifiedUtf8() : "<null>";
}
+ } else if (thread != nullptr) {
+ priority = thread->GetNativePriority();
} else {
- priority = GetNativePriority();
+ PaletteStatus status = PaletteSchedGetPriority(tid, &priority);
+ CHECK(status == PaletteStatus::kOkay || status == PaletteStatus::kCheckErrno);
}
std::string scheduler_group_name(GetSchedulerGroupName(tid));
@@ -4266,15 +4269,13 @@
}
void Thread::SetNativePriority(int new_priority) {
- // ART tests on JVM can reach this code path, use tid = 0 as shorthand for current thread.
- PaletteStatus status = PaletteSchedSetPriority(0, new_priority);
+ PaletteStatus status = PaletteSchedSetPriority(GetTid(), new_priority);
CHECK(status == PaletteStatus::kOkay || status == PaletteStatus::kCheckErrno);
}
-int Thread::GetNativePriority() {
+int Thread::GetNativePriority() const {
int priority = 0;
- // ART tests on JVM can reach this code path, use tid = 0 as shorthand for current thread.
- PaletteStatus status = PaletteSchedGetPriority(0, &priority);
+ PaletteStatus status = PaletteSchedGetPriority(GetTid(), &priority);
CHECK(status == PaletteStatus::kOkay || status == PaletteStatus::kCheckErrno);
return priority;
}
diff --git a/runtime/thread.h b/runtime/thread.h
index dd483c1..ae04600 100644
--- a/runtime/thread.h
+++ b/runtime/thread.h
@@ -375,12 +375,12 @@
void SetNativePriority(int newPriority);
/*
- * Returns the thread priority for the current thread by querying the system.
+ * Returns the priority of this thread by querying the system.
* This is useful when attaching a thread through JNI.
*
* Returns a value from 1 to 10 (compatible with java.lang.Thread values).
*/
- static int GetNativePriority();
+ int GetNativePriority() const;
// Guaranteed to be non-zero.
uint32_t GetThreadId() const {
diff --git a/test/720-thread-priority/expected.txt b/test/720-thread-priority/expected.txt
new file mode 100644
index 0000000..6a5618e
--- /dev/null
+++ b/test/720-thread-priority/expected.txt
@@ -0,0 +1 @@
+JNI_OnLoad called
diff --git a/test/720-thread-priority/info.txt b/test/720-thread-priority/info.txt
new file mode 100644
index 0000000..0122261
--- /dev/null
+++ b/test/720-thread-priority/info.txt
@@ -0,0 +1,2 @@
+Regression test for Thread.setPriority, which used to always set the priority
+to the main thread, instead of the passed one.
diff --git a/test/720-thread-priority/src/Main.java b/test/720-thread-priority/src/Main.java
new file mode 100644
index 0000000..9ea5cfc
--- /dev/null
+++ b/test/720-thread-priority/src/Main.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.util.concurrent.CountDownLatch;
+
+public class Main {
+ static final CountDownLatch processStarted = new CountDownLatch(1);
+ static final CountDownLatch prioritySet = new CountDownLatch(1);
+
+ static int initialPlatformPriority = 0;
+ static int maxPlatformPriority = 0;
+
+ static class MyThread extends Thread {
+ public void run() {
+ try {
+ int priority = getThreadPlatformPriority();
+ if (priority != initialPlatformPriority) {
+ throw new Error("Expected " + initialPlatformPriority + ", got " + priority);
+ }
+ processStarted.countDown();
+ prioritySet.await();
+ priority = getThreadPlatformPriority();
+ if (priority != maxPlatformPriority) {
+ throw new Error("Expected " + maxPlatformPriority + ", got " + priority);
+ }
+ } catch (Exception e) {
+ throw new Error(e);
+ }
+ }
+ }
+
+ public static void main(String[] args) throws Exception {
+ System.loadLibrary(args[0]);
+
+ // Fetch priorities from the main thread to know what to compare against.
+ int javaPriority = Thread.currentThread().getPriority();
+ initialPlatformPriority = getThreadPlatformPriority();
+ Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
+ maxPlatformPriority = getThreadPlatformPriority();
+ Thread.currentThread().setPriority(javaPriority);
+
+ MyThread t1 = new MyThread();
+ t1.start();
+ processStarted.await();
+
+ t1.setPriority(Thread.MAX_PRIORITY);
+ prioritySet.countDown();
+ t1.join();
+ }
+
+ private static native int getThreadPlatformPriority();
+}
diff --git a/test/720-thread-priority/thread_priority.cc b/test/720-thread-priority/thread_priority.cc
new file mode 100644
index 0000000..db4a2b2
--- /dev/null
+++ b/test/720-thread-priority/thread_priority.cc
@@ -0,0 +1,28 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <sys/time.h>
+#include <sys/resource.h>
+
+#include "base/macros.h"
+#include "base/utils.h"
+#include "jni.h"
+
+extern "C" JNIEXPORT jint JNICALL Java_Main_getThreadPlatformPriority(
+ JNIEnv* env ATTRIBUTE_UNUSED,
+ jclass clazz ATTRIBUTE_UNUSED) {
+ return getpriority(PRIO_PROCESS, art::GetTid());
+}
diff --git a/test/Android.bp b/test/Android.bp
index 9cf5606..cb9f612 100644
--- a/test/Android.bp
+++ b/test/Android.bp
@@ -496,6 +496,7 @@
"674-hiddenapi/hiddenapi.cc",
"692-vdex-inmem-loader/vdex_inmem_loader.cc",
"708-jit-cache-churn/jit.cc",
+ "720-thread-priority/thread_priority.cc",
"800-smali/jni.cc",
"909-attach-agent/disallow_debugging.cc",
"1001-app-image-regions/app_image_regions.cc",