summaryrefslogtreecommitdiffstats
path: root/vm/Native.c
diff options
context:
space:
mode:
authorAndy McFadden <fadden@android.com>2009-06-17 16:29:30 -0700
committerAndy McFadden <fadden@android.com>2009-06-17 16:55:40 -0700
commit2aa43610c391868eb6ef80bf3b1f947776defcca (patch)
tree3a212711da1c0177b47059d66994b6cffbe3e568 /vm/Native.c
parenteba51c25771a07993224e5ae74e8cac715985ba6 (diff)
downloadandroid_dalvik-2aa43610c391868eb6ef80bf3b1f947776defcca.tar.gz
android_dalvik-2aa43610c391868eb6ef80bf3b1f947776defcca.tar.bz2
android_dalvik-2aa43610c391868eb6ef80bf3b1f947776defcca.zip
Reduce VM aborts during high CPU stress.
The VM has some timeouts that are meant to kill the current process if something gets stuck (e.g. a thread grabs a lock and then manages to die while the rest of the process continues on). These were tripping a little too easily during some high-load situations. This changes the order of operations so that we now unlock the "thread suspend" lock before sending a wakeup broadcast to the condition variable that threads sleep on. This should make it less likely for a thread to be running for an extended period while the lock is held. (Relates to internal bug 1664687.) This also wraps a couple of things (pthread_create, dlopen) with a state change to VMWAIT. During high load situations these can take a while to complete, and we would (with the K-Means Visualizer load generator running) very occasionally time out. Augmented the debug output in a couple of minor ways. Updated comments.
Diffstat (limited to 'vm/Native.c')
-rw-r--r--vm/Native.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/vm/Native.c b/vm/Native.c
index 93bbc0702..dcfb46902 100644
--- a/vm/Native.c
+++ b/vm/Native.c
@@ -433,8 +433,16 @@ bool dvmLoadNativeCode(const char* pathName, Object* classLoader)
* - write a trivial app that calls sleep() then dlopen(), attach
* to it with "strace -p <pid>" while it sleeps, and watch for
* attempts to open nonexistent dependent shared libs
+ *
+ * This can execute slowly for a large library on a busy system, so we
+ * want to switch from RUNNING to VMWAIT while it executes. This allows
+ * the GC to ignore us.
*/
+ Thread* self = dvmThreadSelf();
+ int oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
handle = dlopen(pathName, RTLD_LAZY);
+ dvmChangeStatus(self, oldStatus);
+
if (handle == NULL) {
LOGI("Unable to dlopen(%s): %s\n", pathName, dlerror());
return false;
@@ -470,9 +478,9 @@ bool dvmLoadNativeCode(const char* pathName, Object* classLoader)
Object* prevOverride = self->classLoaderOverride;
self->classLoaderOverride = classLoader;
- dvmChangeStatus(NULL, THREAD_NATIVE);
+ oldStatus = dvmChangeStatus(self, THREAD_NATIVE);
version = (*func)(gDvm.vmList, NULL);
- dvmChangeStatus(NULL, THREAD_RUNNING);
+ dvmChangeStatus(self, oldStatus);
self->classLoaderOverride = prevOverride;
if (version != JNI_VERSION_1_2 && version != JNI_VERSION_1_4 &&