From: Elliott Hughes Date: Wed, 15 Jun 2011 18:12:05 +0000 (-0700) Subject: Break a dependency on frameworks/base when building a host VM. X-Git-Tag: android-x86-4.0-r1~110^2~10 X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=e6c0ef210ee6c62cf4c63d50c04f451d5fa505f5;p=android-x86%2Fdalvik.git 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 --- 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 #include @@ -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 +#include "os/os.h" #include #include @@ -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 +#include +#include +#include + +#include +#include + +/* + * 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();