2 * Copyright (C) 2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
21 #include "native/SystemThread.h"
23 #include "utils/threads.h" // need Android thread priorities
28 #include <sys/resource.h>
33 #include <cutils/sched_policy.h>
35 #if defined(HAVE_PRCTL)
36 #include <sys/prctl.h>
39 #if defined(WITH_SELF_VERIFICATION)
40 #include "interp/Jit.h" // need for self verification
44 /* desktop Linux needs a little help with gettid() */
45 #if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS)
47 # include <linux/unistd.h>
49 _syscall0(pid_t,gettid)
51 pid_t gettid() { return syscall(__NR_gettid);}
56 // Change this to enable logging on cgroup errors
57 #define ENABLE_CGROUP_ERR_LOGGING 0
59 // change this to LOGV/LOGD to debug thread activity
60 #define LOG_THREAD LOGVV
65 All threads are native pthreads. All threads, except the JDWP debugger
66 thread, are visible to code running in the VM and to the debugger. (We
67 don't want the debugger to try to manipulate the thread that listens for
68 instructions from the debugger.) Internal VM threads are in the "system"
69 ThreadGroup, all others are in the "main" ThreadGroup, per convention.
71 The GC only runs when all threads have been suspended. Threads are
72 expected to suspend themselves, using a "safe point" mechanism. We check
73 for a suspend request at certain points in the main interpreter loop,
74 and on requests coming in from native code (e.g. all JNI functions).
75 Certain debugger events may inspire threads to self-suspend.
77 Native methods must use JNI calls to modify object references to avoid
78 clashes with the GC. JNI doesn't provide a way for native code to access
79 arrays of objects as such -- code must always get/set individual entries --
80 so it should be possible to fully control access through JNI.
82 Internal native VM threads, such as the finalizer thread, must explicitly
83 check for suspension periodically. In most cases they will be sound
84 asleep on a condition variable, and won't notice the suspension anyway.
86 Threads may be suspended by the GC, debugger, or the SIGQUIT listener
87 thread. The debugger may suspend or resume individual threads, while the
88 GC always suspends all threads. Each thread has a "suspend count" that
89 is incremented on suspend requests and decremented on resume requests.
90 When the count is zero, the thread is runnable. This allows us to fulfill
91 a debugger requirement: if the debugger suspends a thread, the thread is
92 not allowed to run again until the debugger resumes it (or disconnects,
93 in which case we must resume all debugger-suspended threads).
95 Paused threads sleep on a condition variable, and are awoken en masse.
96 Certain "slow" VM operations, such as starting up a new thread, will be
97 done in a separate "VMWAIT" state, so that the rest of the VM doesn't
98 freeze up waiting for the operation to finish. Threads must check for
99 pending suspension when leaving VMWAIT.
101 Because threads suspend themselves while interpreting code or when native
102 code makes JNI calls, there is no risk of suspending while holding internal
103 VM locks. All threads can enter a suspended (or native-code-only) state.
104 Also, we don't have to worry about object references existing solely
105 in hardware registers.
107 We do, however, have to worry about objects that were allocated internally
108 and aren't yet visible to anything else in the VM. If we allocate an
109 object, and then go to sleep on a mutex after changing to a non-RUNNING
110 state (e.g. while trying to allocate a second object), the first object
111 could be garbage-collected out from under us while we sleep. To manage
112 this, we automatically add all allocated objects to an internal object
113 tracking list, and only remove them when we know we won't be suspended
114 before the object appears in the GC root set.
116 The debugger may choose to suspend or resume a single thread, which can
117 lead to application-level deadlocks; this is expected behavior. The VM
118 will only check for suspension of single threads when the debugger is
119 active (the java.lang.Thread calls for this are deprecated and hence are
120 not supported). Resumption of a single thread is handled by decrementing
121 the thread's suspend count and sending a broadcast signal to the condition
122 variable. (This will cause all threads to wake up and immediately go back
123 to sleep, which isn't tremendously efficient, but neither is having the
126 The debugger is not allowed to resume threads suspended by the GC. This
127 is trivially enforced by ignoring debugger requests while the GC is running
128 (the JDWP thread is suspended during GC).
130 The VM maintains a Thread struct for every pthread known to the VM. There
131 is a java/lang/Thread object associated with every Thread. At present,
132 there is no safe way to go from a Thread object to a Thread struct except by
133 locking and scanning the list; this is necessary because the lifetimes of
134 the two are not closely coupled. We may want to change this behavior,
135 though at present the only performance impact is on the debugger (see
136 threadObjToThread()). See also notes about dvmDetachCurrentThread().
139 Alternate implementation (signal-based):
141 Threads run without safe points -- zero overhead. The VM uses a signal
142 (e.g. pthread_kill(SIGUSR1)) to notify threads of suspension or resumption.
144 The trouble with using signals to suspend threads is that it means a thread
145 can be in the middle of an operation when garbage collection starts.
146 To prevent some sticky situations, we have to introduce critical sections
149 Critical sections temporarily block suspension for a given thread.
150 The thread must move to a non-blocked state (and self-suspend) after
151 finishing its current task. If the thread blocks on a resource held
152 by a suspended thread, we're hosed.
154 One approach is to require that no blocking operations, notably
155 acquisition of mutexes, can be performed within a critical section.
156 This is too limiting. For example, if thread A gets suspended while
157 holding the thread list lock, it will prevent the GC or debugger from
158 being able to safely access the thread list. We need to wrap the critical
159 section around the entire operation (enter critical, get lock, do stuff,
160 release lock, exit critical).
162 A better approach is to declare that certain resources can only be held
163 within critical sections. A thread that enters a critical section and
164 then gets blocked on the thread list lock knows that the thread it is
165 waiting for is also in a critical section, and will release the lock
166 before suspending itself. Eventually all threads will complete their
167 operations and self-suspend. For this to work, the VM must:
169 (1) Determine the set of resources that may be accessed from the GC or
170 debugger threads. The mutexes guarding those go into the "critical
172 (2) Ensure that no resource in the CRS can be acquired outside of a
173 critical section. This can be verified with an assert().
174 (3) Ensure that only resources in the CRS can be held while in a critical
175 section. This is harder to enforce.
177 If any of these conditions are not met, deadlock can ensue when grabbing
178 resources in the GC or debugger (#1) or waiting for threads to suspend
179 (#2,#3). (You won't actually deadlock in the GC, because if the semantics
180 above are followed you don't need to lock anything in the GC. The risk is
181 rather that the GC will access data structures in an intermediate state.)
183 This approach requires more care and awareness in the VM than
184 safe-pointing. Because the GC and debugger are fairly intrusive, there
185 really aren't any internal VM resources that aren't shared. Thus, the
186 enter/exit critical calls can be added to internal mutex wrappers, which
187 makes it easy to get #1 and #2 right.
189 An ordering should be established for all locks to avoid deadlocks.
191 Monitor locks, which are also implemented with pthread calls, should not
192 cause any problems here. Threads fighting over such locks will not be in
193 critical sections and can be suspended freely.
195 This can get tricky if we ever need exclusive access to VM and non-VM
196 resources at the same time. It's not clear if this is a real concern.
198 There are (at least) two ways to handle the incoming signals:
200 (a) Always accept signals. If we're in a critical section, the signal
201 handler just returns without doing anything (the "suspend level"
202 should have been incremented before the signal was sent). Otherwise,
203 if the "suspend level" is nonzero, we go to sleep.
204 (b) Block signals in critical sections. This ensures that we can't be
205 interrupted in a critical section, but requires pthread_sigmask()
206 calls on entry and exit.
208 This is a choice between blocking the message and blocking the messenger.
209 Because UNIX signals are unreliable (you can only know that you have been
210 signaled, not whether you were signaled once or 10 times), the choice is
211 not significant for correctness. The choice depends on the efficiency
212 of pthread_sigmask() and the desire to actually block signals. Either way,
213 it is best to ensure that there is only one indication of "blocked";
214 having two (i.e. block signals and set a flag, then only send a signal
215 if the flag isn't set) can lead to race conditions.
217 The signal handler must take care to copy registers onto the stack (via
218 setjmp), so that stack scans find all references. Because we have to scan
219 native stacks, "exact" GC is not possible with this approach.
221 Some other concerns with flinging signals around:
222 - Odd interactions with some debuggers (e.g. gdb on the Mac)
223 - Restrictions on some standard library calls during GC (e.g. don't
224 use printf on stdout to print GC debug messages)
227 #define kMaxThreadId ((1<<15) - 1)
228 #define kMainThreadId ((1<<1) | 1)
231 static Thread* allocThread(int interpStackSize);
232 static bool prepareThread(Thread* thread);
233 static void setThreadSelf(Thread* thread);
234 static void unlinkThread(Thread* thread);
235 static void freeThread(Thread* thread);
236 static void assignThreadId(Thread* thread);
237 static bool createFakeEntryFrame(Thread* thread);
238 static bool createFakeRunFrame(Thread* thread);
239 static void* interpThreadStart(void* arg);
240 static void* internalThreadStart(void* arg);
241 static void threadExitUncaughtException(Thread* thread, Object* group);
242 static void threadExitCheck(void* arg);
243 static void waitForThreadSuspend(Thread* self, Thread* thread);
244 static int getThreadPriorityFromSystem(void);
247 * The JIT needs to know if any thread is suspended. We do this by
248 * maintaining a global sum of all threads' suspend counts. All suspendCount
249 * updates should go through this after aquiring threadSuspendCountLock.
251 static inline void dvmAddToThreadSuspendCount(int *pSuspendCount, int delta)
253 *pSuspendCount += delta;
254 gDvm.sumThreadSuspendCount += delta;
258 * Initialize thread list and main thread's environment. We need to set
259 * up some basic stuff so that dvmThreadSelf() will work when we start
260 * loading classes (e.g. to check for exceptions).
262 bool dvmThreadStartup(void)
266 /* allocate a TLS slot */
267 if (pthread_key_create(&gDvm.pthreadKeySelf, threadExitCheck) != 0) {
268 LOGE("ERROR: pthread_key_create failed\n");
272 /* test our pthread lib */
273 if (pthread_getspecific(gDvm.pthreadKeySelf) != NULL)
274 LOGW("WARNING: newly-created pthread TLS slot is not NULL\n");
276 /* prep thread-related locks and conditions */
277 dvmInitMutex(&gDvm.threadListLock);
278 pthread_cond_init(&gDvm.threadStartCond, NULL);
279 //dvmInitMutex(&gDvm.vmExitLock);
280 pthread_cond_init(&gDvm.vmExitCond, NULL);
281 dvmInitMutex(&gDvm._threadSuspendLock);
282 dvmInitMutex(&gDvm.threadSuspendCountLock);
283 pthread_cond_init(&gDvm.threadSuspendCountCond, NULL);
284 #ifdef WITH_DEADLOCK_PREDICTION
285 dvmInitMutex(&gDvm.deadlockHistoryLock);
289 * Dedicated monitor for Thread.sleep().
290 * TODO: change this to an Object* so we don't have to expose this
291 * call, and we interact better with JDWP monitor calls. Requires
292 * deferring the object creation to much later (e.g. final "main"
293 * thread prep) or until first use.
295 gDvm.threadSleepMon = dvmCreateMonitor(NULL);
297 gDvm.threadIdMap = dvmAllocBitVector(kMaxThreadId, false);
299 thread = allocThread(gDvm.stackSize);
303 /* switch mode for when we run initializers */
304 thread->status = THREAD_RUNNING;
307 * We need to assign the threadId early so we can lock/notify
308 * object monitors. We'll set the "threadObj" field later.
310 prepareThread(thread);
311 gDvm.threadList = thread;
313 #ifdef COUNT_PRECISE_METHODS
314 gDvm.preciseMethods = dvmPointerSetAlloc(200);
321 * We're a little farther up now, and can load some basic classes.
323 * We're far enough along that we can poke at java.lang.Thread and friends,
324 * but should not assume that static initializers have run (or cause them
325 * to do so). That means no object allocations yet.
327 bool dvmThreadObjStartup(void)
330 * Cache the locations of these classes. It's likely that we're the
331 * first to reference them, so they're being loaded now.
333 gDvm.classJavaLangThread =
334 dvmFindSystemClassNoInit("Ljava/lang/Thread;");
335 gDvm.classJavaLangVMThread =
336 dvmFindSystemClassNoInit("Ljava/lang/VMThread;");
337 gDvm.classJavaLangThreadGroup =
338 dvmFindSystemClassNoInit("Ljava/lang/ThreadGroup;");
339 if (gDvm.classJavaLangThread == NULL ||
340 gDvm.classJavaLangThreadGroup == NULL ||
341 gDvm.classJavaLangThreadGroup == NULL)
343 LOGE("Could not find one or more essential thread classes\n");
348 * Cache field offsets. This makes things a little faster, at the
349 * expense of hard-coding non-public field names into the VM.
351 gDvm.offJavaLangThread_vmThread =
352 dvmFindFieldOffset(gDvm.classJavaLangThread,
353 "vmThread", "Ljava/lang/VMThread;");
354 gDvm.offJavaLangThread_group =
355 dvmFindFieldOffset(gDvm.classJavaLangThread,
356 "group", "Ljava/lang/ThreadGroup;");
357 gDvm.offJavaLangThread_daemon =
358 dvmFindFieldOffset(gDvm.classJavaLangThread, "daemon", "Z");
359 gDvm.offJavaLangThread_name =
360 dvmFindFieldOffset(gDvm.classJavaLangThread,
361 "name", "Ljava/lang/String;");
362 gDvm.offJavaLangThread_priority =
363 dvmFindFieldOffset(gDvm.classJavaLangThread, "priority", "I");
365 if (gDvm.offJavaLangThread_vmThread < 0 ||
366 gDvm.offJavaLangThread_group < 0 ||
367 gDvm.offJavaLangThread_daemon < 0 ||
368 gDvm.offJavaLangThread_name < 0 ||
369 gDvm.offJavaLangThread_priority < 0)
371 LOGE("Unable to find all fields in java.lang.Thread\n");
375 gDvm.offJavaLangVMThread_thread =
376 dvmFindFieldOffset(gDvm.classJavaLangVMThread,
377 "thread", "Ljava/lang/Thread;");
378 gDvm.offJavaLangVMThread_vmData =
379 dvmFindFieldOffset(gDvm.classJavaLangVMThread, "vmData", "I");
380 if (gDvm.offJavaLangVMThread_thread < 0 ||
381 gDvm.offJavaLangVMThread_vmData < 0)
383 LOGE("Unable to find all fields in java.lang.VMThread\n");
388 * Cache the vtable offset for "run()".
390 * We don't want to keep the Method* because then we won't find see
391 * methods defined in subclasses.
394 meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThread, "run", "()V");
396 LOGE("Unable to find run() in java.lang.Thread\n");
399 gDvm.voffJavaLangThread_run = meth->methodIndex;
402 * Cache vtable offsets for ThreadGroup methods.
404 meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThreadGroup,
405 "removeThread", "(Ljava/lang/Thread;)V");
407 LOGE("Unable to find removeThread(Thread) in java.lang.ThreadGroup\n");
410 gDvm.voffJavaLangThreadGroup_removeThread = meth->methodIndex;
416 * All threads should be stopped by now. Clean up some thread globals.
418 void dvmThreadShutdown(void)
420 if (gDvm.threadList != NULL) {
422 * If we walk through the thread list and try to free the
423 * lingering thread structures (which should only be for daemon
424 * threads), the daemon threads may crash if they execute before
425 * the process dies. Let them leak.
427 freeThread(gDvm.threadList);
428 gDvm.threadList = NULL;
431 dvmFreeBitVector(gDvm.threadIdMap);
433 dvmFreeMonitorList();
435 pthread_key_delete(gDvm.pthreadKeySelf);
440 * Grab the suspend count global lock.
442 static inline void lockThreadSuspendCount(void)
445 * Don't try to change to VMWAIT here. When we change back to RUNNING
446 * we have to check for a pending suspend, which results in grabbing
447 * this lock recursively. Doesn't work with "fast" pthread mutexes.
449 * This lock is always held for very brief periods, so as long as
450 * mutex ordering is respected we shouldn't stall.
452 int cc = pthread_mutex_lock(&gDvm.threadSuspendCountLock);
457 * Release the suspend count global lock.
459 static inline void unlockThreadSuspendCount(void)
461 dvmUnlockMutex(&gDvm.threadSuspendCountLock);
465 * Grab the thread list global lock.
467 * This is held while "suspend all" is trying to make everybody stop. If
468 * the shutdown is in progress, and somebody tries to grab the lock, they'll
469 * have to wait for the GC to finish. Therefore it's important that the
470 * thread not be in RUNNING mode.
472 * We don't have to check to see if we should be suspended once we have
473 * the lock. Nobody can suspend all threads without holding the thread list
474 * lock while they do it, so by definition there isn't a GC in progress.
476 * TODO: consider checking for suspend after acquiring the lock, and
477 * backing off if set. As stated above, it can't happen during normal
478 * execution, but it *can* happen during shutdown when daemon threads
479 * are being suspended.
481 void dvmLockThreadList(Thread* self)
483 ThreadStatus oldStatus;
485 if (self == NULL) /* try to get it from TLS */
486 self = dvmThreadSelf();
489 oldStatus = self->status;
490 self->status = THREAD_VMWAIT;
492 /* happens during VM shutdown */
493 //LOGW("NULL self in dvmLockThreadList\n");
494 oldStatus = -1; // shut up gcc
497 int cc = pthread_mutex_lock(&gDvm.threadListLock);
501 self->status = oldStatus;
505 * Release the thread list global lock.
507 void dvmUnlockThreadList(void)
509 int cc = pthread_mutex_unlock(&gDvm.threadListLock);
514 * Convert SuspendCause to a string.
516 static const char* getSuspendCauseStr(SuspendCause why)
519 case SUSPEND_NOT: return "NOT?";
520 case SUSPEND_FOR_GC: return "gc";
521 case SUSPEND_FOR_DEBUG: return "debug";
522 case SUSPEND_FOR_DEBUG_EVENT: return "debug-event";
523 case SUSPEND_FOR_STACK_DUMP: return "stack-dump";
524 #if defined(WITH_JIT)
525 case SUSPEND_FOR_TBL_RESIZE: return "table-resize";
526 case SUSPEND_FOR_IC_PATCH: return "inline-cache-patch";
527 case SUSPEND_FOR_CC_RESET: return "reset-code-cache";
529 default: return "UNKNOWN";
534 * Grab the "thread suspend" lock. This is required to prevent the
535 * GC and the debugger from simultaneously suspending all threads.
537 * If we fail to get the lock, somebody else is trying to suspend all
538 * threads -- including us. If we go to sleep on the lock we'll deadlock
539 * the VM. Loop until we get it or somebody puts us to sleep.
541 static void lockThreadSuspend(const char* who, SuspendCause why)
543 const int kSpinSleepTime = 3*1000*1000; /* 3s */
544 u8 startWhen = 0; // init req'd to placate gcc
549 cc = pthread_mutex_trylock(&gDvm._threadSuspendLock);
551 if (!dvmCheckSuspendPending(NULL)) {
553 * Could be that a resume-all is in progress, and something
554 * grabbed the CPU when the wakeup was broadcast. The thread
555 * performing the resume hasn't had a chance to release the
556 * thread suspend lock. (We release before the broadcast,
557 * so this should be a narrow window.)
559 * Could be we hit the window as a suspend was started,
560 * and the lock has been grabbed but the suspend counts
561 * haven't been incremented yet.
563 * Could be an unusual JNI thread-attach thing.
565 * Could be the debugger telling us to resume at roughly
566 * the same time we're posting an event.
568 * Could be two app threads both want to patch predicted
569 * chaining cells around the same time.
571 LOGI("threadid=%d ODD: want thread-suspend lock (%s:%s),"
572 " it's held, no suspend pending\n",
573 dvmThreadSelf()->threadId, who, getSuspendCauseStr(why));
575 /* we suspended; reset timeout */
579 /* give the lock-holder a chance to do some work */
581 startWhen = dvmGetRelativeTimeUsec();
582 if (!dvmIterativeSleep(sleepIter++, kSpinSleepTime, startWhen)) {
583 LOGE("threadid=%d: couldn't get thread-suspend lock (%s:%s),"
585 dvmThreadSelf()->threadId, who, getSuspendCauseStr(why));
586 /* threads are not suspended, thread dump could crash */
587 dvmDumpAllThreads(false);
596 * Release the "thread suspend" lock.
598 static inline void unlockThreadSuspend(void)
600 int cc = pthread_mutex_unlock(&gDvm._threadSuspendLock);
606 * Kill any daemon threads that still exist. All of ours should be
607 * stopped, so these should be Thread objects or JNI-attached threads
608 * started by the application. Actively-running threads are likely
609 * to crash the process if they continue to execute while the VM
610 * shuts down, so we really need to kill or suspend them. (If we want
611 * the VM to restart within this process, we need to kill them, but that
612 * leaves open the possibility of orphaned resources.)
614 * Waiting for the thread to suspend may be unwise at this point, but
615 * if one of these is wedged in a critical section then we probably
616 * would've locked up on the last GC attempt.
618 * It's possible for this function to get called after a failed
619 * initialization, so be careful with assumptions about the environment.
621 * This will be called from whatever thread calls DestroyJavaVM, usually
622 * but not necessarily the main thread. It's likely, but not guaranteed,
623 * that the current thread has already been cleaned up.
625 void dvmSlayDaemons(void)
627 Thread* self = dvmThreadSelf(); // may be null
632 //dvmEnterCritical(self);
633 dvmLockThreadList(self);
636 threadId = self->threadId;
638 target = gDvm.threadList;
639 while (target != NULL) {
640 if (target == self) {
641 target = target->next;
645 if (!dvmGetFieldBoolean(target->threadObj,
646 gDvm.offJavaLangThread_daemon))
648 /* should never happen; suspend it with the rest */
649 LOGW("threadid=%d: non-daemon id=%d still running at shutdown?!\n",
650 threadId, target->threadId);
653 char* threadName = dvmGetThreadName(target);
654 LOGD("threadid=%d: suspending daemon id=%d name='%s'\n",
655 threadId, target->threadId, threadName);
658 /* mark as suspended */
659 lockThreadSuspendCount();
660 dvmAddToThreadSuspendCount(&target->suspendCount, 1);
661 unlockThreadSuspendCount();
664 target = target->next;
667 //dvmDumpAllThreads(false);
670 * Unlock the thread list, relocking it later if necessary. It's
671 * possible a thread is in VMWAIT after calling dvmLockThreadList,
672 * and that function *doesn't* check for pending suspend after
673 * acquiring the lock. We want to let them finish their business
674 * and see the pending suspend before we continue here.
676 * There's no guarantee of mutex fairness, so this might not work.
677 * (The alternative is to have dvmLockThreadList check for suspend
678 * after acquiring the lock and back off, something we should consider.)
680 dvmUnlockThreadList();
685 dvmLockThreadList(self);
688 * Sleep for a bit until the threads have suspended. We're trying
689 * to exit, so don't wait for too long.
692 for (i = 0; i < 10; i++) {
693 bool allSuspended = true;
695 target = gDvm.threadList;
696 while (target != NULL) {
697 if (target == self) {
698 target = target->next;
702 if (target->status == THREAD_RUNNING && !target->isSuspended) {
703 LOGD("threadid=%d not ready yet\n", target->threadId);
704 allSuspended = false;
708 target = target->next;
712 LOGD("threadid=%d: all daemons have suspended\n", threadId);
715 LOGD("threadid=%d: waiting for daemons to suspend\n", threadId);
720 dvmUnlockThreadList();
723 #if 0 /* bad things happen if they come out of JNI or "spuriously" wake up */
725 * Abandon the threads and recover their resources.
727 target = gDvm.threadList;
728 while (target != NULL) {
729 Thread* nextTarget = target->next;
730 unlinkThread(target);
736 //dvmDumpAllThreads(true);
741 * Finish preparing the parts of the Thread struct required to support
744 bool dvmPrepMainForJni(JNIEnv* pEnv)
748 /* main thread is always first in list at this point */
749 self = gDvm.threadList;
750 assert(self->threadId == kMainThreadId);
752 /* create a "fake" JNI frame at the top of the main thread interp stack */
753 if (!createFakeEntryFrame(self))
756 /* fill these in, since they weren't ready at dvmCreateJNIEnv time */
757 dvmSetJniEnvThreadId(pEnv, self);
758 dvmSetThreadJNIEnv(self, (JNIEnv*) pEnv);
765 * Finish preparing the main thread, allocating some objects to represent
766 * it. As part of doing so, we finish initializing Thread and ThreadGroup.
767 * This will execute some interpreted code (e.g. class initializers).
769 bool dvmPrepMainThread(void)
775 StringObject* threadNameStr;
779 LOGV("+++ finishing prep on main VM thread\n");
781 /* main thread is always first in list at this point */
782 thread = gDvm.threadList;
783 assert(thread->threadId == kMainThreadId);
786 * Make sure the classes are initialized. We have to do this before
787 * we create an instance of them.
789 if (!dvmInitClass(gDvm.classJavaLangClass)) {
790 LOGE("'Class' class failed to initialize\n");
793 if (!dvmInitClass(gDvm.classJavaLangThreadGroup) ||
794 !dvmInitClass(gDvm.classJavaLangThread) ||
795 !dvmInitClass(gDvm.classJavaLangVMThread))
797 LOGE("thread classes failed to initialize\n");
801 groupObj = dvmGetMainThreadGroup();
802 if (groupObj == NULL)
806 * Allocate and construct a Thread with the internal-creation
809 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_DEFAULT);
810 if (threadObj == NULL) {
811 LOGE("unable to allocate main thread object\n");
814 dvmReleaseTrackedAlloc(threadObj, NULL);
816 threadNameStr = dvmCreateStringFromCstr("main", ALLOC_DEFAULT);
817 if (threadNameStr == NULL)
819 dvmReleaseTrackedAlloc((Object*)threadNameStr, NULL);
821 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
822 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
823 assert(init != NULL);
824 dvmCallMethod(thread, init, threadObj, &unused, groupObj, threadNameStr,
825 THREAD_NORM_PRIORITY, false);
826 if (dvmCheckException(thread)) {
827 LOGE("exception thrown while constructing main thread object\n");
832 * Allocate and construct a VMThread.
834 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
835 if (vmThreadObj == NULL) {
836 LOGE("unable to allocate main vmthread object\n");
839 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
841 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangVMThread, "<init>",
842 "(Ljava/lang/Thread;)V");
843 dvmCallMethod(thread, init, vmThreadObj, &unused, threadObj);
844 if (dvmCheckException(thread)) {
845 LOGE("exception thrown while constructing main vmthread object\n");
849 /* set the VMThread.vmData field to our Thread struct */
850 assert(gDvm.offJavaLangVMThread_vmData != 0);
851 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)thread);
854 * Stuff the VMThread back into the Thread. From this point on, other
855 * Threads will see that this Thread is running (at least, they would,
856 * if there were any).
858 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread,
861 thread->threadObj = threadObj;
864 * Set the context class loader. This invokes a ClassLoader method,
865 * which could conceivably call Thread.currentThread(), so we want the
866 * Thread to be fully configured before we do this.
868 Object* systemLoader = dvmGetSystemClassLoader();
869 if (systemLoader == NULL) {
870 LOGW("WARNING: system class loader is NULL (setting main ctxt)\n");
873 int ctxtClassLoaderOffset = dvmFindFieldOffset(gDvm.classJavaLangThread,
874 "contextClassLoader", "Ljava/lang/ClassLoader;");
875 if (ctxtClassLoaderOffset < 0) {
876 LOGE("Unable to find contextClassLoader field in Thread\n");
879 dvmSetFieldObject(threadObj, ctxtClassLoaderOffset, systemLoader);
882 * Finish our thread prep.
885 /* include self in non-daemon threads (mainly for AttachCurrentThread) */
886 gDvm.nonDaemonThreadCount++;
893 * Alloc and initialize a Thread struct.
895 * "threadObj" is the java.lang.Thread object. It will be NULL for the
896 * main VM thread, but non-NULL for everything else.
898 * Does not create any objects, just stuff on the system (malloc) heap. (If
899 * this changes, we need to use ALLOC_NO_GC. And also verify that we're
900 * ready to load classes at the time this is called.)
902 static Thread* allocThread(int interpStackSize)
907 thread = (Thread*) calloc(1, sizeof(Thread));
911 #if defined(WITH_SELF_VERIFICATION)
912 if (dvmSelfVerificationShadowSpaceAlloc(thread) == NULL)
916 assert(interpStackSize >= kMinStackSize && interpStackSize <=kMaxStackSize);
918 thread->status = THREAD_INITIALIZING;
919 thread->suspendCount = 0;
921 #ifdef WITH_ALLOC_LIMITS
922 thread->allocLimit = -1;
926 * Allocate and initialize the interpreted code stack. We essentially
927 * "lose" the alloc pointer, which points at the bottom of the stack,
928 * but we can get it back later because we know how big the stack is.
930 * The stack must be aligned on a 4-byte boundary.
932 #ifdef MALLOC_INTERP_STACK
933 stackBottom = (u1*) malloc(interpStackSize);
934 if (stackBottom == NULL) {
935 #if defined(WITH_SELF_VERIFICATION)
936 dvmSelfVerificationShadowSpaceFree(thread);
941 memset(stackBottom, 0xc5, interpStackSize); // stop valgrind complaints
943 stackBottom = mmap(NULL, interpStackSize, PROT_READ | PROT_WRITE,
944 MAP_PRIVATE | MAP_ANON, -1, 0);
945 if (stackBottom == MAP_FAILED) {
946 #if defined(WITH_SELF_VERIFICATION)
947 dvmSelfVerificationShadowSpaceFree(thread);
954 assert(((u4)stackBottom & 0x03) == 0); // looks like our malloc ensures this
955 thread->interpStackSize = interpStackSize;
956 thread->interpStackStart = stackBottom + interpStackSize;
957 thread->interpStackEnd = stackBottom + STACK_OVERFLOW_RESERVE;
959 /* give the thread code a chance to set things up */
960 dvmInitInterpStack(thread, interpStackSize);
966 * Get a meaningful thread ID. At present this only has meaning under Linux,
967 * where getpid() and gettid() sometimes agree and sometimes don't depending
968 * on your thread model (try "export LD_ASSUME_KERNEL=2.4.19").
970 pid_t dvmGetSysThreadId(void)
980 * Finish initialization of a Thread struct.
982 * This must be called while executing in the new thread, but before the
983 * thread is added to the thread list.
985 * *** NOTE: The threadListLock must be held by the caller (needed for
988 static bool prepareThread(Thread* thread)
990 assignThreadId(thread);
991 thread->handle = pthread_self();
992 thread->systemTid = dvmGetSysThreadId();
994 //LOGI("SYSTEM TID IS %d (pid is %d)\n", (int) thread->systemTid,
996 setThreadSelf(thread);
998 LOGV("threadid=%d: interp stack at %p\n",
999 thread->threadId, thread->interpStackStart - thread->interpStackSize);
1002 * Initialize invokeReq.
1004 dvmInitMutex(&thread->invokeReq.lock);
1005 pthread_cond_init(&thread->invokeReq.cv, NULL);
1008 * Initialize our reference tracking tables.
1010 * Most threads won't use jniMonitorRefTable, so we clear out the
1011 * structure but don't call the init function (which allocs storage).
1013 #ifdef USE_INDIRECT_REF
1014 if (!dvmInitIndirectRefTable(&thread->jniLocalRefTable,
1015 kJniLocalRefMin, kJniLocalRefMax, kIndirectKindLocal))
1019 * The JNI local ref table *must* be fixed-size because we keep pointers
1020 * into the table in our stack frames.
1022 if (!dvmInitReferenceTable(&thread->jniLocalRefTable,
1023 kJniLocalRefMax, kJniLocalRefMax))
1026 if (!dvmInitReferenceTable(&thread->internalLocalRefTable,
1027 kInternalRefDefault, kInternalRefMax))
1030 memset(&thread->jniMonitorRefTable, 0, sizeof(thread->jniMonitorRefTable));
1032 pthread_cond_init(&thread->waitCond, NULL);
1033 dvmInitMutex(&thread->waitMutex);
1039 * Remove a thread from the internal list.
1040 * Clear out the links to make it obvious that the thread is
1041 * no longer on the list. Caller must hold gDvm.threadListLock.
1043 static void unlinkThread(Thread* thread)
1045 LOG_THREAD("threadid=%d: removing from list\n", thread->threadId);
1046 if (thread == gDvm.threadList) {
1047 assert(thread->prev == NULL);
1048 gDvm.threadList = thread->next;
1050 assert(thread->prev != NULL);
1051 thread->prev->next = thread->next;
1053 if (thread->next != NULL)
1054 thread->next->prev = thread->prev;
1055 thread->prev = thread->next = NULL;
1059 * Free a Thread struct, and all the stuff allocated within.
1061 static void freeThread(Thread* thread)
1066 /* thread->threadId is zero at this point */
1067 LOGVV("threadid=%d: freeing\n", thread->threadId);
1069 if (thread->interpStackStart != NULL) {
1070 u1* interpStackBottom;
1072 interpStackBottom = thread->interpStackStart;
1073 interpStackBottom -= thread->interpStackSize;
1074 #ifdef MALLOC_INTERP_STACK
1075 free(interpStackBottom);
1077 if (munmap(interpStackBottom, thread->interpStackSize) != 0)
1078 LOGW("munmap(thread stack) failed\n");
1082 #ifdef USE_INDIRECT_REF
1083 dvmClearIndirectRefTable(&thread->jniLocalRefTable);
1085 dvmClearReferenceTable(&thread->jniLocalRefTable);
1087 dvmClearReferenceTable(&thread->internalLocalRefTable);
1088 if (&thread->jniMonitorRefTable.table != NULL)
1089 dvmClearReferenceTable(&thread->jniMonitorRefTable);
1091 #if defined(WITH_SELF_VERIFICATION)
1092 dvmSelfVerificationShadowSpaceFree(thread);
1098 * Like pthread_self(), but on a Thread*.
1100 Thread* dvmThreadSelf(void)
1102 return (Thread*) pthread_getspecific(gDvm.pthreadKeySelf);
1106 * Explore our sense of self. Stuffs the thread pointer into TLS.
1108 static void setThreadSelf(Thread* thread)
1112 cc = pthread_setspecific(gDvm.pthreadKeySelf, thread);
1115 * Sometimes this fails under Bionic with EINVAL during shutdown.
1116 * This can happen if the timing is just right, e.g. a thread
1117 * fails to attach during shutdown, but the "fail" path calls
1118 * here to ensure we clean up after ourselves.
1120 if (thread != NULL) {
1121 LOGE("pthread_setspecific(%p) failed, err=%d\n", thread, cc);
1122 dvmAbort(); /* the world is fundamentally hosed */
1128 * This is associated with the pthreadKeySelf key. It's called by the
1129 * pthread library when a thread is exiting and the "self" pointer in TLS
1130 * is non-NULL, meaning the VM hasn't had a chance to clean up. In normal
1131 * operation this will not be called.
1133 * This is mainly of use to ensure that we don't leak resources if, for
1134 * example, a thread attaches itself to us with AttachCurrentThread and
1135 * then exits without notifying the VM.
1137 * We could do the detach here instead of aborting, but this will lead to
1138 * portability problems. Other implementations do not do this check and
1139 * will simply be unaware that the thread has exited, leading to resource
1140 * leaks (and, if this is a non-daemon thread, an infinite hang when the
1141 * VM tries to shut down).
1143 * Because some implementations may want to use the pthread destructor
1144 * to initiate the detach, and the ordering of destructors is not defined,
1145 * we want to iterate a couple of times to give those a chance to run.
1147 static void threadExitCheck(void* arg)
1149 const int kMaxCount = 2;
1151 Thread* self = (Thread*) arg;
1152 assert(self != NULL);
1154 LOGV("threadid=%d: threadExitCheck(%p) count=%d\n",
1155 self->threadId, arg, self->threadExitCheckCount);
1157 if (self->status == THREAD_ZOMBIE) {
1158 LOGW("threadid=%d: Weird -- shouldn't be in threadExitCheck\n",
1163 if (self->threadExitCheckCount < kMaxCount) {
1165 * Spin a couple of times to let other destructors fire.
1167 LOGD("threadid=%d: thread exiting, not yet detached (count=%d)\n",
1168 self->threadId, self->threadExitCheckCount);
1169 self->threadExitCheckCount++;
1170 int cc = pthread_setspecific(gDvm.pthreadKeySelf, self);
1172 LOGE("threadid=%d: unable to re-add thread to TLS\n",
1177 LOGE("threadid=%d: native thread exited without detaching\n",
1185 * Assign the threadId. This needs to be a small integer so that our
1186 * "thin" locks fit in a small number of bits.
1188 * We reserve zero for use as an invalid ID.
1190 * This must be called with threadListLock held (unless we're still
1191 * initializing the system).
1193 static void assignThreadId(Thread* thread)
1195 /* Find a small unique integer. threadIdMap is a vector of
1196 * kMaxThreadId bits; dvmAllocBit() returns the index of a
1197 * bit, meaning that it will always be < kMaxThreadId.
1199 * The thin locking magic requires that the low bit is always
1200 * set, so we do it once, here.
1202 int num = dvmAllocBit(gDvm.threadIdMap);
1204 LOGE("Ran out of thread IDs\n");
1205 dvmAbort(); // TODO: make this a non-fatal error result
1208 thread->threadId = ((num + 1) << 1) | 1;
1210 assert(thread->threadId != 0);
1211 assert(thread->threadId != DVM_LOCK_INITIAL_THIN_VALUE);
1215 * Give back the thread ID.
1217 static void releaseThreadId(Thread* thread)
1219 assert(thread->threadId > 0);
1220 dvmClearBit(gDvm.threadIdMap, (thread->threadId >> 1) - 1);
1221 thread->threadId = 0;
1226 * Add a stack frame that makes it look like the native code in the main
1227 * thread was originally invoked from interpreted code. This gives us a
1228 * place to hang JNI local references. The VM spec says (v2 5.2) that the
1229 * VM begins by executing "main" in a class, so in a way this brings us
1230 * closer to the spec.
1232 static bool createFakeEntryFrame(Thread* thread)
1234 assert(thread->threadId == kMainThreadId); // main thread only
1236 /* find the method on first use */
1237 if (gDvm.methFakeNativeEntry == NULL) {
1238 ClassObject* nativeStart;
1241 nativeStart = dvmFindSystemClassNoInit(
1242 "Ldalvik/system/NativeStart;");
1243 if (nativeStart == NULL) {
1244 LOGE("Unable to find dalvik.system.NativeStart class\n");
1249 * Because we are creating a frame that represents application code, we
1250 * want to stuff the application class loader into the method's class
1251 * loader field, even though we're using the system class loader to
1252 * load it. This makes life easier over in JNI FindClass (though it
1253 * could bite us in other ways).
1255 * Unfortunately this is occurring too early in the initialization,
1256 * of necessity coming before JNI is initialized, and we're not quite
1257 * ready to set up the application class loader.
1259 * So we save a pointer to the method in gDvm.methFakeNativeEntry
1260 * and check it in FindClass. The method is private so nobody else
1263 //nativeStart->classLoader = dvmGetSystemClassLoader();
1265 mainMeth = dvmFindDirectMethodByDescriptor(nativeStart,
1266 "main", "([Ljava/lang/String;)V");
1267 if (mainMeth == NULL) {
1268 LOGE("Unable to find 'main' in dalvik.system.NativeStart\n");
1272 gDvm.methFakeNativeEntry = mainMeth;
1275 return dvmPushJNIFrame(thread, gDvm.methFakeNativeEntry);
1280 * Add a stack frame that makes it look like the native thread has been
1281 * executing interpreted code. This gives us a place to hang JNI local
1284 static bool createFakeRunFrame(Thread* thread)
1286 ClassObject* nativeStart;
1289 assert(thread->threadId != 1); // not for main thread
1292 dvmFindSystemClassNoInit("Ldalvik/system/NativeStart;");
1293 if (nativeStart == NULL) {
1294 LOGE("Unable to find dalvik.system.NativeStart class\n");
1298 runMeth = dvmFindVirtualMethodByDescriptor(nativeStart, "run", "()V");
1299 if (runMeth == NULL) {
1300 LOGE("Unable to find 'run' in dalvik.system.NativeStart\n");
1304 return dvmPushJNIFrame(thread, runMeth);
1308 * Helper function to set the name of the current thread
1310 static void setThreadName(const char *threadName)
1312 #if defined(HAVE_PRCTL)
1315 const char *s = threadName;
1317 if (*s == '.') hasDot = 1;
1318 else if (*s == '@') hasAt = 1;
1321 int len = s - threadName;
1322 if (len < 15 || hasAt || !hasDot) {
1325 s = threadName + len - 15;
1327 prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
1332 * Create a thread as a result of java.lang.Thread.start().
1334 * We do have to worry about some concurrency problems, e.g. programs
1335 * that try to call Thread.start() on the same object from multiple threads.
1336 * (This will fail for all but one, but we have to make sure that it succeeds
1339 * Some of the complexity here arises from our desire to mimic the
1340 * Thread vs. VMThread class decomposition we inherited. We've been given
1341 * a Thread, and now we need to create a VMThread and then populate both
1342 * objects. We also need to create one of our internal Thread objects.
1344 * Pass in a stack size of 0 to get the default.
1346 bool dvmCreateInterpThread(Object* threadObj, int reqStackSize)
1348 pthread_attr_t threadAttr;
1349 pthread_t threadHandle;
1351 Thread* newThread = NULL;
1352 Object* vmThreadObj = NULL;
1355 assert(threadObj != NULL);
1358 // Allow the sampling profiler thread. We shut it down before forking.
1359 StringObject* nameStr = (StringObject*) dvmGetFieldObject(threadObj,
1360 gDvm.offJavaLangThread_name);
1361 char* threadName = dvmCreateCstrFromString(nameStr);
1362 bool profilerThread = strcmp(threadName, "SamplingProfiler") == 0;
1364 if (!profilerThread) {
1365 dvmThrowException("Ljava/lang/IllegalStateException;",
1366 "No new threads in -Xzygote mode");
1372 self = dvmThreadSelf();
1373 if (reqStackSize == 0)
1374 stackSize = gDvm.stackSize;
1375 else if (reqStackSize < kMinStackSize)
1376 stackSize = kMinStackSize;
1377 else if (reqStackSize > kMaxStackSize)
1378 stackSize = kMaxStackSize;
1380 stackSize = reqStackSize;
1382 pthread_attr_init(&threadAttr);
1383 pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1386 * To minimize the time spent in the critical section, we allocate the
1387 * vmThread object here.
1389 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
1390 if (vmThreadObj == NULL)
1393 newThread = allocThread(stackSize);
1394 if (newThread == NULL)
1396 newThread->threadObj = threadObj;
1398 assert(newThread->status == THREAD_INITIALIZING);
1401 * We need to lock out other threads while we test and set the
1402 * "vmThread" field in java.lang.Thread, because we use that to determine
1403 * if this thread has been started before. We use the thread list lock
1404 * because it's handy and we're going to need to grab it again soon
1407 dvmLockThreadList(self);
1409 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
1410 dvmUnlockThreadList();
1411 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
1412 "thread has already been started");
1417 * There are actually three data structures: Thread (object), VMThread
1418 * (object), and Thread (C struct). All of them point to at least one
1421 * As soon as "VMThread.vmData" is assigned, other threads can start
1422 * making calls into us (e.g. setPriority).
1424 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)newThread);
1425 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
1428 * Thread creation might take a while, so release the lock.
1430 dvmUnlockThreadList();
1433 oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
1434 cc = pthread_create(&threadHandle, &threadAttr, interpThreadStart,
1436 oldStatus = dvmChangeStatus(self, oldStatus);
1440 * Failure generally indicates that we have exceeded system
1441 * resource limits. VirtualMachineError is probably too severe,
1442 * so use OutOfMemoryError.
1444 LOGE("Thread creation failed (err=%s)\n", strerror(errno));
1446 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, NULL);
1448 dvmThrowException("Ljava/lang/OutOfMemoryError;",
1449 "thread creation failed");
1454 * We need to wait for the thread to start. Otherwise, depending on
1455 * the whims of the OS scheduler, we could return and the code in our
1456 * thread could try to do operations on the new thread before it had
1457 * finished starting.
1459 * The new thread will lock the thread list, change its state to
1460 * THREAD_STARTING, broadcast to gDvm.threadStartCond, and then sleep
1461 * on gDvm.threadStartCond (which uses the thread list lock). This
1462 * thread (the parent) will either see that the thread is already ready
1463 * after we grab the thread list lock, or will be awakened from the
1464 * condition variable on the broadcast.
1466 * We don't want to stall the rest of the VM while the new thread
1467 * starts, which can happen if the GC wakes up at the wrong moment.
1468 * So, we change our own status to VMWAIT, and self-suspend if
1469 * necessary after we finish adding the new thread.
1472 * We have to deal with an odd race with the GC/debugger suspension
1473 * mechanism when creating a new thread. The information about whether
1474 * or not a thread should be suspended is contained entirely within
1475 * the Thread struct; this is usually cleaner to deal with than having
1476 * one or more globally-visible suspension flags. The trouble is that
1477 * we could create the thread while the VM is trying to suspend all
1478 * threads. The suspend-count won't be nonzero for the new thread,
1479 * so dvmChangeStatus(THREAD_RUNNING) won't cause a suspension.
1481 * The easiest way to deal with this is to prevent the new thread from
1482 * running until the parent says it's okay. This results in the
1483 * following (correct) sequence of events for a "badly timed" GC
1484 * (where '-' is us, 'o' is the child, and '+' is some other thread):
1486 * - call pthread_create()
1487 * - lock thread list
1488 * - put self into THREAD_VMWAIT so GC doesn't wait for us
1489 * - sleep on condition var (mutex = thread list lock) until child starts
1490 * + GC triggered by another thread
1491 * + thread list locked; suspend counts updated; thread list unlocked
1492 * + loop waiting for all runnable threads to suspend
1493 * + success, start GC
1494 * o child thread wakes, signals condition var to wake parent
1495 * o child waits for parent ack on condition variable
1496 * - we wake up, locking thread list
1497 * - add child to thread list
1498 * - unlock thread list
1499 * - change our state back to THREAD_RUNNING; GC causes us to suspend
1500 * + GC finishes; all threads in thread list are resumed
1501 * - lock thread list
1502 * - set child to THREAD_VMWAIT, and signal it to start
1503 * - unlock thread list
1505 * o child changes state to THREAD_RUNNING
1507 * The above shows the GC starting up during thread creation, but if
1508 * it starts anywhere after VMThread.create() is called it will
1509 * produce the same series of events.
1511 * Once the child is in the thread list, it will be suspended and
1512 * resumed like any other thread. In the above scenario the resume-all
1513 * code will try to resume the new thread, which was never actually
1514 * suspended, and try to decrement the child's thread suspend count to -1.
1515 * We can catch this in the resume-all code.
1517 * Bouncing back and forth between threads like this adds a small amount
1518 * of scheduler overhead to thread startup.
1520 * One alternative to having the child wait for the parent would be
1521 * to have the child inherit the parents' suspension count. This
1522 * would work for a GC, since we can safely assume that the parent
1523 * thread didn't cause it, but we must only do so if the parent suspension
1524 * was caused by a suspend-all. If the parent was being asked to
1525 * suspend singly by the debugger, the child should not inherit the value.
1527 * We could also have a global "new thread suspend count" that gets
1528 * picked up by new threads before changing state to THREAD_RUNNING.
1529 * This would be protected by the thread list lock and set by a
1532 dvmLockThreadList(self);
1533 assert(self->status == THREAD_RUNNING);
1534 self->status = THREAD_VMWAIT;
1535 while (newThread->status != THREAD_STARTING)
1536 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1538 LOG_THREAD("threadid=%d: adding to list\n", newThread->threadId);
1539 newThread->next = gDvm.threadList->next;
1540 if (newThread->next != NULL)
1541 newThread->next->prev = newThread;
1542 newThread->prev = gDvm.threadList;
1543 gDvm.threadList->next = newThread;
1545 if (!dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon))
1546 gDvm.nonDaemonThreadCount++; // guarded by thread list lock
1548 dvmUnlockThreadList();
1550 /* change status back to RUNNING, self-suspending if necessary */
1551 dvmChangeStatus(self, THREAD_RUNNING);
1554 * Tell the new thread to start.
1556 * We must hold the thread list lock before messing with another thread.
1557 * In the general case we would also need to verify that newThread was
1558 * still in the thread list, but in our case the thread has not started
1559 * executing user code and therefore has not had a chance to exit.
1561 * We move it to VMWAIT, and it then shifts itself to RUNNING, which
1562 * comes with a suspend-pending check.
1564 dvmLockThreadList(self);
1566 assert(newThread->status == THREAD_STARTING);
1567 newThread->status = THREAD_VMWAIT;
1568 pthread_cond_broadcast(&gDvm.threadStartCond);
1570 dvmUnlockThreadList();
1572 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1576 freeThread(newThread);
1577 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1582 * pthread entry function for threads started from interpreted code.
1584 static void* interpThreadStart(void* arg)
1586 Thread* self = (Thread*) arg;
1588 char *threadName = dvmGetThreadName(self);
1589 setThreadName(threadName);
1593 * Finish initializing the Thread struct.
1595 prepareThread(self);
1597 LOG_THREAD("threadid=%d: created from interp\n", self->threadId);
1600 * Change our status and wake our parent, who will add us to the
1601 * thread list and advance our state to VMWAIT.
1603 dvmLockThreadList(self);
1604 self->status = THREAD_STARTING;
1605 pthread_cond_broadcast(&gDvm.threadStartCond);
1608 * Wait until the parent says we can go. Assuming there wasn't a
1609 * suspend pending, this will happen immediately. When it completes,
1610 * we're full-fledged citizens of the VM.
1612 * We have to use THREAD_VMWAIT here rather than THREAD_RUNNING
1613 * because the pthread_cond_wait below needs to reacquire a lock that
1614 * suspend-all is also interested in. If we get unlucky, the parent could
1615 * change us to THREAD_RUNNING, then a GC could start before we get
1616 * signaled, and suspend-all will grab the thread list lock and then
1617 * wait for us to suspend. We'll be in the tail end of pthread_cond_wait
1618 * trying to get the lock.
1620 while (self->status != THREAD_VMWAIT)
1621 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1623 dvmUnlockThreadList();
1626 * Add a JNI context.
1628 self->jniEnv = dvmCreateJNIEnv(self);
1631 * Change our state so the GC will wait for us from now on. If a GC is
1632 * in progress this call will suspend us.
1634 dvmChangeStatus(self, THREAD_RUNNING);
1637 * Notify the debugger & DDM. The debugger notification may cause
1638 * us to suspend ourselves (and others).
1640 if (gDvm.debuggerConnected)
1641 dvmDbgPostThreadStart(self);
1644 * Set the system thread priority according to the Thread object's
1645 * priority level. We don't usually need to do this, because both the
1646 * Thread object and system thread priorities inherit from parents. The
1647 * tricky case is when somebody creates a Thread object, calls
1648 * setPriority(), and then starts the thread. We could manage this with
1649 * a "needs priority update" flag to avoid the redundant call.
1651 int priority = dvmGetFieldInt(self->threadObj,
1652 gDvm.offJavaLangThread_priority);
1653 dvmChangeThreadPriority(self, priority);
1656 * Execute the "run" method.
1658 * At this point our stack is empty, so somebody who comes looking for
1659 * stack traces right now won't have much to look at. This is normal.
1661 Method* run = self->threadObj->clazz->vtable[gDvm.voffJavaLangThread_run];
1664 LOGV("threadid=%d: calling run()\n", self->threadId);
1665 assert(strcmp(run->name, "run") == 0);
1666 dvmCallMethod(self, run, self->threadObj, &unused);
1667 LOGV("threadid=%d: exiting\n", self->threadId);
1670 * Remove the thread from various lists, report its death, and free
1673 dvmDetachCurrentThread();
1679 * The current thread is exiting with an uncaught exception. The
1680 * Java programming language allows the application to provide a
1681 * thread-exit-uncaught-exception handler for the VM, for a specific
1682 * Thread, and for all threads in a ThreadGroup.
1684 * Version 1.5 added the per-thread handler. We need to call
1685 * "uncaughtException" in the handler object, which is either the
1686 * ThreadGroup object or the Thread-specific handler.
1688 static void threadExitUncaughtException(Thread* self, Object* group)
1692 ClassObject* throwable;
1693 Method* uncaughtHandler = NULL;
1694 InstField* threadHandler;
1696 LOGW("threadid=%d: thread exiting with uncaught exception (group=%p)\n",
1697 self->threadId, group);
1698 assert(group != NULL);
1701 * Get a pointer to the exception, then clear out the one in the
1702 * thread. We don't want to have it set when executing interpreted code.
1704 exception = dvmGetException(self);
1705 dvmAddTrackedAlloc(exception, self);
1706 dvmClearException(self);
1709 * Get the Thread's "uncaughtHandler" object. Use it if non-NULL;
1710 * else use "group" (which is an instance of UncaughtExceptionHandler).
1712 threadHandler = dvmFindInstanceField(gDvm.classJavaLangThread,
1713 "uncaughtHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;");
1714 if (threadHandler == NULL) {
1715 LOGW("WARNING: no 'uncaughtHandler' field in java/lang/Thread\n");
1718 handlerObj = dvmGetFieldObject(self->threadObj, threadHandler->byteOffset);
1719 if (handlerObj == NULL)
1723 * Find the "uncaughtHandler" field in this object.
1725 uncaughtHandler = dvmFindVirtualMethodHierByDescriptor(handlerObj->clazz,
1726 "uncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
1728 if (uncaughtHandler != NULL) {
1729 //LOGI("+++ calling %s.uncaughtException\n",
1730 // handlerObj->clazz->descriptor);
1732 dvmCallMethod(self, uncaughtHandler, handlerObj, &unused,
1733 self->threadObj, exception);
1735 /* restore it and dump a stack trace */
1736 LOGW("WARNING: no 'uncaughtException' method in class %s\n",
1737 handlerObj->clazz->descriptor);
1738 dvmSetException(self, exception);
1739 dvmLogExceptionStackTrace();
1743 #if defined(WITH_JIT)
1744 /* Remove this thread's suspendCount from global suspendCount sum */
1745 lockThreadSuspendCount();
1746 dvmAddToThreadSuspendCount(&self->suspendCount, -self->suspendCount);
1747 unlockThreadSuspendCount();
1749 dvmReleaseTrackedAlloc(exception, self);
1754 * Create an internal VM thread, for things like JDWP and finalizers.
1756 * The easiest way to do this is create a new thread and then use the
1757 * JNI AttachCurrentThread implementation.
1759 * This does not return until after the new thread has begun executing.
1761 bool dvmCreateInternalThread(pthread_t* pHandle, const char* name,
1762 InternalThreadStart func, void* funcArg)
1764 InternalStartArgs* pArgs;
1765 Object* systemGroup;
1766 pthread_attr_t threadAttr;
1767 volatile Thread* newThread = NULL;
1768 volatile int createStatus = 0;
1770 systemGroup = dvmGetSystemThreadGroup();
1771 if (systemGroup == NULL)
1774 pArgs = (InternalStartArgs*) malloc(sizeof(*pArgs));
1776 pArgs->funcArg = funcArg;
1777 pArgs->name = strdup(name); // storage will be owned by new thread
1778 pArgs->group = systemGroup;
1779 pArgs->isDaemon = true;
1780 pArgs->pThread = &newThread;
1781 pArgs->pCreateStatus = &createStatus;
1783 pthread_attr_init(&threadAttr);
1784 //pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1786 if (pthread_create(pHandle, &threadAttr, internalThreadStart,
1789 LOGE("internal thread creation failed\n");
1796 * Wait for the child to start. This gives us an opportunity to make
1797 * sure that the thread started correctly, and allows our caller to
1798 * assume that the thread has started running.
1800 * Because we aren't holding a lock across the thread creation, it's
1801 * possible that the child will already have completed its
1802 * initialization. Because the child only adjusts "createStatus" while
1803 * holding the thread list lock, the initial condition on the "while"
1804 * loop will correctly avoid the wait if this occurs.
1806 * It's also possible that we'll have to wait for the thread to finish
1807 * being created, and as part of allocating a Thread object it might
1808 * need to initiate a GC. We switch to VMWAIT while we pause.
1810 Thread* self = dvmThreadSelf();
1811 int oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
1812 dvmLockThreadList(self);
1813 while (createStatus == 0)
1814 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1816 if (newThread == NULL) {
1817 LOGW("internal thread create failed (createStatus=%d)\n", createStatus);
1818 assert(createStatus < 0);
1819 /* don't free pArgs -- if pthread_create succeeded, child owns it */
1820 dvmUnlockThreadList();
1821 dvmChangeStatus(self, oldStatus);
1825 /* thread could be in any state now (except early init states) */
1826 //assert(newThread->status == THREAD_RUNNING);
1828 dvmUnlockThreadList();
1829 dvmChangeStatus(self, oldStatus);
1835 * pthread entry function for internally-created threads.
1837 * We are expected to free "arg" and its contents. If we're a daemon
1838 * thread, and we get cancelled abruptly when the VM shuts down, the
1839 * storage won't be freed. If this becomes a concern we can make a copy
1842 static void* internalThreadStart(void* arg)
1844 InternalStartArgs* pArgs = (InternalStartArgs*) arg;
1845 JavaVMAttachArgs jniArgs;
1847 jniArgs.version = JNI_VERSION_1_2;
1848 jniArgs.name = pArgs->name;
1849 jniArgs.group = pArgs->group;
1851 setThreadName(pArgs->name);
1853 /* use local jniArgs as stack top */
1854 if (dvmAttachCurrentThread(&jniArgs, pArgs->isDaemon)) {
1856 * Tell the parent of our success.
1858 * threadListLock is the mutex for threadStartCond.
1860 dvmLockThreadList(dvmThreadSelf());
1861 *pArgs->pCreateStatus = 1;
1862 *pArgs->pThread = dvmThreadSelf();
1863 pthread_cond_broadcast(&gDvm.threadStartCond);
1864 dvmUnlockThreadList();
1866 LOG_THREAD("threadid=%d: internal '%s'\n",
1867 dvmThreadSelf()->threadId, pArgs->name);
1870 (*pArgs->func)(pArgs->funcArg);
1872 /* detach ourselves */
1873 dvmDetachCurrentThread();
1876 * Tell the parent of our failure. We don't have a Thread struct,
1877 * so we can't be suspended, so we don't need to enter a critical
1880 dvmLockThreadList(dvmThreadSelf());
1881 *pArgs->pCreateStatus = -1;
1882 assert(*pArgs->pThread == NULL);
1883 pthread_cond_broadcast(&gDvm.threadStartCond);
1884 dvmUnlockThreadList();
1886 assert(*pArgs->pThread == NULL);
1895 * Attach the current thread to the VM.
1897 * Used for internally-created threads and JNI's AttachCurrentThread.
1899 bool dvmAttachCurrentThread(const JavaVMAttachArgs* pArgs, bool isDaemon)
1901 Thread* self = NULL;
1902 Object* threadObj = NULL;
1903 Object* vmThreadObj = NULL;
1904 StringObject* threadNameStr = NULL;
1908 /* establish a basic sense of self */
1909 self = allocThread(gDvm.stackSize);
1912 setThreadSelf(self);
1915 * Create Thread and VMThread objects. We have to use ALLOC_NO_GC
1916 * because this thread is not yet visible to the VM. We could also
1917 * just grab the GC lock earlier, but that leaves us executing
1918 * interpreted code with the lock held, which is not prudent.
1920 * The alloc calls will block if a GC is in progress, so we don't need
1921 * to check for global suspension here.
1923 * It's also possible for the allocation calls to *cause* a GC.
1925 //BUG: deadlock if a GC happens here during HeapWorker creation
1926 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_NO_GC);
1927 if (threadObj == NULL)
1929 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_NO_GC);
1930 if (vmThreadObj == NULL)
1933 self->threadObj = threadObj;
1934 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)self);
1937 * Do some java.lang.Thread constructor prep before we lock stuff down.
1939 if (pArgs->name != NULL) {
1940 threadNameStr = dvmCreateStringFromCstr(pArgs->name, ALLOC_NO_GC);
1941 if (threadNameStr == NULL) {
1942 assert(dvmCheckException(dvmThreadSelf()));
1947 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
1948 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
1950 assert(dvmCheckException(dvmThreadSelf()));
1955 * Finish our thread prep. We need to do this before invoking any
1956 * interpreted code. prepareThread() requires that we hold the thread
1959 dvmLockThreadList(self);
1960 ok = prepareThread(self);
1961 dvmUnlockThreadList();
1965 self->jniEnv = dvmCreateJNIEnv(self);
1966 if (self->jniEnv == NULL)
1970 * Create a "fake" JNI frame at the top of the main thread interp stack.
1971 * It isn't really necessary for the internal threads, but it gives
1972 * the debugger something to show. It is essential for the JNI-attached
1975 if (!createFakeRunFrame(self))
1979 * The native side of the thread is ready; add it to the list.
1981 LOG_THREAD("threadid=%d: adding to list (attached)\n", self->threadId);
1983 /* Start off in VMWAIT, because we may be about to block
1984 * on the heap lock, and we don't want any suspensions
1987 self->status = THREAD_VMWAIT;
1990 * Add ourselves to the thread list. Once we finish here we are
1991 * visible to the debugger and the GC.
1993 dvmLockThreadList(self);
1995 self->next = gDvm.threadList->next;
1996 if (self->next != NULL)
1997 self->next->prev = self;
1998 self->prev = gDvm.threadList;
1999 gDvm.threadList->next = self;
2001 gDvm.nonDaemonThreadCount++;
2003 dvmUnlockThreadList();
2006 * It's possible that a GC is currently running. Our thread
2007 * wasn't in the list when the GC started, so it's not properly
2008 * suspended in that case. Synchronize on the heap lock (held
2009 * when a GC is happening) to guarantee that any GCs from here
2010 * on will see this thread in the list.
2012 dvmLockMutex(&gDvm.gcHeapLock);
2013 dvmUnlockMutex(&gDvm.gcHeapLock);
2016 * Switch to the running state now that we're ready for
2017 * suspensions. This call may suspend.
2019 dvmChangeStatus(self, THREAD_RUNNING);
2022 * Now we're ready to run some interpreted code.
2024 * We need to construct the Thread object and set the VMThread field.
2025 * Setting VMThread tells interpreted code that we're alive.
2027 * Call the (group, name, priority, daemon) constructor on the Thread.
2028 * This sets the thread's name and adds it to the specified group, and
2029 * provides values for priority and daemon (which are normally inherited
2030 * from the current thread).
2033 dvmCallMethod(self, init, threadObj, &unused, (Object*)pArgs->group,
2034 threadNameStr, getThreadPriorityFromSystem(), isDaemon);
2035 if (dvmCheckException(self)) {
2036 LOGE("exception thrown while constructing attached thread object\n");
2040 // dvmSetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon, true);
2043 * Set the VMThread field, which tells interpreted code that we're alive.
2045 * The risk of a thread start collision here is very low; somebody
2046 * would have to be deliberately polling the ThreadGroup list and
2047 * trying to start threads against anything it sees, which would
2048 * generally cause problems for all thread creation. However, for
2049 * correctness we test "vmThread" before setting it.
2051 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
2052 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
2053 "thread has already been started");
2054 /* We don't want to free anything associated with the thread
2055 * because someone is obviously interested in it. Just let
2056 * it go and hope it will clean itself up when its finished.
2057 * This case should never happen anyway.
2059 * Since we're letting it live, we need to finish setting it up.
2060 * We just have to let the caller know that the intended operation
2063 * [ This seems strange -- stepping on the vmThread object that's
2064 * already present seems like a bad idea. TODO: figure this out. ]
2069 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
2071 /* These are now reachable from the thread groups. */
2072 dvmClearAllocFlags(threadObj, ALLOC_NO_GC);
2073 dvmClearAllocFlags(vmThreadObj, ALLOC_NO_GC);
2076 * The thread is ready to go; let the debugger see it.
2078 self->threadObj = threadObj;
2080 LOG_THREAD("threadid=%d: attached from native, name=%s\n",
2081 self->threadId, pArgs->name);
2083 /* tell the debugger & DDM */
2084 if (gDvm.debuggerConnected)
2085 dvmDbgPostThreadStart(self);
2090 dvmLockThreadList(self);
2093 gDvm.nonDaemonThreadCount--;
2094 dvmUnlockThreadList();
2095 /* fall through to "fail" */
2097 dvmClearAllocFlags(threadObj, ALLOC_NO_GC);
2098 dvmClearAllocFlags(vmThreadObj, ALLOC_NO_GC);
2100 if (self->jniEnv != NULL) {
2101 dvmDestroyJNIEnv(self->jniEnv);
2102 self->jniEnv = NULL;
2106 setThreadSelf(NULL);
2111 * Detach the thread from the various data structures, notify other threads
2112 * that are waiting to "join" it, and free up all heap-allocated storage.
2114 * Used for all threads.
2116 * When we get here the interpreted stack should be empty. The JNI 1.6 spec
2117 * requires us to enforce this for the DetachCurrentThread call, probably
2118 * because it also says that DetachCurrentThread causes all monitors
2119 * associated with the thread to be released. (Because the stack is empty,
2120 * we only have to worry about explicit JNI calls to MonitorEnter.)
2123 * We might want to avoid freeing our internal Thread structure until the
2124 * associated Thread/VMThread objects get GCed. Our Thread is impossible to
2125 * get to once the thread shuts down, but there is a small possibility of
2126 * an operation starting in another thread before this thread halts, and
2127 * finishing much later (perhaps the thread got stalled by a weird OS bug).
2128 * We don't want something like Thread.isInterrupted() crawling through
2129 * freed storage. Can do with a Thread finalizer, or by creating a
2130 * dedicated ThreadObject class for java/lang/Thread and moving all of our
2133 void dvmDetachCurrentThread(void)
2135 Thread* self = dvmThreadSelf();
2140 * Make sure we're not detaching a thread that's still running. (This
2141 * could happen with an explicit JNI detach call.)
2143 * A thread created by interpreted code will finish with a depth of
2144 * zero, while a JNI-attached thread will have the synthetic "stack
2145 * starter" native method at the top.
2147 int curDepth = dvmComputeExactFrameDepth(self->curFrame);
2148 if (curDepth != 0) {
2149 bool topIsNative = false;
2151 if (curDepth == 1) {
2152 /* not expecting a lingering break frame; just look at curFrame */
2153 assert(!dvmIsBreakFrame(self->curFrame));
2154 StackSaveArea* ssa = SAVEAREA_FROM_FP(self->curFrame);
2155 if (dvmIsNativeMethod(ssa->method))
2160 LOGE("ERROR: detaching thread with interp frames (count=%d)\n",
2162 dvmDumpThread(self, false);
2167 group = dvmGetFieldObject(self->threadObj, gDvm.offJavaLangThread_group);
2168 LOG_THREAD("threadid=%d: detach (group=%p)\n", self->threadId, group);
2171 * Release any held monitors. Since there are no interpreted stack
2172 * frames, the only thing left are the monitors held by JNI MonitorEnter
2175 dvmReleaseJniMonitors(self);
2178 * Do some thread-exit uncaught exception processing if necessary.
2180 if (dvmCheckException(self))
2181 threadExitUncaughtException(self, group);
2184 * Remove the thread from the thread group.
2186 if (group != NULL) {
2187 Method* removeThread =
2188 group->clazz->vtable[gDvm.voffJavaLangThreadGroup_removeThread];
2190 dvmCallMethod(self, removeThread, group, &unused, self->threadObj);
2194 * Clear the vmThread reference in the Thread object. Interpreted code
2195 * will now see that this Thread is not running. As this may be the
2196 * only reference to the VMThread object that the VM knows about, we
2197 * have to create an internal reference to it first.
2199 vmThread = dvmGetFieldObject(self->threadObj,
2200 gDvm.offJavaLangThread_vmThread);
2201 dvmAddTrackedAlloc(vmThread, self);
2202 dvmSetFieldObject(self->threadObj, gDvm.offJavaLangThread_vmThread, NULL);
2204 /* clear out our struct Thread pointer, since it's going away */
2205 dvmSetFieldObject(vmThread, gDvm.offJavaLangVMThread_vmData, NULL);
2208 * Tell the debugger & DDM. This may cause the current thread or all
2209 * threads to suspend.
2211 * The JDWP spec is somewhat vague about when this happens, other than
2212 * that it's issued by the dying thread, which may still appear in
2213 * an "all threads" listing.
2215 if (gDvm.debuggerConnected)
2216 dvmDbgPostThreadDeath(self);
2219 * Thread.join() is implemented as an Object.wait() on the VMThread
2220 * object. Signal anyone who is waiting.
2222 dvmLockObject(self, vmThread);
2223 dvmObjectNotifyAll(self, vmThread);
2224 dvmUnlockObject(self, vmThread);
2226 dvmReleaseTrackedAlloc(vmThread, self);
2230 * We're done manipulating objects, so it's okay if the GC runs in
2231 * parallel with us from here out. It's important to do this if
2232 * profiling is enabled, since we can wait indefinitely.
2234 self->status = THREAD_VMWAIT;
2236 #ifdef WITH_PROFILER
2238 * If we're doing method trace profiling, we don't want threads to exit,
2239 * because if they do we'll end up reusing thread IDs. This complicates
2240 * analysis and makes it impossible to have reasonable output in the
2241 * "threads" section of the "key" file.
2243 * We need to do this after Thread.join() completes, or other threads
2244 * could get wedged. Since self->threadObj is still valid, the Thread
2245 * object will not get GCed even though we're no longer in the ThreadGroup
2246 * list (which is important since the profiling thread needs to get
2247 * the thread's name).
2249 MethodTraceState* traceState = &gDvm.methodTrace;
2251 dvmLockMutex(&traceState->startStopLock);
2252 if (traceState->traceEnabled) {
2253 LOGI("threadid=%d: waiting for method trace to finish\n",
2255 while (traceState->traceEnabled) {
2257 cc = pthread_cond_wait(&traceState->threadExitCond,
2258 &traceState->startStopLock);
2262 dvmUnlockMutex(&traceState->startStopLock);
2265 dvmLockThreadList(self);
2268 * Lose the JNI context.
2270 dvmDestroyJNIEnv(self->jniEnv);
2271 self->jniEnv = NULL;
2273 self->status = THREAD_ZOMBIE;
2276 * Remove ourselves from the internal thread list.
2281 * If we're the last one standing, signal anybody waiting in
2282 * DestroyJavaVM that it's okay to exit.
2284 if (!dvmGetFieldBoolean(self->threadObj, gDvm.offJavaLangThread_daemon)) {
2285 gDvm.nonDaemonThreadCount--; // guarded by thread list lock
2287 if (gDvm.nonDaemonThreadCount == 0) {
2290 LOGV("threadid=%d: last non-daemon thread\n", self->threadId);
2291 //dvmDumpAllThreads(false);
2292 // cond var guarded by threadListLock, which we already hold
2293 cc = pthread_cond_signal(&gDvm.vmExitCond);
2298 LOGV("threadid=%d: bye!\n", self->threadId);
2299 releaseThreadId(self);
2300 dvmUnlockThreadList();
2302 setThreadSelf(NULL);
2304 dvmDetachSystemThread(self);
2311 * Suspend a single thread. Do not use to suspend yourself.
2313 * This is used primarily for debugger/DDMS activity. Does not return
2314 * until the thread has suspended or is in a "safe" state (e.g. executing
2315 * native code outside the VM).
2317 * The thread list lock should be held before calling here -- it's not
2318 * entirely safe to hang on to a Thread* from another thread otherwise.
2319 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2321 void dvmSuspendThread(Thread* thread)
2323 assert(thread != NULL);
2324 assert(thread != dvmThreadSelf());
2325 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2327 lockThreadSuspendCount();
2328 dvmAddToThreadSuspendCount(&thread->suspendCount, 1);
2329 thread->dbgSuspendCount++;
2331 LOG_THREAD("threadid=%d: suspend++, now=%d\n",
2332 thread->threadId, thread->suspendCount);
2333 unlockThreadSuspendCount();
2335 waitForThreadSuspend(dvmThreadSelf(), thread);
2339 * Reduce the suspend count of a thread. If it hits zero, tell it to
2342 * Used primarily for debugger/DDMS activity. The thread in question
2343 * might have been suspended singly or as part of a suspend-all operation.
2345 * The thread list lock should be held before calling here -- it's not
2346 * entirely safe to hang on to a Thread* from another thread otherwise.
2347 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2349 void dvmResumeThread(Thread* thread)
2351 assert(thread != NULL);
2352 assert(thread != dvmThreadSelf());
2353 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2355 lockThreadSuspendCount();
2356 if (thread->suspendCount > 0) {
2357 dvmAddToThreadSuspendCount(&thread->suspendCount, -1);
2358 thread->dbgSuspendCount--;
2360 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2364 LOG_THREAD("threadid=%d: suspend--, now=%d\n",
2365 thread->threadId, thread->suspendCount);
2367 if (thread->suspendCount == 0) {
2368 int cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2372 unlockThreadSuspendCount();
2376 * Suspend yourself, as a result of debugger activity.
2378 void dvmSuspendSelf(bool jdwpActivity)
2380 Thread* self = dvmThreadSelf();
2382 /* debugger thread may not suspend itself due to debugger activity! */
2383 assert(gDvm.jdwpState != NULL);
2384 if (self->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2390 * Collisions with other suspends aren't really interesting. We want
2391 * to ensure that we're the only one fiddling with the suspend count
2394 lockThreadSuspendCount();
2395 dvmAddToThreadSuspendCount(&self->suspendCount, 1);
2396 self->dbgSuspendCount++;
2399 * Suspend ourselves.
2401 assert(self->suspendCount > 0);
2402 self->isSuspended = true;
2403 LOG_THREAD("threadid=%d: self-suspending (dbg)\n", self->threadId);
2406 * Tell JDWP that we've completed suspension. The JDWP thread can't
2407 * tell us to resume before we're fully asleep because we hold the
2408 * suspend count lock.
2410 * If we got here via waitForDebugger(), don't do this part.
2413 //LOGI("threadid=%d: clearing wait-for-event (my handle=%08x)\n",
2414 // self->threadId, (int) self->handle);
2415 dvmJdwpClearWaitForEventThread(gDvm.jdwpState);
2418 while (self->suspendCount != 0) {
2420 cc = pthread_cond_wait(&gDvm.threadSuspendCountCond,
2421 &gDvm.threadSuspendCountLock);
2423 if (self->suspendCount != 0) {
2425 * The condition was signaled but we're still suspended. This
2426 * can happen if the debugger lets go while a SIGQUIT thread
2427 * dump event is pending (assuming SignalCatcher was resumed for
2428 * just long enough to try to grab the thread-suspend lock).
2430 LOGD("threadid=%d: still suspended after undo (sc=%d dc=%d s=%c)\n",
2431 self->threadId, self->suspendCount, self->dbgSuspendCount,
2432 self->isSuspended ? 'Y' : 'N');
2435 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
2436 self->isSuspended = false;
2437 LOG_THREAD("threadid=%d: self-reviving (dbg), status=%d\n",
2438 self->threadId, self->status);
2440 unlockThreadSuspendCount();
2445 # define NUM_FRAMES 20
2446 # include <execinfo.h>
2448 * glibc-only stack dump function. Requires link with "--export-dynamic".
2450 * TODO: move this into libs/cutils and make it work for all platforms.
2452 static void printBackTrace(void)
2454 void* array[NUM_FRAMES];
2459 size = backtrace(array, NUM_FRAMES);
2460 strings = backtrace_symbols(array, size);
2462 LOGW("Obtained %zd stack frames.\n", size);
2464 for (i = 0; i < size; i++)
2465 LOGW("%s\n", strings[i]);
2470 static void printBackTrace(void) {}
2474 * Dump the state of the current thread and that of another thread that
2475 * we think is wedged.
2477 static void dumpWedgedThread(Thread* thread)
2482 * The "executablepath" function in libutils is host-side only.
2484 strcpy(exePath, "-");
2488 sprintf(proc, "/proc/%d/exe", getpid());
2491 len = readlink(proc, exePath, sizeof(exePath)-1);
2492 exePath[len] = '\0';
2496 LOGW("dumping state: process %s %d\n", exePath, getpid());
2497 dvmDumpThread(dvmThreadSelf(), false);
2500 // dumping a running thread is risky, but could be useful
2501 dvmDumpThread(thread, true);
2504 // stop now and get a core dump
2510 * Wait for another thread to see the pending suspension and stop running.
2511 * It can either suspend itself or go into a non-running state such as
2512 * VMWAIT or NATIVE in which it cannot interact with the GC.
2514 * If we're running at a higher priority, sched_yield() may not do anything,
2515 * so we need to sleep for "long enough" to guarantee that the other
2516 * thread has a chance to finish what it's doing. Sleeping for too short
2517 * a period (e.g. less than the resolution of the sleep clock) might cause
2518 * the scheduler to return immediately, so we want to start with a
2519 * "reasonable" value and expand.
2521 * This does not return until the other thread has stopped running.
2522 * Eventually we time out and the VM aborts.
2524 * This does not try to detect the situation where two threads are
2525 * waiting for each other to suspend. In normal use this is part of a
2526 * suspend-all, which implies that the suspend-all lock is held, or as
2527 * part of a debugger action in which the JDWP thread is always the one
2528 * doing the suspending. (We may need to re-evaluate this now that
2529 * getThreadStackTrace is implemented as suspend-snapshot-resume.)
2531 * TODO: track basic stats about time required to suspend VM.
2533 #define FIRST_SLEEP (250*1000) /* 0.25s */
2534 #define MORE_SLEEP (750*1000) /* 0.75s */
2535 static void waitForThreadSuspend(Thread* self, Thread* thread)
2537 const int kMaxRetries = 10;
2538 int spinSleepTime = FIRST_SLEEP;
2539 bool complained = false;
2540 bool needPriorityReset = false;
2541 int savedThreadPrio = -500;
2545 u8 startWhen = 0; // init req'd to placate gcc
2546 u8 firstStartWhen = 0;
2548 while (thread->status == THREAD_RUNNING && !thread->isSuspended) {
2549 if (sleepIter == 0) { // get current time on first iteration
2550 startWhen = dvmGetRelativeTimeUsec();
2551 if (firstStartWhen == 0) // first iteration of first attempt
2552 firstStartWhen = startWhen;
2555 * After waiting for a bit, check to see if the target thread is
2556 * running at a reduced priority. If so, bump it up temporarily
2557 * to give it more CPU time.
2559 * getpriority() returns the "nice" value, so larger numbers
2560 * indicate lower priority.
2562 * (Not currently changing the cgroup. Wasn't necessary in some
2563 * simple experiments.)
2565 if (retryCount == 2) {
2566 assert(thread->systemTid != 0);
2568 int threadPrio = getpriority(PRIO_PROCESS, thread->systemTid);
2569 if (errno == 0 && threadPrio > 0) {
2570 const int kHigher = 0;
2571 if (setpriority(PRIO_PROCESS, thread->systemTid, kHigher) < 0)
2573 LOGW("Couldn't raise priority on tid %d to %d\n",
2574 thread->systemTid, kHigher);
2576 savedThreadPrio = threadPrio;
2577 needPriorityReset = true;
2578 LOGD("Temporarily raising priority on tid %d (%d -> %d)\n",
2579 thread->systemTid, threadPrio, kHigher);
2585 #if defined (WITH_JIT)
2587 * If we're still waiting after the first timeout,
2588 * unchain all translations.
2590 if (gDvmJit.pJitEntryTable && retryCount > 0) {
2591 LOGD("JIT unchain all attempt #%d",retryCount);
2597 * Sleep briefly. The iterative sleep call returns false if we've
2598 * exceeded the total time limit for this round of sleeping.
2600 if (!dvmIterativeSleep(sleepIter++, spinSleepTime, startWhen)) {
2601 if (spinSleepTime != FIRST_SLEEP) {
2602 LOGW("threadid=%d: spin on suspend #%d threadid=%d (h=%d)\n",
2603 self->threadId, retryCount,
2604 thread->threadId, (int)thread->handle);
2605 dumpWedgedThread(thread);
2609 // keep going; could be slow due to valgrind
2611 spinSleepTime = MORE_SLEEP;
2613 if (retryCount++ == kMaxRetries) {
2614 LOGE("threadid=%d: stuck on threadid=%d, giving up\n",
2615 self->threadId, thread->threadId);
2616 dvmDumpAllThreads(false);
2623 LOGW("threadid=%d: spin on suspend resolved in %lld msec\n",
2625 (dvmGetRelativeTimeUsec() - firstStartWhen) / 1000);
2626 //dvmDumpThread(thread, false); /* suspended, so dump is safe */
2628 if (needPriorityReset) {
2629 if (setpriority(PRIO_PROCESS, thread->systemTid, savedThreadPrio) < 0) {
2630 LOGW("NOTE: couldn't reset priority on thread %d to %d\n",
2631 thread->systemTid, savedThreadPrio);
2633 LOGV("Restored priority on %d to %d\n",
2634 thread->systemTid, savedThreadPrio);
2640 * Suspend all threads except the current one. This is used by the GC,
2641 * the debugger, and by any thread that hits a "suspend all threads"
2642 * debugger event (e.g. breakpoint or exception).
2644 * If thread N hits a "suspend all threads" breakpoint, we don't want it
2645 * to suspend the JDWP thread. For the GC, we do, because the debugger can
2646 * create objects and even execute arbitrary code. The "why" argument
2647 * allows the caller to say why the suspension is taking place.
2649 * This can be called when a global suspend has already happened, due to
2650 * various debugger gymnastics, so keeping an "everybody is suspended" flag
2653 * DO NOT grab any locks before calling here. We grab & release the thread
2654 * lock and suspend lock here (and we're not using recursive threads), and
2655 * we might have to self-suspend if somebody else beats us here.
2657 * The current thread may not be attached to the VM. This can happen if
2658 * we happen to GC as the result of an allocation of a Thread object.
2660 void dvmSuspendAllThreads(SuspendCause why)
2662 Thread* self = dvmThreadSelf();
2668 * Start by grabbing the thread suspend lock. If we can't get it, most
2669 * likely somebody else is in the process of performing a suspend or
2670 * resume, so lockThreadSuspend() will cause us to self-suspend.
2672 * We keep the lock until all other threads are suspended.
2674 lockThreadSuspend("susp-all", why);
2676 LOG_THREAD("threadid=%d: SuspendAll starting\n", self->threadId);
2679 * This is possible if the current thread was in VMWAIT mode when a
2680 * suspend-all happened, and then decided to do its own suspend-all.
2681 * This can happen when a couple of threads have simultaneous events
2682 * of interest to the debugger.
2684 //assert(self->suspendCount == 0);
2687 * Increment everybody's suspend count (except our own).
2689 dvmLockThreadList(self);
2691 lockThreadSuspendCount();
2692 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2696 /* debugger events don't suspend JDWP thread */
2697 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2698 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2701 dvmAddToThreadSuspendCount(&thread->suspendCount, 1);
2702 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2703 thread->dbgSuspendCount++;
2705 unlockThreadSuspendCount();
2708 * Wait for everybody in THREAD_RUNNING state to stop. Other states
2709 * indicate the code is either running natively or sleeping quietly.
2710 * Any attempt to transition back to THREAD_RUNNING will cause a check
2711 * for suspension, so it should be impossible for anything to execute
2712 * interpreted code or modify objects (assuming native code plays nicely).
2714 * It's also okay if the thread transitions to a non-RUNNING state.
2716 * Note we released the threadSuspendCountLock before getting here,
2717 * so if another thread is fiddling with its suspend count (perhaps
2718 * self-suspending for the debugger) it won't block while we're waiting
2721 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2725 /* debugger events don't suspend JDWP thread */
2726 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2727 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2730 /* wait for the other thread to see the pending suspend */
2731 waitForThreadSuspend(self, thread);
2733 LOG_THREAD("threadid=%d: threadid=%d status=%d c=%d dc=%d isSusp=%d\n",
2735 thread->threadId, thread->status, thread->suspendCount,
2736 thread->dbgSuspendCount, thread->isSuspended);
2739 dvmUnlockThreadList();
2740 unlockThreadSuspend();
2742 LOG_THREAD("threadid=%d: SuspendAll complete\n", self->threadId);
2746 * Resume all threads that are currently suspended.
2748 * The "why" must match with the previous suspend.
2750 void dvmResumeAllThreads(SuspendCause why)
2752 Thread* self = dvmThreadSelf();
2756 lockThreadSuspend("res-all", why); /* one suspend/resume at a time */
2757 LOG_THREAD("threadid=%d: ResumeAll starting\n", self->threadId);
2760 * Decrement the suspend counts for all threads. No need for atomic
2761 * writes, since nobody should be moving until we decrement the count.
2762 * We do need to hold the thread list because of JNI attaches.
2764 dvmLockThreadList(self);
2765 lockThreadSuspendCount();
2766 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2770 /* debugger events don't suspend JDWP thread */
2771 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2772 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2777 if (thread->suspendCount > 0) {
2778 dvmAddToThreadSuspendCount(&thread->suspendCount, -1);
2779 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2780 thread->dbgSuspendCount--;
2782 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2786 unlockThreadSuspendCount();
2787 dvmUnlockThreadList();
2790 * In some ways it makes sense to continue to hold the thread-suspend
2791 * lock while we issue the wakeup broadcast. It allows us to complete
2792 * one operation before moving on to the next, which simplifies the
2793 * thread activity debug traces.
2795 * This approach caused us some difficulty under Linux, because the
2796 * condition variable broadcast not only made the threads runnable,
2797 * but actually caused them to execute, and it was a while before
2798 * the thread performing the wakeup had an opportunity to release the
2799 * thread-suspend lock.
2801 * This is a problem because, when a thread tries to acquire that
2802 * lock, it times out after 3 seconds. If at some point the thread
2803 * is told to suspend, the clock resets; but since the VM is still
2804 * theoretically mid-resume, there's no suspend pending. If, for
2805 * example, the GC was waking threads up while the SIGQUIT handler
2806 * was trying to acquire the lock, we would occasionally time out on
2807 * a busy system and SignalCatcher would abort.
2809 * We now perform the unlock before the wakeup broadcast. The next
2810 * suspend can't actually start until the broadcast completes and
2811 * returns, because we're holding the thread-suspend-count lock, but the
2812 * suspending thread is now able to make progress and we avoid the abort.
2814 * (Technically there is a narrow window between when we release
2815 * the thread-suspend lock and grab the thread-suspend-count lock.
2816 * This could cause us to send a broadcast to threads with nonzero
2817 * suspend counts, but this is expected and they'll all just fall
2818 * right back to sleep. It's probably safe to grab the suspend-count
2819 * lock before releasing thread-suspend, since we're still following
2820 * the correct order of acquisition, but it feels weird.)
2823 LOG_THREAD("threadid=%d: ResumeAll waking others\n", self->threadId);
2824 unlockThreadSuspend();
2827 * Broadcast a notification to all suspended threads, some or all of
2828 * which may choose to wake up. No need to wait for them.
2830 lockThreadSuspendCount();
2831 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2833 unlockThreadSuspendCount();
2835 LOG_THREAD("threadid=%d: ResumeAll complete\n", self->threadId);
2839 * Undo any debugger suspensions. This is called when the debugger
2842 void dvmUndoDebuggerSuspensions(void)
2844 Thread* self = dvmThreadSelf();
2848 lockThreadSuspend("undo", SUSPEND_FOR_DEBUG);
2849 LOG_THREAD("threadid=%d: UndoDebuggerSusp starting\n", self->threadId);
2852 * Decrement the suspend counts for all threads. No need for atomic
2853 * writes, since nobody should be moving until we decrement the count.
2854 * We do need to hold the thread list because of JNI attaches.
2856 dvmLockThreadList(self);
2857 lockThreadSuspendCount();
2858 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2862 /* debugger events don't suspend JDWP thread */
2863 if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2864 assert(thread->dbgSuspendCount == 0);
2868 assert(thread->suspendCount >= thread->dbgSuspendCount);
2869 dvmAddToThreadSuspendCount(&thread->suspendCount,
2870 -thread->dbgSuspendCount);
2871 thread->dbgSuspendCount = 0;
2873 unlockThreadSuspendCount();
2874 dvmUnlockThreadList();
2877 * Broadcast a notification to all suspended threads, some or all of
2878 * which may choose to wake up. No need to wait for them.
2880 lockThreadSuspendCount();
2881 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2883 unlockThreadSuspendCount();
2885 unlockThreadSuspend();
2887 LOG_THREAD("threadid=%d: UndoDebuggerSusp complete\n", self->threadId);
2891 * Determine if a thread is suspended.
2893 * As with all operations on foreign threads, the caller should hold
2894 * the thread list lock before calling.
2896 bool dvmIsSuspended(Thread* thread)
2899 * The thread could be:
2900 * (1) Running happily. status is RUNNING, isSuspended is false,
2901 * suspendCount is zero. Return "false".
2902 * (2) Pending suspend. status is RUNNING, isSuspended is false,
2903 * suspendCount is nonzero. Return "false".
2904 * (3) Suspended. suspendCount is nonzero, and either (status is
2905 * RUNNING and isSuspended is true) OR (status is !RUNNING).
2907 * (4) Waking up. suspendCount is zero, status is RUNNING and
2908 * isSuspended is true. Return "false" (since it could change
2909 * out from under us, unless we hold suspendCountLock).
2912 return (thread->suspendCount != 0 &&
2913 ((thread->status == THREAD_RUNNING && thread->isSuspended) ||
2914 (thread->status != THREAD_RUNNING)));
2918 * Wait until another thread self-suspends. This is specifically for
2919 * synchronization between the JDWP thread and a thread that has decided
2920 * to suspend itself after sending an event to the debugger.
2922 * Threads that encounter "suspend all" events work as well -- the thread
2923 * in question suspends everybody else and then itself.
2925 * We can't hold a thread lock here or in the caller, because we could
2926 * get here just before the to-be-waited-for-thread issues a "suspend all".
2927 * There's an opportunity for badness if the thread we're waiting for exits
2928 * and gets cleaned up, but since the thread in question is processing a
2929 * debugger event, that's not really a possibility. (To avoid deadlock,
2930 * it's important that we not be in THREAD_RUNNING while we wait.)
2932 void dvmWaitForSuspend(Thread* thread)
2934 Thread* self = dvmThreadSelf();
2936 LOG_THREAD("threadid=%d: waiting for threadid=%d to sleep\n",
2937 self->threadId, thread->threadId);
2939 assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2940 assert(thread != self);
2941 assert(self->status != THREAD_RUNNING);
2943 waitForThreadSuspend(self, thread);
2945 LOG_THREAD("threadid=%d: threadid=%d is now asleep\n",
2946 self->threadId, thread->threadId);
2950 * Check to see if we need to suspend ourselves. If so, go to sleep on
2951 * a condition variable.
2953 * Takes "self" as an argument as an optimization. Pass in NULL to have
2956 * Returns "true" if we suspended ourselves.
2958 bool dvmCheckSuspendPending(Thread* self)
2963 self = dvmThreadSelf();
2965 /* fast path: if count is zero, bail immediately */
2966 if (self->suspendCount == 0)
2969 lockThreadSuspendCount(); /* grab gDvm.threadSuspendCountLock */
2971 assert(self->suspendCount >= 0); /* XXX: valid? useful? */
2973 didSuspend = (self->suspendCount != 0);
2974 self->isSuspended = true;
2975 LOG_THREAD("threadid=%d: self-suspending\n", self->threadId);
2976 while (self->suspendCount != 0) {
2977 /* wait for wakeup signal; releases lock */
2979 cc = pthread_cond_wait(&gDvm.threadSuspendCountCond,
2980 &gDvm.threadSuspendCountLock);
2983 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
2984 self->isSuspended = false;
2985 LOG_THREAD("threadid=%d: self-reviving, status=%d\n",
2986 self->threadId, self->status);
2988 unlockThreadSuspendCount();
2994 * Update our status.
2996 * The "self" argument, which may be NULL, is accepted as an optimization.
2998 * Returns the old status.
3000 ThreadStatus dvmChangeStatus(Thread* self, ThreadStatus newStatus)
3002 ThreadStatus oldStatus;
3005 self = dvmThreadSelf();
3007 LOGVV("threadid=%d: (status %d -> %d)\n",
3008 self->threadId, self->status, newStatus);
3010 oldStatus = self->status;
3012 if (newStatus == THREAD_RUNNING) {
3014 * Change our status to THREAD_RUNNING. The transition requires
3015 * that we check for pending suspension, because the VM considers
3016 * us to be "asleep" in all other states.
3018 * We need to do the "suspend pending" check FIRST, because it grabs
3019 * a lock that could be held by something that wants us to suspend.
3020 * If we're in RUNNING it will wait for us, and we'll be waiting
3021 * for the lock it holds.
3023 assert(self->status != THREAD_RUNNING);
3025 dvmCheckSuspendPending(self);
3026 self->status = THREAD_RUNNING;
3029 * Change from one state to another, neither of which is
3030 * THREAD_RUNNING. This is most common during system or thread
3033 self->status = newStatus;
3040 * Get a statically defined thread group from a field in the ThreadGroup
3041 * Class object. Expected arguments are "mMain" and "mSystem".
3043 static Object* getStaticThreadGroup(const char* fieldName)
3045 StaticField* groupField;
3048 groupField = dvmFindStaticField(gDvm.classJavaLangThreadGroup,
3049 fieldName, "Ljava/lang/ThreadGroup;");
3050 if (groupField == NULL) {
3051 LOGE("java.lang.ThreadGroup does not have an '%s' field\n", fieldName);
3052 dvmThrowException("Ljava/lang/IncompatibleClassChangeError;", NULL);
3055 groupObj = dvmGetStaticFieldObject(groupField);
3056 if (groupObj == NULL) {
3057 LOGE("java.lang.ThreadGroup.%s not initialized\n", fieldName);
3058 dvmThrowException("Ljava/lang/InternalError;", NULL);
3064 Object* dvmGetSystemThreadGroup(void)
3066 return getStaticThreadGroup("mSystem");
3068 Object* dvmGetMainThreadGroup(void)
3070 return getStaticThreadGroup("mMain");
3074 * Given a VMThread object, return the associated Thread*.
3076 * NOTE: if the thread detaches, the struct Thread will disappear, and
3077 * we will be touching invalid data. For safety, lock the thread list
3078 * before calling this.
3080 Thread* dvmGetThreadFromThreadObject(Object* vmThreadObj)
3084 vmData = dvmGetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData);
3087 Thread* thread = gDvm.threadList;
3088 while (thread != NULL) {
3089 if ((Thread*)vmData == thread)
3092 thread = thread->next;
3095 if (thread == NULL) {
3096 LOGW("WARNING: vmThreadObj=%p has thread=%p, not in thread list\n",
3097 vmThreadObj, (Thread*)vmData);
3102 return (Thread*) vmData;
3107 * Conversion map for "nice" values.
3109 * We use Android thread priority constants to be consistent with the rest
3110 * of the system. In some cases adjacent entries may overlap.
3112 static const int kNiceValues[10] = {
3113 ANDROID_PRIORITY_LOWEST, /* 1 (MIN_PRIORITY) */
3114 ANDROID_PRIORITY_BACKGROUND + 6,
3115 ANDROID_PRIORITY_BACKGROUND + 3,
3116 ANDROID_PRIORITY_BACKGROUND,
3117 ANDROID_PRIORITY_NORMAL, /* 5 (NORM_PRIORITY) */
3118 ANDROID_PRIORITY_NORMAL - 2,
3119 ANDROID_PRIORITY_NORMAL - 4,
3120 ANDROID_PRIORITY_URGENT_DISPLAY + 3,
3121 ANDROID_PRIORITY_URGENT_DISPLAY + 2,
3122 ANDROID_PRIORITY_URGENT_DISPLAY /* 10 (MAX_PRIORITY) */
3126 * Change the priority of a system thread to match that of the Thread object.
3128 * We map a priority value from 1-10 to Linux "nice" values, where lower
3129 * numbers indicate higher priority.
3131 void dvmChangeThreadPriority(Thread* thread, int newPriority)
3133 pid_t pid = thread->systemTid;
3136 if (newPriority < 1 || newPriority > 10) {
3137 LOGW("bad priority %d\n", newPriority);
3140 newNice = kNiceValues[newPriority-1];
3142 if (newNice >= ANDROID_PRIORITY_BACKGROUND) {
3143 set_sched_policy(dvmGetSysThreadId(), SP_BACKGROUND);
3144 } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
3145 set_sched_policy(dvmGetSysThreadId(), SP_FOREGROUND);
3148 if (setpriority(PRIO_PROCESS, pid, newNice) != 0) {
3149 char* str = dvmGetThreadName(thread);
3150 LOGI("setPriority(%d) '%s' to prio=%d(n=%d) failed: %s\n",
3151 pid, str, newPriority, newNice, strerror(errno));
3154 LOGV("setPriority(%d) to prio=%d(n=%d)\n",
3155 pid, newPriority, newNice);
3160 * Get the thread priority for the current thread by querying the system.
3161 * This is useful when attaching a thread through JNI.
3163 * Returns a value from 1 to 10 (compatible with java.lang.Thread values).
3165 static int getThreadPriorityFromSystem(void)
3167 int i, sysprio, jprio;
3170 sysprio = getpriority(PRIO_PROCESS, 0);
3171 if (sysprio == -1 && errno != 0) {
3172 LOGW("getpriority() failed: %s\n", strerror(errno));
3173 return THREAD_NORM_PRIORITY;
3176 jprio = THREAD_MIN_PRIORITY;
3177 for (i = 0; i < NELEM(kNiceValues); i++) {
3178 if (sysprio >= kNiceValues[i])
3182 if (jprio > THREAD_MAX_PRIORITY)
3183 jprio = THREAD_MAX_PRIORITY;
3190 * Return true if the thread is on gDvm.threadList.
3191 * Caller should not hold gDvm.threadListLock.
3193 bool dvmIsOnThreadList(const Thread* thread)
3197 dvmLockThreadList(NULL);
3198 if (thread == gDvm.threadList) {
3201 ret = thread->prev != NULL || thread->next != NULL;
3203 dvmUnlockThreadList();
3209 * Dump a thread to the log file -- just calls dvmDumpThreadEx() with an
3212 void dvmDumpThread(Thread* thread, bool isRunning)
3214 DebugOutputTarget target;
3216 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
3217 dvmDumpThreadEx(&target, thread, isRunning);
3221 * Try to get the scheduler group.
3223 * The data from /proc/<pid>/cgroup looks like:
3224 * 2:cpu:/bg_non_interactive
3226 * We return the part after the "/", which will be an empty string for
3227 * the default cgroup. If the string is longer than "bufLen", the string
3228 * will be truncated.
3230 static bool getSchedulerGroup(Thread* thread, char* buf, size_t bufLen)
3232 #ifdef HAVE_ANDROID_OS
3238 snprintf(pathBuf, sizeof(pathBuf), "/proc/%d/cgroup", thread->systemTid);
3239 if ((fd = open(pathBuf, O_RDONLY)) < 0) {
3240 LOGV("open(%s) failed: %s\n", pathBuf, strerror(errno));
3244 count = read(fd, readBuf, sizeof(readBuf));
3246 LOGV("read(%s) failed (%d): %s\n",
3247 pathBuf, (int) count, strerror(errno));
3253 readBuf[--count] = '\0'; /* remove the '\n', now count==strlen */
3255 char* cp = strchr(readBuf, '/');
3257 readBuf[sizeof(readBuf)-1] = '\0';
3258 LOGV("no '/' in '%s' (file=%s count=%d)\n",
3259 readBuf, pathBuf, (int) count);
3263 memcpy(buf, cp+1, count); /* count-1 for cp+1, count+1 for NUL */
3271 * Convert ThreadStatus to a string.
3273 const char* dvmGetThreadStatusStr(ThreadStatus status)
3276 case THREAD_ZOMBIE: return "ZOMBIE";
3277 case THREAD_RUNNING: return "RUNNABLE";
3278 case THREAD_TIMED_WAIT: return "TIMED_WAIT";
3279 case THREAD_MONITOR: return "MONITOR";
3280 case THREAD_WAIT: return "WAIT";
3281 case THREAD_INITIALIZING: return "INITIALIZING";
3282 case THREAD_STARTING: return "STARTING";
3283 case THREAD_NATIVE: return "NATIVE";
3284 case THREAD_VMWAIT: return "VMWAIT";
3285 default: return "UNKNOWN";
3290 * Print information about the specified thread.
3292 * Works best when the thread in question is "self" or has been suspended.
3293 * When dumping a separate thread that's still running, set "isRunning" to
3294 * use a more cautious thread dump function.
3296 void dvmDumpThreadEx(const DebugOutputTarget* target, Thread* thread,
3301 StringObject* nameStr;
3302 char* threadName = NULL;
3303 char* groupName = NULL;
3304 char schedulerGroupBuf[32];
3306 int priority; // java.lang.Thread priority
3307 int policy; // pthread policy
3308 struct sched_param sp; // pthread scheduling parameters
3310 threadObj = thread->threadObj;
3311 if (threadObj == NULL) {
3312 LOGW("Can't dump thread %d: threadObj not set\n", thread->threadId);
3315 nameStr = (StringObject*) dvmGetFieldObject(threadObj,
3316 gDvm.offJavaLangThread_name);
3317 threadName = dvmCreateCstrFromString(nameStr);
3319 priority = dvmGetFieldInt(threadObj, gDvm.offJavaLangThread_priority);
3320 isDaemon = dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon);
3322 if (pthread_getschedparam(pthread_self(), &policy, &sp) != 0) {
3323 LOGW("Warning: pthread_getschedparam failed\n");
3325 sp.sched_priority = -1;
3327 if (!getSchedulerGroup(thread, schedulerGroupBuf,sizeof(schedulerGroupBuf)))
3329 strcpy(schedulerGroupBuf, "unknown");
3330 } else if (schedulerGroupBuf[0] == '\0') {
3331 strcpy(schedulerGroupBuf, "default");
3334 /* a null value for group is not expected, but deal with it anyway */
3335 groupObj = (Object*) dvmGetFieldObject(threadObj,
3336 gDvm.offJavaLangThread_group);
3337 if (groupObj != NULL) {
3338 int offset = dvmFindFieldOffset(gDvm.classJavaLangThreadGroup,
3339 "name", "Ljava/lang/String;");
3341 LOGW("Unable to find 'name' field in ThreadGroup\n");
3343 nameStr = (StringObject*) dvmGetFieldObject(groupObj, offset);
3344 groupName = dvmCreateCstrFromString(nameStr);
3347 if (groupName == NULL)
3348 groupName = strdup("(BOGUS GROUP)");
3350 dvmPrintDebugMessage(target,
3351 "\"%s\"%s prio=%d tid=%d %s\n",
3352 threadName, isDaemon ? " daemon" : "",
3353 priority, thread->threadId, dvmGetThreadStatusStr(thread->status));
3354 dvmPrintDebugMessage(target,
3355 " | group=\"%s\" sCount=%d dsCount=%d s=%c obj=%p self=%p\n",
3356 groupName, thread->suspendCount, thread->dbgSuspendCount,
3357 thread->isSuspended ? 'Y' : 'N', thread->threadObj, thread);
3358 dvmPrintDebugMessage(target,
3359 " | sysTid=%d nice=%d sched=%d/%d cgrp=%s handle=%d\n",
3360 thread->systemTid, getpriority(PRIO_PROCESS, thread->systemTid),
3361 policy, sp.sched_priority, schedulerGroupBuf, (int)thread->handle);
3363 #ifdef WITH_MONITOR_TRACKING
3365 LockedObjectData* lod = thread->pLockedObjects;
3367 dvmPrintDebugMessage(target, " | monitors held:\n");
3369 dvmPrintDebugMessage(target, " | monitors held: <none>\n");
3370 while (lod != NULL) {
3371 Object* obj = lod->obj;
3372 if (obj->clazz == gDvm.classJavaLangClass) {
3373 ClassObject* clazz = (ClassObject*) obj;
3374 dvmPrintDebugMessage(target, " > %p[%d] (%s object for class %s)\n",
3375 obj, lod->recursionCount, obj->clazz->descriptor,
3378 dvmPrintDebugMessage(target, " > %p[%d] (%s)\n",
3379 obj, lod->recursionCount, obj->clazz->descriptor);
3387 dvmDumpRunningThreadStack(target, thread);
3389 dvmDumpThreadStack(target, thread);
3397 * Get the name of a thread.
3399 * For correctness, the caller should hold the thread list lock to ensure
3400 * that the thread doesn't go away mid-call.
3402 * Returns a newly-allocated string, or NULL if the Thread doesn't have a name.
3404 char* dvmGetThreadName(Thread* thread)
3406 StringObject* nameObj;
3408 if (thread->threadObj == NULL) {
3409 LOGW("threadObj is NULL, name not available\n");
3410 return strdup("-unknown-");
3413 nameObj = (StringObject*)
3414 dvmGetFieldObject(thread->threadObj, gDvm.offJavaLangThread_name);
3415 return dvmCreateCstrFromString(nameObj);
3419 * Dump all threads to the log file -- just calls dvmDumpAllThreadsEx() with
3422 void dvmDumpAllThreads(bool grabLock)
3424 DebugOutputTarget target;
3426 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
3427 dvmDumpAllThreadsEx(&target, grabLock);
3431 * Print information about all known threads. Assumes they have been
3432 * suspended (or are in a non-interpreting state, e.g. WAIT or NATIVE).
3434 * If "grabLock" is true, we grab the thread lock list. This is important
3435 * to do unless the caller already holds the lock.
3437 void dvmDumpAllThreadsEx(const DebugOutputTarget* target, bool grabLock)
3441 dvmPrintDebugMessage(target, "DALVIK THREADS:\n");
3444 dvmLockThreadList(dvmThreadSelf());
3446 thread = gDvm.threadList;
3447 while (thread != NULL) {
3448 dvmDumpThreadEx(target, thread, false);
3451 assert(thread->next == NULL || thread->next->prev == thread);
3453 thread = thread->next;
3457 dvmUnlockThreadList();
3460 #ifdef WITH_MONITOR_TRACKING
3462 * Count up the #of locked objects in the current thread.
3464 static int getThreadObjectCount(const Thread* self)
3466 LockedObjectData* lod;
3469 lod = self->pLockedObjects;
3470 while (lod != NULL) {
3478 * Add the object to the thread's locked object list if it doesn't already
3479 * exist. The most recently added object is the most likely to be released
3480 * next, so we insert at the head of the list.
3482 * If it already exists, we increase the recursive lock count.
3484 * The object's lock may be thin or fat.
3486 void dvmAddToMonitorList(Thread* self, Object* obj, bool withTrace)
3488 LockedObjectData* newLod;
3489 LockedObjectData* lod;
3493 lod = self->pLockedObjects;
3494 while (lod != NULL) {
3495 if (lod->obj == obj) {
3496 lod->recursionCount++;
3497 LOGV("+++ +recursive lock %p -> %d\n", obj, lod->recursionCount);
3503 newLod = (LockedObjectData*) calloc(1, sizeof(LockedObjectData));
3504 if (newLod == NULL) {
3505 LOGE("malloc failed on %d bytes\n", sizeof(LockedObjectData));
3509 newLod->recursionCount = 0;
3512 trace = dvmFillInStackTraceRaw(self, &depth);
3513 newLod->rawStackTrace = trace;
3514 newLod->stackDepth = depth;
3517 newLod->next = self->pLockedObjects;
3518 self->pLockedObjects = newLod;
3520 LOGV("+++ threadid=%d: added %p, now %d\n",
3521 self->threadId, newLod, getThreadObjectCount(self));
3525 * Remove the object from the thread's locked object list. If the entry
3526 * has a nonzero recursion count, we just decrement the count instead.
3528 void dvmRemoveFromMonitorList(Thread* self, Object* obj)
3530 LockedObjectData* lod;
3531 LockedObjectData* prevLod;
3533 lod = self->pLockedObjects;
3535 while (lod != NULL) {
3536 if (lod->obj == obj) {
3537 if (lod->recursionCount > 0) {
3538 lod->recursionCount--;
3539 LOGV("+++ -recursive lock %p -> %d\n",
3540 obj, lod->recursionCount);
3551 LOGW("BUG: object %p not found in thread's lock list\n", obj);
3554 if (prevLod == NULL) {
3555 /* first item in list */
3556 assert(self->pLockedObjects == lod);
3557 self->pLockedObjects = lod->next;
3559 /* middle/end of list */
3560 prevLod->next = lod->next;
3563 LOGV("+++ threadid=%d: removed %p, now %d\n",
3564 self->threadId, lod, getThreadObjectCount(self));
3565 free(lod->rawStackTrace);
3570 * If the specified object is already in the thread's locked object list,
3571 * return the LockedObjectData struct. Otherwise return NULL.
3573 LockedObjectData* dvmFindInMonitorList(const Thread* self, const Object* obj)
3575 LockedObjectData* lod;
3577 lod = self->pLockedObjects;
3578 while (lod != NULL) {
3579 if (lod->obj == obj)
3585 #endif /*WITH_MONITOR_TRACKING*/
3589 * GC helper functions
3593 * Add the contents of the registers from the interpreted call stack.
3595 static void gcScanInterpStackReferences(Thread *thread)
3598 #if WITH_EXTRA_GC_CHECKS > 1
3602 framePtr = (const u4 *)thread->curFrame;
3603 while (framePtr != NULL) {
3604 const StackSaveArea *saveArea;
3605 const Method *method;
3607 saveArea = SAVEAREA_FROM_FP(framePtr);
3608 method = saveArea->method;
3609 if (method != NULL && !dvmIsNativeMethod(method)) {
3610 #ifdef COUNT_PRECISE_METHODS
3611 /* the GC is running, so no lock required */
3612 if (dvmPointerSetAddEntry(gDvm.preciseMethods, method))
3613 LOGI("PGC: added %s.%s %p\n",
3614 method->clazz->descriptor, method->name, method);
3616 #if WITH_EXTRA_GC_CHECKS > 1
3618 * May also want to enable the memset() in the "invokeMethod"
3619 * goto target in the portable interpreter. That sets the stack
3620 * to a pattern that makes referring to uninitialized data
3626 * First frame, isn't native, check the "alternate" saved PC
3627 * as a sanity check.
3629 * It seems like we could check the second frame if the first
3630 * is native, since the PCs should be the same. It turns out
3631 * this doesn't always work. The problem is that we could
3632 * have calls in the sequence:
3637 * and then GC while in the native method after returning
3638 * from interp method #2. The currentPc on the stack is
3639 * for interp method #1, but thread->currentPc2 is still
3640 * set for the last thing interp method #2 did.
3642 * This can also happen in normal execution:
3643 * - sget-object on not-yet-loaded class
3644 * - class init updates currentPc2
3645 * - static field init is handled by parsing annotations;
3646 * static String init requires creation of a String object,
3647 * which can cause a GC
3649 * Essentially, any pattern that involves executing
3650 * interpreted code and then causes an allocation without
3651 * executing instructions in the original method will hit
3652 * this. These are rare enough that the test still has
3655 if (saveArea->xtra.currentPc != thread->currentPc2) {
3656 LOGW("PGC: savedPC(%p) != current PC(%p), %s.%s ins=%p\n",
3657 saveArea->xtra.currentPc, thread->currentPc2,
3658 method->clazz->descriptor, method->name, method->insns);
3659 if (saveArea->xtra.currentPc != NULL)
3660 LOGE(" pc inst = 0x%04x\n", *saveArea->xtra.currentPc);
3661 if (thread->currentPc2 != NULL)
3662 LOGE(" pc2 inst = 0x%04x\n", *thread->currentPc2);
3663 dvmDumpThread(thread, false);
3667 * It's unusual, but not impossible, for a non-first frame
3668 * to be at something other than a method invocation. For
3669 * example, if we do a new-instance on a nonexistent class,
3670 * we'll have a lot of class loader activity on the stack
3671 * above the frame with the "new" operation. Could also
3672 * happen while we initialize a Throwable when an instruction
3675 * So there's not much we can do here to verify the PC,
3676 * except to verify that it's a GC point.
3679 assert(saveArea->xtra.currentPc != NULL);
3682 const RegisterMap* pMap;
3683 const u1* regVector;
3686 Method* nonConstMethod = (Method*) method; // quiet gcc
3687 pMap = dvmGetExpandedRegisterMap(nonConstMethod);
3689 /* found map, get registers for this address */
3690 int addr = saveArea->xtra.currentPc - method->insns;
3691 regVector = dvmRegisterMapGetLine(pMap, addr);
3692 if (regVector == NULL) {
3693 LOGW("PGC: map but no entry for %s.%s addr=0x%04x\n",
3694 method->clazz->descriptor, method->name, addr);
3696 LOGV("PGC: found map for %s.%s 0x%04x (t=%d)\n",
3697 method->clazz->descriptor, method->name, addr,
3702 * No map found. If precise GC is disabled this is
3703 * expected -- we don't create pointers to the map data even
3704 * if it's present -- but if it's enabled it means we're
3705 * unexpectedly falling back on a conservative scan, so it's
3706 * worth yelling a little.
3708 if (gDvm.preciseGc) {
3709 LOGVV("PGC: no map for %s.%s\n",
3710 method->clazz->descriptor, method->name);
3715 if (regVector == NULL) {
3716 /* conservative scan */
3717 for (i = method->registersSize - 1; i >= 0; i--) {
3718 u4 rval = *framePtr++;
3719 if (rval != 0 && (rval & 0x3) == 0) {
3720 dvmMarkIfObject((Object *)rval);
3725 * Precise scan. v0 is at the lowest address on the
3726 * interpreted stack, and is the first bit in the register
3727 * vector, so we can walk through the register map and
3728 * memory in the same direction.
3730 * A '1' bit indicates a live reference.
3733 for (i = method->registersSize - 1; i >= 0; i--) {
3734 u4 rval = *framePtr++;
3738 /* set bit 9 so we can tell when we're empty */
3739 bits = *regVector++ | 0x0100;
3740 LOGVV("loaded bits: 0x%02x\n", bits & 0xff);
3743 if (rval != 0 && (bits & 0x01) != 0) {
3745 * Non-null, register marked as live reference. This
3746 * should always be a valid object.
3748 #if WITH_EXTRA_GC_CHECKS > 0
3749 if ((rval & 0x3) != 0 ||
3750 !dvmIsValidObject((Object*) rval))
3752 /* this is very bad */
3753 LOGE("PGC: invalid ref in reg %d: 0x%08x\n",
3754 method->registersSize-1 - i, rval);
3758 dvmMarkObjectNonNull((Object *)rval);
3762 * Null or non-reference, do nothing at all.
3764 #if WITH_EXTRA_GC_CHECKS > 1
3765 if (dvmIsValidObject((Object*) rval)) {
3766 /* this is normal, but we feel chatty */
3767 LOGD("PGC: ignoring valid ref in reg %d: 0x%08x\n",
3768 method->registersSize-1 - i, rval);
3773 dvmReleaseRegisterMapLine(pMap, regVector);
3776 /* else this is a break frame and there is nothing to mark, or
3777 * this is a native method and the registers are just the "ins",
3778 * copied from various registers in the caller's set.
3781 #if WITH_EXTRA_GC_CHECKS > 1
3785 /* Don't fall into an infinite loop if things get corrupted.
3787 assert((uintptr_t)saveArea->prevFrame > (uintptr_t)framePtr ||
3788 saveArea->prevFrame == NULL);
3789 framePtr = saveArea->prevFrame;
3793 static void gcScanReferenceTable(ReferenceTable *refTable)
3797 //TODO: these asserts are overkill; turn them off when things stablize.
3798 assert(refTable != NULL);
3799 assert(refTable->table != NULL);
3800 assert(refTable->nextEntry != NULL);
3801 assert((uintptr_t)refTable->nextEntry >= (uintptr_t)refTable->table);
3802 assert(refTable->nextEntry - refTable->table <= refTable->maxEntries);
3804 op = refTable->table;
3805 while ((uintptr_t)op < (uintptr_t)refTable->nextEntry) {
3806 dvmMarkObjectNonNull(*(op++));
3810 static void gcScanIndirectRefTable(IndirectRefTable* pRefTable)
3812 Object** op = pRefTable->table;
3813 int numEntries = dvmIndirectRefTableEntries(pRefTable);
3816 for (i = 0; i < numEntries; i++) {
3819 dvmMarkObjectNonNull(obj);
3825 * Scan a Thread and mark any objects it references.
3827 static void gcScanThread(Thread *thread)
3829 assert(thread != NULL);
3832 * The target thread must be suspended or in a state where it can't do
3833 * any harm (e.g. in Object.wait()). The only exception is the current
3834 * thread, which will still be active and in the "running" state.
3836 * (Newly-created threads shouldn't be able to shift themselves to
3837 * RUNNING without a suspend-pending check, so this shouldn't cause
3838 * a false-positive.)
3840 if (thread->status == THREAD_RUNNING && !thread->isSuspended &&
3841 thread != dvmThreadSelf())
3843 Thread* self = dvmThreadSelf();
3844 LOGW("threadid=%d: BUG: GC scanning a running thread (%d)\n",
3845 self->threadId, thread->threadId);
3846 dvmDumpThread(thread, true);
3847 LOGW("Found by:\n");
3848 dvmDumpThread(self, false);
3850 /* continue anyway? */
3854 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_THREAD_OBJECT, thread->threadId);
3856 dvmMarkObject(thread->threadObj); // could be NULL, when constructing
3858 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_NATIVE_STACK, thread->threadId);
3860 dvmMarkObject(thread->exception); // usually NULL
3861 gcScanReferenceTable(&thread->internalLocalRefTable);
3863 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_LOCAL, thread->threadId);
3865 #ifdef USE_INDIRECT_REF
3866 gcScanIndirectRefTable(&thread->jniLocalRefTable);
3868 gcScanReferenceTable(&thread->jniLocalRefTable);
3871 if (thread->jniMonitorRefTable.table != NULL) {
3872 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_MONITOR, thread->threadId);
3874 gcScanReferenceTable(&thread->jniMonitorRefTable);
3877 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JAVA_FRAME, thread->threadId);
3879 gcScanInterpStackReferences(thread);
3881 HPROF_CLEAR_GC_SCAN_STATE();
3884 static void gcScanAllThreads()
3888 /* Lock the thread list so we can safely use the
3889 * next/prev pointers.
3891 dvmLockThreadList(dvmThreadSelf());
3893 for (thread = gDvm.threadList; thread != NULL;
3894 thread = thread->next)
3896 /* We need to scan our own stack, so don't special-case
3897 * the current thread.
3899 gcScanThread(thread);
3902 dvmUnlockThreadList();
3905 void dvmGcScanRootThreadGroups()
3907 /* We scan the VM's list of threads instead of going
3908 * through the actual ThreadGroups, but it should be
3911 * This assumes that the ThreadGroup class object is in
3912 * the root set, which should always be true; it's
3913 * loaded by the built-in class loader, which is part