summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2011-06-15 11:12:05 -0700
committerElliott Hughes <enh@google.com>2011-06-15 11:12:05 -0700
commite6c0ef210ee6c62cf4c63d50c04f451d5fa505f5 (patch)
tree240858c4cd500ae6cfaf9b8ae9207caedd297a50
parent8c8d1594ae9c7b588bb990e7407f4baa6185ecb9 (diff)
downloadandroid_dalvik-e6c0ef210ee6c62cf4c63d50c04f451d5fa505f5.tar.gz
android_dalvik-e6c0ef210ee6c62cf4c63d50c04f451d5fa505f5.tar.bz2
android_dalvik-e6c0ef210ee6c62cf4c63d50c04f451d5fa505f5.zip
Break a dependency on frameworks/base when building a host VM.
These aren't necessarily good abstractions, but they're no worse than what we had, and having them factored out is a step in the right direction. Change-Id: I5b839608317d2ca1ca54d8a38624fb686f2c37de
-rw-r--r--dalvikvm/Android.mk2
-rw-r--r--dexopt/Android.mk4
-rw-r--r--libnativehelper/Android.mk8
-rw-r--r--unit-tests/Android.mk4
-rw-r--r--vm/Android.mk2
-rw-r--r--vm/Dvm.mk7
-rw-r--r--vm/Thread.cpp85
-rw-r--r--vm/alloc/Heap.cpp63
-rw-r--r--vm/os/android.cpp139
-rw-r--r--vm/os/linux.cpp39
-rw-r--r--vm/os/os.h50
11 files changed, 250 insertions, 153 deletions
diff --git a/dalvikvm/Android.mk b/dalvikvm/Android.mk
index 5960a4b84..734f6f55b 100644
--- a/dalvikvm/Android.mk
+++ b/dalvikvm/Android.mk
@@ -61,7 +61,7 @@ ifeq ($(WITH_HOST_DALVIK),true)
# OS X comes with all these libraries, so there is no need
# to build any of them. Note: OpenSSL consists of libssl
# and libcrypto.
- LOCAL_LDLIBS := -lffi -lssl -lcrypto -lz -lsqlite3
+ LOCAL_LDLIBS := -lffi -lssl -lcrypto -lz
else
LOCAL_LDLIBS += -ldl -lpthread
LOCAL_SHARED_LIBRARIES += libdvm libcrypto libicuuc libicui18n libssl
diff --git a/dexopt/Android.mk b/dexopt/Android.mk
index 04f2f971c..df8a82feb 100644
--- a/dexopt/Android.mk
+++ b/dexopt/Android.mk
@@ -43,7 +43,7 @@ endif
LOCAL_SRC_FILES := $(local_src_files)
LOCAL_C_INCLUDES := $(local_c_includes)
-LOCAL_SHARED_LIBRARIES := $(local_shared_libraries) libcutils libexpat liblog libnativehelper libutils libz
+LOCAL_SHARED_LIBRARIES := $(local_shared_libraries) libcutils libexpat liblog libnativehelper libz
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := dexopt
@@ -59,7 +59,7 @@ ifeq ($(WITH_HOST_DALVIK),true)
LOCAL_SRC_FILES := $(local_src_files)
LOCAL_C_INCLUDES := $(local_c_includes)
LOCAL_SHARED_LIBRARIES := $(local_shared_libraries)
- LOCAL_STATIC_LIBRARIES := libcutils libexpat liblog libnativehelper libutils libz
+ LOCAL_STATIC_LIBRARIES := libcutils libexpat liblog libnativehelper libz
LOCAL_LDLIBS += -ldl -lpthread
LOCAL_CFLAGS += -DANDROID_SMP=1
LOCAL_MODULE_TAGS := optional
diff --git a/libnativehelper/Android.mk b/libnativehelper/Android.mk
index 3b0b6dcac..dea09078f 100644
--- a/libnativehelper/Android.mk
+++ b/libnativehelper/Android.mk
@@ -34,7 +34,6 @@ shared_libraries := \
libcrypto \
libicui18n \
libicuuc \
- libsqlite \
libssl
static_libraries := \
@@ -52,7 +51,7 @@ include $(CLEAR_VARS)
LOCAL_SRC_FILES := $(src_files)
LOCAL_C_INCLUDES := $(c_includes)
LOCAL_STATIC_LIBRARIES := $(static_libraries)
-LOCAL_SHARED_LIBRARIES := $(shared_libraries) libcutils libexpat liblog libstlport libutils libz
+LOCAL_SHARED_LIBRARIES := $(shared_libraries) libcutils libexpat liblog libstlport libz
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := libnativehelper
@@ -74,11 +73,10 @@ ifeq ($(WITH_HOST_DALVIK),true)
ifeq ($(HOST_OS)-$(HOST_ARCH),darwin-x86)
# OSX has a lot of libraries built in, which we don't have to
# bother building; just include them on the ld line.
- LOCAL_LDLIBS := -lexpat -lssl -lz -lcrypto -licucore -lsqlite3
- LOCAL_WHOLE_STATIC_LIBRARIES += libutils
+ LOCAL_LDLIBS := -lexpat -lssl -lz -lcrypto -licucore
else
LOCAL_SHARED_LIBRARIES := $(shared_libraries)
- LOCAL_STATIC_LIBRARIES := libcutils libexpat liblog libutils libz
+ LOCAL_STATIC_LIBRARIES := libcutils libexpat liblog libz
endif
LOCAL_MODULE_TAGS := optional
diff --git a/unit-tests/Android.mk b/unit-tests/Android.mk
index e9b8a7466..62b666a20 100644
--- a/unit-tests/Android.mk
+++ b/unit-tests/Android.mk
@@ -34,7 +34,7 @@ LOCAL_C_INCLUDES += $(test_c_includes)
LOCAL_MODULE := $(test_module)
LOCAL_MODULE_TAGS := $(test_tags)
LOCAL_SRC_FILES := $(test_src_files)
-LOCAL_SHARED_LIBRARIES += libcutils libutils libdvm
+LOCAL_SHARED_LIBRARIES += libcutils libdvm
include $(BUILD_NATIVE_TEST)
# Build for the host.
@@ -46,5 +46,5 @@ include $(BUILD_NATIVE_TEST)
#LOCAL_MODULE_TAGS := $(test_tags)
#LOCAL_SRC_FILES := $(test_src_files)
#LOCAL_SHARED_LIBRARIES += libdvm libcrypto libssl libicuuc libicui18n
-#LOCAL_WHOLE_STATIC_LIBRARIES += libcutils libutils liblog libdvm
+#LOCAL_WHOLE_STATIC_LIBRARIES += libcutils liblog libdvm
#include $(BUILD_HOST_NATIVE_TEST)
diff --git a/vm/Android.mk b/vm/Android.mk
index 84a35e39b..b1f3d0d46 100644
--- a/vm/Android.mk
+++ b/vm/Android.mk
@@ -112,7 +112,7 @@ ifeq ($(WITH_HOST_DALVIK),true)
# Build as a WHOLE static library so dependencies are available at link
# time. When building this target as a regular static library, certain
# dependencies like expat are not found by the linker.
- LOCAL_WHOLE_STATIC_LIBRARIES += libexpat libcutils libdex liblog libnativehelper libutils libz
+ LOCAL_WHOLE_STATIC_LIBRARIES += libexpat libcutils libdex liblog libnativehelper libz
# The libffi from the source tree should never be used by host builds.
# The recommendation is that host builds should always either
diff --git a/vm/Dvm.mk b/vm/Dvm.mk
index 9688dfe15..72d92990e 100644
--- a/vm/Dvm.mk
+++ b/vm/Dvm.mk
@@ -188,6 +188,13 @@ LOCAL_SRC_FILES := \
test/TestHash.cpp \
test/TestIndirectRefTable.cpp
+# TODO: this is the wrong test, but what's the right one?
+ifeq ($(dvm_arch),arm)
+ LOCAL_SRC_FILES += os/android.cpp
+else
+ LOCAL_SRC_FILES += os/linux.cpp
+endif
+
WITH_COPYING_GC := $(strip $(WITH_COPYING_GC))
ifeq ($(WITH_COPYING_GC),true)
diff --git a/vm/Thread.cpp b/vm/Thread.cpp
index bef4bc623..3844b25e6 100644
--- a/vm/Thread.cpp
+++ b/vm/Thread.cpp
@@ -18,8 +18,7 @@
* Thread support.
*/
#include "Dalvik.h"
-
-#include "utils/threads.h" // need Android thread priorities
+#include "os/os.h"
#include <stdlib.h>
#include <unistd.h>
@@ -240,7 +239,6 @@ static void* internalThreadStart(void* arg);
static void threadExitUncaughtException(Thread* thread, Object* group);
static void threadExitCheck(void* arg);
static void waitForThreadSuspend(Thread* self, Thread* thread);
-static int getThreadPriorityFromSystem();
/*
* Initialize thread list and main thread's environment. We need to set
@@ -1889,7 +1887,7 @@ bool dvmAttachCurrentThread(const JavaVMAttachArgs* pArgs, bool isDaemon)
*/
JValue unused;
dvmCallMethod(self, init, threadObj, &unused, (Object*)pArgs->group,
- threadNameStr, getThreadPriorityFromSystem(), isDaemon);
+ threadNameStr, os_getThreadPriorityFromSystem(), isDaemon);
if (dvmCheckException(self)) {
LOGE("exception thrown while constructing attached thread object");
goto fail_unlink;
@@ -3075,89 +3073,12 @@ Thread* dvmGetThreadByThreadId(u4 threadId)
return thread;
}
-
-/*
- * Conversion map for "nice" values.
- *
- * We use Android thread priority constants to be consistent with the rest
- * of the system. In some cases adjacent entries may overlap.
- */
-static const int kNiceValues[10] = {
- ANDROID_PRIORITY_LOWEST, /* 1 (MIN_PRIORITY) */
- ANDROID_PRIORITY_BACKGROUND + 6,
- ANDROID_PRIORITY_BACKGROUND + 3,
- ANDROID_PRIORITY_BACKGROUND,
- ANDROID_PRIORITY_NORMAL, /* 5 (NORM_PRIORITY) */
- ANDROID_PRIORITY_NORMAL - 2,
- ANDROID_PRIORITY_NORMAL - 4,
- ANDROID_PRIORITY_URGENT_DISPLAY + 3,
- ANDROID_PRIORITY_URGENT_DISPLAY + 2,
- ANDROID_PRIORITY_URGENT_DISPLAY /* 10 (MAX_PRIORITY) */
-};
-
-/*
- * Change the priority of a system thread to match that of the Thread object.
- *
- * We map a priority value from 1-10 to Linux "nice" values, where lower
- * numbers indicate higher priority.
- */
void dvmChangeThreadPriority(Thread* thread, int newPriority)
{
- pid_t pid = thread->systemTid;
- int newNice;
-
- if (newPriority < 1 || newPriority > 10) {
- LOGW("bad priority %d", newPriority);
- newPriority = 5;
- }
- newNice = kNiceValues[newPriority-1];
-
- if (newNice >= ANDROID_PRIORITY_BACKGROUND) {
- set_sched_policy(dvmGetSysThreadId(), SP_BACKGROUND);
- } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
- set_sched_policy(dvmGetSysThreadId(), SP_FOREGROUND);
- }
-
- if (setpriority(PRIO_PROCESS, pid, newNice) != 0) {
- std::string threadName(dvmGetThreadName(thread));
- LOGI("setPriority(%d) '%s' to prio=%d(n=%d) failed: %s",
- pid, threadName.c_str(), newPriority, newNice, strerror(errno));
- } else {
- LOGV("setPriority(%d) to prio=%d(n=%d)", pid, newPriority, newNice);
- }
+ os_changeThreadPriority(thread, newPriority);
}
/*
- * Get the thread priority for the current 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 getThreadPriorityFromSystem()
-{
- int i, sysprio, jprio;
-
- errno = 0;
- sysprio = getpriority(PRIO_PROCESS, 0);
- if (sysprio == -1 && errno != 0) {
- LOGW("getpriority() failed: %s", strerror(errno));
- return THREAD_NORM_PRIORITY;
- }
-
- jprio = THREAD_MIN_PRIORITY;
- for (i = 0; i < NELEM(kNiceValues); i++) {
- if (sysprio >= kNiceValues[i])
- break;
- jprio++;
- }
- if (jprio > THREAD_MAX_PRIORITY)
- jprio = THREAD_MAX_PRIORITY;
-
- return jprio;
-}
-
-
-/*
* Return true if the thread is on gDvm.threadList.
* Caller should not hold gDvm.threadListLock.
*/
diff --git a/vm/alloc/Heap.cpp b/vm/alloc/Heap.cpp
index 534aad8a5..bd333221d 100644
--- a/vm/alloc/Heap.cpp
+++ b/vm/alloc/Heap.cpp
@@ -24,10 +24,7 @@
#include "alloc/DdmHeap.h"
#include "alloc/HeapSource.h"
#include "alloc/MarkSweep.h"
-
-#include "utils/threads.h" // need Android thread priorities
-
-#include <cutils/sched_policy.h>
+#include "os/os.h"
#include <sys/time.h>
#include <sys/resource.h>
@@ -443,60 +440,6 @@ static void verifyRootsAndHeap()
}
/*
- * Raises the scheduling priority of the current thread. Returns the
- * original priority if successful. Otherwise, returns INT_MAX on
- * failure.
- */
-static int raiseThreadPriority()
-{
- /* Get the priority (the "nice" value) of the current thread. The
- * getpriority() call can legitimately return -1, so we have to
- * explicitly test errno.
- */
- errno = 0;
- int oldThreadPriority = getpriority(PRIO_PROCESS, 0);
- if (errno != 0) {
- LOGI_HEAP("getpriority(self) failed: %s", strerror(errno));
- } else if (oldThreadPriority > ANDROID_PRIORITY_NORMAL) {
- /* Current value is numerically greater than "normal", which
- * in backward UNIX terms means lower priority.
- */
- if (oldThreadPriority >= ANDROID_PRIORITY_BACKGROUND) {
- set_sched_policy(dvmGetSysThreadId(), SP_FOREGROUND);
- }
- if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL) != 0) {
- LOGI_HEAP("Unable to elevate priority from %d to %d",
- oldThreadPriority, ANDROID_PRIORITY_NORMAL);
- } else {
- /*
- * The priority has been elevated. Return the old value
- * so the caller can restore it later.
- */
- LOGD_HEAP("Elevating priority from %d to %d",
- oldThreadPriority, ANDROID_PRIORITY_NORMAL);
- return oldThreadPriority;
- }
- }
- return INT_MAX;
-}
-
-/*
- * Sets the current thread scheduling priority.
- */
-static void setThreadPriority(int newThreadPriority)
-{
- if (setpriority(PRIO_PROCESS, 0, newThreadPriority) != 0) {
- LOGW_HEAP("Unable to reset priority to %d: %s",
- newThreadPriority, strerror(errno));
- } else {
- LOGD_HEAP("Reset priority to %d", oldThreadPriority);
- }
- if (newThreadPriority >= ANDROID_PRIORITY_BACKGROUND) {
- set_sched_policy(dvmGetSysThreadId(), SP_BACKGROUND);
- }
-}
-
-/*
* Initiate garbage collection.
*
* NOTES:
@@ -541,7 +484,7 @@ void dvmCollectGarbageInternal(const GcSpec* spec)
* thread performing the garbage collection.
*/
if (!spec->isConcurrent) {
- oldThreadPriority = raiseThreadPriority();
+ oldThreadPriority = os_raiseThreadPriority();
}
if (gDvm.preVerify) {
LOGV_HEAP("Verifying roots and heap before GC");
@@ -704,7 +647,7 @@ void dvmCollectGarbageInternal(const GcSpec* spec)
* changed at the start of the current garbage collection.
*/
if (oldThreadPriority != INT_MAX) {
- setThreadPriority(oldThreadPriority);
+ os_lowerThreadPriority(oldThreadPriority);
}
}
diff --git a/vm/os/android.cpp b/vm/os/android.cpp
new file mode 100644
index 000000000..b7e5df5ac
--- /dev/null
+++ b/vm/os/android.cpp
@@ -0,0 +1,139 @@
+/*
+ * Copyright (C) 2011 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 "os.h"
+
+#include "Dalvik.h"
+
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <limits.h>
+#include <errno.h>
+
+#include <cutils/sched_policy.h>
+#include <utils/threads.h>
+
+/*
+ * Conversion map for "nice" values.
+ *
+ * We use Android thread priority constants to be consistent with the rest
+ * of the system. In some cases adjacent entries may overlap.
+ */
+static const int kNiceValues[10] = {
+ ANDROID_PRIORITY_LOWEST, /* 1 (MIN_PRIORITY) */
+ ANDROID_PRIORITY_BACKGROUND + 6,
+ ANDROID_PRIORITY_BACKGROUND + 3,
+ ANDROID_PRIORITY_BACKGROUND,
+ ANDROID_PRIORITY_NORMAL, /* 5 (NORM_PRIORITY) */
+ ANDROID_PRIORITY_NORMAL - 2,
+ ANDROID_PRIORITY_NORMAL - 4,
+ ANDROID_PRIORITY_URGENT_DISPLAY + 3,
+ ANDROID_PRIORITY_URGENT_DISPLAY + 2,
+ ANDROID_PRIORITY_URGENT_DISPLAY /* 10 (MAX_PRIORITY) */
+};
+
+void os_changeThreadPriority(Thread* thread, int newPriority)
+{
+ if (newPriority < 1 || newPriority > 10) {
+ LOGW("bad priority %d", newPriority);
+ newPriority = 5;
+ }
+
+ int newNice = kNiceValues[newPriority-1];
+ pid_t pid = thread->systemTid;
+
+ if (newNice >= ANDROID_PRIORITY_BACKGROUND) {
+ set_sched_policy(dvmGetSysThreadId(), SP_BACKGROUND);
+ } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
+ set_sched_policy(dvmGetSysThreadId(), SP_FOREGROUND);
+ }
+
+ if (setpriority(PRIO_PROCESS, pid, newNice) != 0) {
+ std::string threadName(dvmGetThreadName(thread));
+ LOGI("setPriority(%d) '%s' to prio=%d(n=%d) failed: %s",
+ pid, threadName.c_str(), newPriority, newNice, strerror(errno));
+ } else {
+ LOGV("setPriority(%d) to prio=%d(n=%d)", pid, newPriority, newNice);
+ }
+}
+
+int os_getThreadPriorityFromSystem()
+{
+ errno = 0;
+ int sysprio = getpriority(PRIO_PROCESS, 0);
+ if (sysprio == -1 && errno != 0) {
+ LOGW("getpriority() failed: %s", strerror(errno));
+ return THREAD_NORM_PRIORITY;
+ }
+
+ int jprio = THREAD_MIN_PRIORITY;
+ for (int i = 0; i < NELEM(kNiceValues); i++) {
+ if (sysprio >= kNiceValues[i]) {
+ break;
+ }
+ jprio++;
+ }
+ if (jprio > THREAD_MAX_PRIORITY) {
+ jprio = THREAD_MAX_PRIORITY;
+ }
+ return jprio;
+}
+
+int os_raiseThreadPriority()
+{
+ /* Get the priority (the "nice" value) of the current thread. The
+ * getpriority() call can legitimately return -1, so we have to
+ * explicitly test errno.
+ */
+ errno = 0;
+ int oldThreadPriority = getpriority(PRIO_PROCESS, 0);
+ if (errno != 0) {
+ LOGI("getpriority(self) failed: %s", strerror(errno));
+ } else if (oldThreadPriority > ANDROID_PRIORITY_NORMAL) {
+ /* Current value is numerically greater than "normal", which
+ * in backward UNIX terms means lower priority.
+ */
+ if (oldThreadPriority >= ANDROID_PRIORITY_BACKGROUND) {
+ set_sched_policy(dvmGetSysThreadId(), SP_FOREGROUND);
+ }
+ if (setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_NORMAL) != 0) {
+ LOGI("Unable to elevate priority from %d to %d",
+ oldThreadPriority, ANDROID_PRIORITY_NORMAL);
+ } else {
+ /*
+ * The priority has been elevated. Return the old value
+ * so the caller can restore it later.
+ */
+ LOGD("Elevating priority from %d to %d",
+ oldThreadPriority, ANDROID_PRIORITY_NORMAL);
+ return oldThreadPriority;
+ }
+ }
+ return INT_MAX;
+}
+
+void os_lowerThreadPriority(int oldThreadPriority)
+{
+ if (setpriority(PRIO_PROCESS, 0, oldThreadPriority) != 0) {
+ LOGW("Unable to reset priority to %d: %s",
+ oldThreadPriority, strerror(errno));
+ } else {
+ LOGD("Reset priority to %d", oldThreadPriority);
+ }
+ if (oldThreadPriority >= ANDROID_PRIORITY_BACKGROUND) {
+ set_sched_policy(dvmGetSysThreadId(), SP_BACKGROUND);
+ }
+}
diff --git a/vm/os/linux.cpp b/vm/os/linux.cpp
new file mode 100644
index 000000000..172cd059f
--- /dev/null
+++ b/vm/os/linux.cpp
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2011 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 "os.h"
+
+#include "Dalvik.h"
+
+int os_raiseThreadPriority()
+{
+ return 0;
+}
+
+void os_lowerThreadPriority(int oldThreadPriority)
+{
+ // Do nothing.
+}
+
+void os_changeThreadPriority(Thread* thread, int newPriority)
+{
+ // Do nothing.
+}
+
+int os_getThreadPriorityFromSystem()
+{
+ return THREAD_NORM_PRIORITY;
+}
diff --git a/vm/os/os.h b/vm/os/os.h
new file mode 100644
index 000000000..19e2a6168
--- /dev/null
+++ b/vm/os/os.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2011 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.
+ */
+
+struct Thread;
+
+/*
+ * Raises the scheduling priority of the current thread. Returns the
+ * original priority if successful, or INT_MAX on failure.
+ * Use os_lowerThreadPriority to undo.
+ *
+ * TODO: does the GC really need this?
+ */
+int os_raiseThreadPriority();
+
+/*
+ * Sets the current thread scheduling priority. Used to undo the effects
+ * of an earlier call to os_raiseThreadPriority.
+ *
+ * TODO: does the GC really need this?
+ */
+void os_lowerThreadPriority(int oldThreadPriority);
+
+/*
+ * Changes the priority of a system thread to match that of the Thread object.
+ *
+ * We map a priority value from 1-10 to Linux "nice" values, where lower
+ * numbers indicate higher priority.
+ */
+void os_changeThreadPriority(Thread* thread, int newPriority);
+
+/*
+ * Returns the thread priority for the current 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).
+ */
+int os_getThreadPriorityFromSystem();