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.
22 #include "utils/threads.h" // need Android thread priorities
27 #include <sys/types.h>
28 #include <sys/resource.h>
34 #if defined(HAVE_PRCTL)
35 #include <sys/prctl.h>
38 #if defined(WITH_SELF_VERIFICATION)
39 #include "interp/Jit.h" // need for self verification
43 /* desktop Linux needs a little help with gettid() */
44 #if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS)
46 # include <linux/unistd.h>
48 _syscall0(pid_t,gettid)
50 pid_t gettid() { return syscall(__NR_gettid);}
55 // Change this to enable logging on cgroup errors
56 #define ENABLE_CGROUP_ERR_LOGGING 0
58 // change this to LOGV/LOGD to debug thread activity
59 #define LOG_THREAD LOGVV
64 All threads are native pthreads. All threads, except the JDWP debugger
65 thread, are visible to code running in the VM and to the debugger. (We
66 don't want the debugger to try to manipulate the thread that listens for
67 instructions from the debugger.) Internal VM threads are in the "system"
68 ThreadGroup, all others are in the "main" ThreadGroup, per convention.
70 The GC only runs when all threads have been suspended. Threads are
71 expected to suspend themselves, using a "safe point" mechanism. We check
72 for a suspend request at certain points in the main interpreter loop,
73 and on requests coming in from native code (e.g. all JNI functions).
74 Certain debugger events may inspire threads to self-suspend.
76 Native methods must use JNI calls to modify object references to avoid
77 clashes with the GC. JNI doesn't provide a way for native code to access
78 arrays of objects as such -- code must always get/set individual entries --
79 so it should be possible to fully control access through JNI.
81 Internal native VM threads, such as the finalizer thread, must explicitly
82 check for suspension periodically. In most cases they will be sound
83 asleep on a condition variable, and won't notice the suspension anyway.
85 Threads may be suspended by the GC, debugger, or the SIGQUIT listener
86 thread. The debugger may suspend or resume individual threads, while the
87 GC always suspends all threads. Each thread has a "suspend count" that
88 is incremented on suspend requests and decremented on resume requests.
89 When the count is zero, the thread is runnable. This allows us to fulfill
90 a debugger requirement: if the debugger suspends a thread, the thread is
91 not allowed to run again until the debugger resumes it (or disconnects,
92 in which case we must resume all debugger-suspended threads).
94 Paused threads sleep on a condition variable, and are awoken en masse.
95 Certain "slow" VM operations, such as starting up a new thread, will be
96 done in a separate "VMWAIT" state, so that the rest of the VM doesn't
97 freeze up waiting for the operation to finish. Threads must check for
98 pending suspension when leaving VMWAIT.
100 Because threads suspend themselves while interpreting code or when native
101 code makes JNI calls, there is no risk of suspending while holding internal
102 VM locks. All threads can enter a suspended (or native-code-only) state.
103 Also, we don't have to worry about object references existing solely
104 in hardware registers.
106 We do, however, have to worry about objects that were allocated internally
107 and aren't yet visible to anything else in the VM. If we allocate an
108 object, and then go to sleep on a mutex after changing to a non-RUNNING
109 state (e.g. while trying to allocate a second object), the first object
110 could be garbage-collected out from under us while we sleep. To manage
111 this, we automatically add all allocated objects to an internal object
112 tracking list, and only remove them when we know we won't be suspended
113 before the object appears in the GC root set.
115 The debugger may choose to suspend or resume a single thread, which can
116 lead to application-level deadlocks; this is expected behavior. The VM
117 will only check for suspension of single threads when the debugger is
118 active (the java.lang.Thread calls for this are deprecated and hence are
119 not supported). Resumption of a single thread is handled by decrementing
120 the thread's suspend count and sending a broadcast signal to the condition
121 variable. (This will cause all threads to wake up and immediately go back
122 to sleep, which isn't tremendously efficient, but neither is having the
125 The debugger is not allowed to resume threads suspended by the GC. This
126 is trivially enforced by ignoring debugger requests while the GC is running
127 (the JDWP thread is suspended during GC).
129 The VM maintains a Thread struct for every pthread known to the VM. There
130 is a java/lang/Thread object associated with every Thread. At present,
131 there is no safe way to go from a Thread object to a Thread struct except by
132 locking and scanning the list; this is necessary because the lifetimes of
133 the two are not closely coupled. We may want to change this behavior,
134 though at present the only performance impact is on the debugger (see
135 threadObjToThread()). See also notes about dvmDetachCurrentThread().
138 Alternate implementation (signal-based):
140 Threads run without safe points -- zero overhead. The VM uses a signal
141 (e.g. pthread_kill(SIGUSR1)) to notify threads of suspension or resumption.
143 The trouble with using signals to suspend threads is that it means a thread
144 can be in the middle of an operation when garbage collection starts.
145 To prevent some sticky situations, we have to introduce critical sections
148 Critical sections temporarily block suspension for a given thread.
149 The thread must move to a non-blocked state (and self-suspend) after
150 finishing its current task. If the thread blocks on a resource held
151 by a suspended thread, we're hosed.
153 One approach is to require that no blocking operations, notably
154 acquisition of mutexes, can be performed within a critical section.
155 This is too limiting. For example, if thread A gets suspended while
156 holding the thread list lock, it will prevent the GC or debugger from
157 being able to safely access the thread list. We need to wrap the critical
158 section around the entire operation (enter critical, get lock, do stuff,
159 release lock, exit critical).
161 A better approach is to declare that certain resources can only be held
162 within critical sections. A thread that enters a critical section and
163 then gets blocked on the thread list lock knows that the thread it is
164 waiting for is also in a critical section, and will release the lock
165 before suspending itself. Eventually all threads will complete their
166 operations and self-suspend. For this to work, the VM must:
168 (1) Determine the set of resources that may be accessed from the GC or
169 debugger threads. The mutexes guarding those go into the "critical
171 (2) Ensure that no resource in the CRS can be acquired outside of a
172 critical section. This can be verified with an assert().
173 (3) Ensure that only resources in the CRS can be held while in a critical
174 section. This is harder to enforce.
176 If any of these conditions are not met, deadlock can ensue when grabbing
177 resources in the GC or debugger (#1) or waiting for threads to suspend
178 (#2,#3). (You won't actually deadlock in the GC, because if the semantics
179 above are followed you don't need to lock anything in the GC. The risk is
180 rather that the GC will access data structures in an intermediate state.)
182 This approach requires more care and awareness in the VM than
183 safe-pointing. Because the GC and debugger are fairly intrusive, there
184 really aren't any internal VM resources that aren't shared. Thus, the
185 enter/exit critical calls can be added to internal mutex wrappers, which
186 makes it easy to get #1 and #2 right.
188 An ordering should be established for all locks to avoid deadlocks.
190 Monitor locks, which are also implemented with pthread calls, should not
191 cause any problems here. Threads fighting over such locks will not be in
192 critical sections and can be suspended freely.
194 This can get tricky if we ever need exclusive access to VM and non-VM
195 resources at the same time. It's not clear if this is a real concern.
197 There are (at least) two ways to handle the incoming signals:
199 (a) Always accept signals. If we're in a critical section, the signal
200 handler just returns without doing anything (the "suspend level"
201 should have been incremented before the signal was sent). Otherwise,
202 if the "suspend level" is nonzero, we go to sleep.
203 (b) Block signals in critical sections. This ensures that we can't be
204 interrupted in a critical section, but requires pthread_sigmask()
205 calls on entry and exit.
207 This is a choice between blocking the message and blocking the messenger.
208 Because UNIX signals are unreliable (you can only know that you have been
209 signaled, not whether you were signaled once or 10 times), the choice is
210 not significant for correctness. The choice depends on the efficiency
211 of pthread_sigmask() and the desire to actually block signals. Either way,
212 it is best to ensure that there is only one indication of "blocked";
213 having two (i.e. block signals and set a flag, then only send a signal
214 if the flag isn't set) can lead to race conditions.
216 The signal handler must take care to copy registers onto the stack (via
217 setjmp), so that stack scans find all references. Because we have to scan
218 native stacks, "exact" GC is not possible with this approach.
220 Some other concerns with flinging signals around:
221 - Odd interactions with some debuggers (e.g. gdb on the Mac)
222 - Restrictions on some standard library calls during GC (e.g. don't
223 use printf on stdout to print GC debug messages)
226 #define kMaxThreadId ((1 << 16) - 1)
227 #define kMainThreadId 1
230 static Thread* allocThread(int interpStackSize);
231 static bool prepareThread(Thread* thread);
232 static void setThreadSelf(Thread* thread);
233 static void unlinkThread(Thread* thread);
234 static void freeThread(Thread* thread);
235 static void assignThreadId(Thread* thread);
236 static bool createFakeEntryFrame(Thread* thread);
237 static bool createFakeRunFrame(Thread* thread);
238 static void* interpThreadStart(void* arg);
239 static void* internalThreadStart(void* arg);
240 static void threadExitUncaughtException(Thread* thread, Object* group);
241 static void threadExitCheck(void* arg);
242 static void waitForThreadSuspend(Thread* self, Thread* thread);
243 static int getThreadPriorityFromSystem(void);
246 * The JIT needs to know if any thread is suspended. We do this by
247 * maintaining a global sum of all threads' suspend counts. All suspendCount
248 * updates should go through this after aquiring threadSuspendCountLock.
250 static inline void dvmAddToThreadSuspendCount(int *pSuspendCount, int delta)
252 *pSuspendCount += delta;
253 gDvm.sumThreadSuspendCount += delta;
257 * Initialize thread list and main thread's environment. We need to set
258 * up some basic stuff so that dvmThreadSelf() will work when we start
259 * loading classes (e.g. to check for exceptions).
261 bool dvmThreadStartup(void)
265 /* allocate a TLS slot */
266 if (pthread_key_create(&gDvm.pthreadKeySelf, threadExitCheck) != 0) {
267 LOGE("ERROR: pthread_key_create failed\n");
271 /* test our pthread lib */
272 if (pthread_getspecific(gDvm.pthreadKeySelf) != NULL)
273 LOGW("WARNING: newly-created pthread TLS slot is not NULL\n");
275 /* prep thread-related locks and conditions */
276 dvmInitMutex(&gDvm.threadListLock);
277 pthread_cond_init(&gDvm.threadStartCond, NULL);
278 //dvmInitMutex(&gDvm.vmExitLock);
279 pthread_cond_init(&gDvm.vmExitCond, NULL);
280 dvmInitMutex(&gDvm._threadSuspendLock);
281 dvmInitMutex(&gDvm.threadSuspendCountLock);
282 pthread_cond_init(&gDvm.threadSuspendCountCond, NULL);
283 #ifdef WITH_DEADLOCK_PREDICTION
284 dvmInitMutex(&gDvm.deadlockHistoryLock);
288 * Dedicated monitor for Thread.sleep().
289 * TODO: change this to an Object* so we don't have to expose this
290 * call, and we interact better with JDWP monitor calls. Requires
291 * deferring the object creation to much later (e.g. final "main"
292 * thread prep) or until first use.
294 gDvm.threadSleepMon = dvmCreateMonitor(NULL);
296 gDvm.threadIdMap = dvmAllocBitVector(kMaxThreadId, false);
298 thread = allocThread(gDvm.stackSize);
302 /* switch mode for when we run initializers */
303 thread->status = THREAD_RUNNING;
306 * We need to assign the threadId early so we can lock/notify
307 * object monitors. We'll set the "threadObj" field later.
309 prepareThread(thread);
310 gDvm.threadList = thread;
312 #ifdef COUNT_PRECISE_METHODS
313 gDvm.preciseMethods = dvmPointerSetAlloc(200);
320 * We're a little farther up now, and can load some basic classes.
322 * We're far enough along that we can poke at java.lang.Thread and friends,
323 * but should not assume that static initializers have run (or cause them
324 * to do so). That means no object allocations yet.
326 bool dvmThreadObjStartup(void)
329 * Cache the locations of these classes. It's likely that we're the
330 * first to reference them, so they're being loaded now.
332 gDvm.classJavaLangThread =
333 dvmFindSystemClassNoInit("Ljava/lang/Thread;");
334 gDvm.classJavaLangVMThread =
335 dvmFindSystemClassNoInit("Ljava/lang/VMThread;");
336 gDvm.classJavaLangThreadGroup =
337 dvmFindSystemClassNoInit("Ljava/lang/ThreadGroup;");
338 if (gDvm.classJavaLangThread == NULL ||
339 gDvm.classJavaLangThreadGroup == NULL ||
340 gDvm.classJavaLangThreadGroup == NULL)
342 LOGE("Could not find one or more essential thread classes\n");
347 * Cache field offsets. This makes things a little faster, at the
348 * expense of hard-coding non-public field names into the VM.
350 gDvm.offJavaLangThread_vmThread =
351 dvmFindFieldOffset(gDvm.classJavaLangThread,
352 "vmThread", "Ljava/lang/VMThread;");
353 gDvm.offJavaLangThread_group =
354 dvmFindFieldOffset(gDvm.classJavaLangThread,
355 "group", "Ljava/lang/ThreadGroup;");
356 gDvm.offJavaLangThread_daemon =
357 dvmFindFieldOffset(gDvm.classJavaLangThread, "daemon", "Z");
358 gDvm.offJavaLangThread_name =
359 dvmFindFieldOffset(gDvm.classJavaLangThread,
360 "name", "Ljava/lang/String;");
361 gDvm.offJavaLangThread_priority =
362 dvmFindFieldOffset(gDvm.classJavaLangThread, "priority", "I");
364 if (gDvm.offJavaLangThread_vmThread < 0 ||
365 gDvm.offJavaLangThread_group < 0 ||
366 gDvm.offJavaLangThread_daemon < 0 ||
367 gDvm.offJavaLangThread_name < 0 ||
368 gDvm.offJavaLangThread_priority < 0)
370 LOGE("Unable to find all fields in java.lang.Thread\n");
374 gDvm.offJavaLangVMThread_thread =
375 dvmFindFieldOffset(gDvm.classJavaLangVMThread,
376 "thread", "Ljava/lang/Thread;");
377 gDvm.offJavaLangVMThread_vmData =
378 dvmFindFieldOffset(gDvm.classJavaLangVMThread, "vmData", "I");
379 if (gDvm.offJavaLangVMThread_thread < 0 ||
380 gDvm.offJavaLangVMThread_vmData < 0)
382 LOGE("Unable to find all fields in java.lang.VMThread\n");
387 * Cache the vtable offset for "run()".
389 * We don't want to keep the Method* because then we won't find see
390 * methods defined in subclasses.
393 meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThread, "run", "()V");
395 LOGE("Unable to find run() in java.lang.Thread\n");
398 gDvm.voffJavaLangThread_run = meth->methodIndex;
401 * Cache vtable offsets for ThreadGroup methods.
403 meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThreadGroup,
404 "removeThread", "(Ljava/lang/Thread;)V");
406 LOGE("Unable to find removeThread(Thread) in java.lang.ThreadGroup\n");
409 gDvm.voffJavaLangThreadGroup_removeThread = meth->methodIndex;
415 * All threads should be stopped by now. Clean up some thread globals.
417 void dvmThreadShutdown(void)
419 if (gDvm.threadList != NULL) {
421 * If we walk through the thread list and try to free the
422 * lingering thread structures (which should only be for daemon
423 * threads), the daemon threads may crash if they execute before
424 * the process dies. Let them leak.
426 freeThread(gDvm.threadList);
427 gDvm.threadList = NULL;
430 dvmFreeBitVector(gDvm.threadIdMap);
432 dvmFreeMonitorList();
434 pthread_key_delete(gDvm.pthreadKeySelf);
439 * Grab the suspend count global lock.
441 static inline void lockThreadSuspendCount(void)
444 * Don't try to change to VMWAIT here. When we change back to RUNNING
445 * we have to check for a pending suspend, which results in grabbing
446 * this lock recursively. Doesn't work with "fast" pthread mutexes.
448 * This lock is always held for very brief periods, so as long as
449 * mutex ordering is respected we shouldn't stall.
451 dvmLockMutex(&gDvm.threadSuspendCountLock);
455 * Release the suspend count global lock.
457 static inline void unlockThreadSuspendCount(void)
459 dvmUnlockMutex(&gDvm.threadSuspendCountLock);
463 * Grab the thread list global lock.
465 * This is held while "suspend all" is trying to make everybody stop. If
466 * the shutdown is in progress, and somebody tries to grab the lock, they'll
467 * have to wait for the GC to finish. Therefore it's important that the
468 * thread not be in RUNNING mode.
470 * We don't have to check to see if we should be suspended once we have
471 * the lock. Nobody can suspend all threads without holding the thread list
472 * lock while they do it, so by definition there isn't a GC in progress.
474 * This function deliberately avoids the use of dvmChangeStatus(),
475 * which could grab threadSuspendCountLock. To avoid deadlock, threads
476 * are required to grab the thread list lock before the thread suspend
477 * count lock. (See comment in DvmGlobals.)
479 * TODO: consider checking for suspend after acquiring the lock, and
480 * backing off if set. As stated above, it can't happen during normal
481 * execution, but it *can* happen during shutdown when daemon threads
482 * are being suspended.
484 void dvmLockThreadList(Thread* self)
486 ThreadStatus oldStatus;
488 if (self == NULL) /* try to get it from TLS */
489 self = dvmThreadSelf();
492 oldStatus = self->status;
493 self->status = THREAD_VMWAIT;
495 /* happens during VM shutdown */
496 //LOGW("NULL self in dvmLockThreadList\n");
497 oldStatus = -1; // shut up gcc
500 dvmLockMutex(&gDvm.threadListLock);
503 self->status = oldStatus;
507 * Try to lock the thread list.
509 * Returns "true" if we locked it. This is a "fast" mutex, so if the
510 * current thread holds the lock this will fail.
512 bool dvmTryLockThreadList(void)
514 return (dvmTryLockMutex(&gDvm.threadListLock) == 0);
518 * Release the thread list global lock.
520 void dvmUnlockThreadList(void)
522 dvmUnlockMutex(&gDvm.threadListLock);
526 * Convert SuspendCause to a string.
528 static const char* getSuspendCauseStr(SuspendCause why)
531 case SUSPEND_NOT: return "NOT?";
532 case SUSPEND_FOR_GC: return "gc";
533 case SUSPEND_FOR_DEBUG: return "debug";
534 case SUSPEND_FOR_DEBUG_EVENT: return "debug-event";
535 case SUSPEND_FOR_STACK_DUMP: return "stack-dump";
536 case SUSPEND_FOR_VERIFY: return "verify";
537 case SUSPEND_FOR_HPROF: return "hprof";
538 #if defined(WITH_JIT)
539 case SUSPEND_FOR_TBL_RESIZE: return "table-resize";
540 case SUSPEND_FOR_IC_PATCH: return "inline-cache-patch";
541 case SUSPEND_FOR_CC_RESET: return "reset-code-cache";
542 case SUSPEND_FOR_REFRESH: return "refresh jit status";
544 default: return "UNKNOWN";
549 * Grab the "thread suspend" lock. This is required to prevent the
550 * GC and the debugger from simultaneously suspending all threads.
552 * If we fail to get the lock, somebody else is trying to suspend all
553 * threads -- including us. If we go to sleep on the lock we'll deadlock
554 * the VM. Loop until we get it or somebody puts us to sleep.
556 static void lockThreadSuspend(const char* who, SuspendCause why)
558 const int kSpinSleepTime = 3*1000*1000; /* 3s */
559 u8 startWhen = 0; // init req'd to placate gcc
564 cc = dvmTryLockMutex(&gDvm._threadSuspendLock);
566 Thread* self = dvmThreadSelf();
568 if (!dvmCheckSuspendPending(self)) {
570 * Could be that a resume-all is in progress, and something
571 * grabbed the CPU when the wakeup was broadcast. The thread
572 * performing the resume hasn't had a chance to release the
573 * thread suspend lock. (We release before the broadcast,
574 * so this should be a narrow window.)
576 * Could be we hit the window as a suspend was started,
577 * and the lock has been grabbed but the suspend counts
578 * haven't been incremented yet.
580 * Could be an unusual JNI thread-attach thing.
582 * Could be the debugger telling us to resume at roughly
583 * the same time we're posting an event.
585 * Could be two app threads both want to patch predicted
586 * chaining cells around the same time.
588 LOGI("threadid=%d ODD: want thread-suspend lock (%s:%s),"
589 " it's held, no suspend pending\n",
590 self->threadId, who, getSuspendCauseStr(why));
592 /* we suspended; reset timeout */
596 /* give the lock-holder a chance to do some work */
598 startWhen = dvmGetRelativeTimeUsec();
599 if (!dvmIterativeSleep(sleepIter++, kSpinSleepTime, startWhen)) {
600 LOGE("threadid=%d: couldn't get thread-suspend lock (%s:%s),"
602 self->threadId, who, getSuspendCauseStr(why));
603 /* threads are not suspended, thread dump could crash */
604 dvmDumpAllThreads(false);
613 * Release the "thread suspend" lock.
615 static inline void unlockThreadSuspend(void)
617 dvmUnlockMutex(&gDvm._threadSuspendLock);
622 * Kill any daemon threads that still exist. All of ours should be
623 * stopped, so these should be Thread objects or JNI-attached threads
624 * started by the application. Actively-running threads are likely
625 * to crash the process if they continue to execute while the VM
626 * shuts down, so we really need to kill or suspend them. (If we want
627 * the VM to restart within this process, we need to kill them, but that
628 * leaves open the possibility of orphaned resources.)
630 * Waiting for the thread to suspend may be unwise at this point, but
631 * if one of these is wedged in a critical section then we probably
632 * would've locked up on the last GC attempt.
634 * It's possible for this function to get called after a failed
635 * initialization, so be careful with assumptions about the environment.
637 * This will be called from whatever thread calls DestroyJavaVM, usually
638 * but not necessarily the main thread. It's likely, but not guaranteed,
639 * that the current thread has already been cleaned up.
641 void dvmSlayDaemons(void)
643 Thread* self = dvmThreadSelf(); // may be null
648 dvmLockThreadList(self);
651 threadId = self->threadId;
653 target = gDvm.threadList;
654 while (target != NULL) {
655 if (target == self) {
656 target = target->next;
660 if (!dvmGetFieldBoolean(target->threadObj,
661 gDvm.offJavaLangThread_daemon))
663 /* should never happen; suspend it with the rest */
664 LOGW("threadid=%d: non-daemon id=%d still running at shutdown?!\n",
665 threadId, target->threadId);
668 char* threadName = dvmGetThreadName(target);
669 LOGD("threadid=%d: suspending daemon id=%d name='%s'\n",
670 threadId, target->threadId, threadName);
673 /* mark as suspended */
674 lockThreadSuspendCount();
675 dvmAddToThreadSuspendCount(&target->suspendCount, 1);
676 unlockThreadSuspendCount();
679 target = target->next;
682 //dvmDumpAllThreads(false);
685 * Unlock the thread list, relocking it later if necessary. It's
686 * possible a thread is in VMWAIT after calling dvmLockThreadList,
687 * and that function *doesn't* check for pending suspend after
688 * acquiring the lock. We want to let them finish their business
689 * and see the pending suspend before we continue here.
691 * There's no guarantee of mutex fairness, so this might not work.
692 * (The alternative is to have dvmLockThreadList check for suspend
693 * after acquiring the lock and back off, something we should consider.)
695 dvmUnlockThreadList();
698 bool complained = false;
702 dvmLockThreadList(self);
705 * Sleep for a bit until the threads have suspended. We're trying
706 * to exit, so don't wait for too long.
709 for (i = 0; i < 10; i++) {
710 bool allSuspended = true;
712 target = gDvm.threadList;
713 while (target != NULL) {
714 if (target == self) {
715 target = target->next;
719 if (target->status == THREAD_RUNNING) {
721 LOGD("threadid=%d not ready yet\n", target->threadId);
722 allSuspended = false;
723 /* keep going so we log each running daemon once */
726 target = target->next;
730 LOGD("threadid=%d: all daemons have suspended\n", threadId);
735 LOGD("threadid=%d: waiting briefly for daemon suspension\n",
742 dvmUnlockThreadList();
745 #if 0 /* bad things happen if they come out of JNI or "spuriously" wake up */
747 * Abandon the threads and recover their resources.
749 target = gDvm.threadList;
750 while (target != NULL) {
751 Thread* nextTarget = target->next;
752 unlinkThread(target);
758 //dvmDumpAllThreads(true);
763 * Finish preparing the parts of the Thread struct required to support
766 bool dvmPrepMainForJni(JNIEnv* pEnv)
770 /* main thread is always first in list at this point */
771 self = gDvm.threadList;
772 assert(self->threadId == kMainThreadId);
774 /* create a "fake" JNI frame at the top of the main thread interp stack */
775 if (!createFakeEntryFrame(self))
778 /* fill these in, since they weren't ready at dvmCreateJNIEnv time */
779 dvmSetJniEnvThreadId(pEnv, self);
780 dvmSetThreadJNIEnv(self, (JNIEnv*) pEnv);
787 * Finish preparing the main thread, allocating some objects to represent
788 * it. As part of doing so, we finish initializing Thread and ThreadGroup.
789 * This will execute some interpreted code (e.g. class initializers).
791 bool dvmPrepMainThread(void)
797 StringObject* threadNameStr;
801 LOGV("+++ finishing prep on main VM thread\n");
803 /* main thread is always first in list at this point */
804 thread = gDvm.threadList;
805 assert(thread->threadId == kMainThreadId);
808 * Make sure the classes are initialized. We have to do this before
809 * we create an instance of them.
811 if (!dvmInitClass(gDvm.classJavaLangClass)) {
812 LOGE("'Class' class failed to initialize\n");
815 if (!dvmInitClass(gDvm.classJavaLangThreadGroup) ||
816 !dvmInitClass(gDvm.classJavaLangThread) ||
817 !dvmInitClass(gDvm.classJavaLangVMThread))
819 LOGE("thread classes failed to initialize\n");
823 groupObj = dvmGetMainThreadGroup();
824 if (groupObj == NULL)
828 * Allocate and construct a Thread with the internal-creation
831 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_DEFAULT);
832 if (threadObj == NULL) {
833 LOGE("unable to allocate main thread object\n");
836 dvmReleaseTrackedAlloc(threadObj, NULL);
838 threadNameStr = dvmCreateStringFromCstr("main");
839 if (threadNameStr == NULL)
841 dvmReleaseTrackedAlloc((Object*)threadNameStr, NULL);
843 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
844 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
845 assert(init != NULL);
846 dvmCallMethod(thread, init, threadObj, &unused, groupObj, threadNameStr,
847 THREAD_NORM_PRIORITY, false);
848 if (dvmCheckException(thread)) {
849 LOGE("exception thrown while constructing main thread object\n");
854 * Allocate and construct a VMThread.
856 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
857 if (vmThreadObj == NULL) {
858 LOGE("unable to allocate main vmthread object\n");
861 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
863 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangVMThread, "<init>",
864 "(Ljava/lang/Thread;)V");
865 dvmCallMethod(thread, init, vmThreadObj, &unused, threadObj);
866 if (dvmCheckException(thread)) {
867 LOGE("exception thrown while constructing main vmthread object\n");
871 /* set the VMThread.vmData field to our Thread struct */
872 assert(gDvm.offJavaLangVMThread_vmData != 0);
873 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)thread);
876 * Stuff the VMThread back into the Thread. From this point on, other
877 * Threads will see that this Thread is running (at least, they would,
878 * if there were any).
880 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread,
883 thread->threadObj = threadObj;
886 * Set the context class loader. This invokes a ClassLoader method,
887 * which could conceivably call Thread.currentThread(), so we want the
888 * Thread to be fully configured before we do this.
890 Object* systemLoader = dvmGetSystemClassLoader();
891 if (systemLoader == NULL) {
892 LOGW("WARNING: system class loader is NULL (setting main ctxt)\n");
895 int ctxtClassLoaderOffset = dvmFindFieldOffset(gDvm.classJavaLangThread,
896 "contextClassLoader", "Ljava/lang/ClassLoader;");
897 if (ctxtClassLoaderOffset < 0) {
898 LOGE("Unable to find contextClassLoader field in Thread\n");
901 dvmSetFieldObject(threadObj, ctxtClassLoaderOffset, systemLoader);
902 dvmReleaseTrackedAlloc(systemLoader, NULL);
905 * Finish our thread prep.
908 /* include self in non-daemon threads (mainly for AttachCurrentThread) */
909 gDvm.nonDaemonThreadCount++;
916 * Alloc and initialize a Thread struct.
918 * Does not create any objects, just stuff on the system (malloc) heap.
920 static Thread* allocThread(int interpStackSize)
925 thread = (Thread*) calloc(1, sizeof(Thread));
929 #if defined(WITH_SELF_VERIFICATION)
930 if (dvmSelfVerificationShadowSpaceAlloc(thread) == NULL)
934 assert(interpStackSize >= kMinStackSize && interpStackSize <=kMaxStackSize);
936 thread->status = THREAD_INITIALIZING;
937 thread->suspendCount = 0;
940 * Allocate and initialize the interpreted code stack. We essentially
941 * "lose" the alloc pointer, which points at the bottom of the stack,
942 * but we can get it back later because we know how big the stack is.
944 * The stack must be aligned on a 4-byte boundary.
946 #ifdef MALLOC_INTERP_STACK
947 stackBottom = (u1*) malloc(interpStackSize);
948 if (stackBottom == NULL) {
949 #if defined(WITH_SELF_VERIFICATION)
950 dvmSelfVerificationShadowSpaceFree(thread);
955 memset(stackBottom, 0xc5, interpStackSize); // stop valgrind complaints
957 stackBottom = mmap(NULL, interpStackSize, PROT_READ | PROT_WRITE,
958 MAP_PRIVATE | MAP_ANON, -1, 0);
959 if (stackBottom == MAP_FAILED) {
960 #if defined(WITH_SELF_VERIFICATION)
961 dvmSelfVerificationShadowSpaceFree(thread);
968 assert(((u4)stackBottom & 0x03) == 0); // looks like our malloc ensures this
969 thread->interpStackSize = interpStackSize;
970 thread->interpStackStart = stackBottom + interpStackSize;
971 thread->interpStackEnd = stackBottom + STACK_OVERFLOW_RESERVE;
973 /* give the thread code a chance to set things up */
974 dvmInitInterpStack(thread, interpStackSize);
980 * Get a meaningful thread ID. At present this only has meaning under Linux,
981 * where getpid() and gettid() sometimes agree and sometimes don't depending
982 * on your thread model (try "export LD_ASSUME_KERNEL=2.4.19").
984 pid_t dvmGetSysThreadId(void)
994 * Finish initialization of a Thread struct.
996 * This must be called while executing in the new thread, but before the
997 * thread is added to the thread list.
999 * NOTE: The threadListLock must be held by the caller (needed for
1000 * assignThreadId()).
1002 static bool prepareThread(Thread* thread)
1004 assignThreadId(thread);
1005 thread->handle = pthread_self();
1006 thread->systemTid = dvmGetSysThreadId();
1008 //LOGI("SYSTEM TID IS %d (pid is %d)\n", (int) thread->systemTid,
1011 * If we were called by dvmAttachCurrentThread, the self value is
1012 * already correctly established as "thread".
1014 setThreadSelf(thread);
1016 LOGV("threadid=%d: interp stack at %p\n",
1017 thread->threadId, thread->interpStackStart - thread->interpStackSize);
1020 * Initialize invokeReq.
1022 dvmInitMutex(&thread->invokeReq.lock);
1023 pthread_cond_init(&thread->invokeReq.cv, NULL);
1026 * Initialize our reference tracking tables.
1028 * Most threads won't use jniMonitorRefTable, so we clear out the
1029 * structure but don't call the init function (which allocs storage).
1031 #ifdef USE_INDIRECT_REF
1032 if (!dvmInitIndirectRefTable(&thread->jniLocalRefTable,
1033 kJniLocalRefMin, kJniLocalRefMax, kIndirectKindLocal))
1037 * The JNI local ref table *must* be fixed-size because we keep pointers
1038 * into the table in our stack frames.
1040 if (!dvmInitReferenceTable(&thread->jniLocalRefTable,
1041 kJniLocalRefMax, kJniLocalRefMax))
1044 if (!dvmInitReferenceTable(&thread->internalLocalRefTable,
1045 kInternalRefDefault, kInternalRefMax))
1048 memset(&thread->jniMonitorRefTable, 0, sizeof(thread->jniMonitorRefTable));
1050 pthread_cond_init(&thread->waitCond, NULL);
1051 dvmInitMutex(&thread->waitMutex);
1057 * Remove a thread from the internal list.
1058 * Clear out the links to make it obvious that the thread is
1059 * no longer on the list. Caller must hold gDvm.threadListLock.
1061 static void unlinkThread(Thread* thread)
1063 LOG_THREAD("threadid=%d: removing from list\n", thread->threadId);
1064 if (thread == gDvm.threadList) {
1065 assert(thread->prev == NULL);
1066 gDvm.threadList = thread->next;
1068 assert(thread->prev != NULL);
1069 thread->prev->next = thread->next;
1071 if (thread->next != NULL)
1072 thread->next->prev = thread->prev;
1073 thread->prev = thread->next = NULL;
1077 * Free a Thread struct, and all the stuff allocated within.
1079 static void freeThread(Thread* thread)
1084 /* thread->threadId is zero at this point */
1085 LOGVV("threadid=%d: freeing\n", thread->threadId);
1087 if (thread->interpStackStart != NULL) {
1088 u1* interpStackBottom;
1090 interpStackBottom = thread->interpStackStart;
1091 interpStackBottom -= thread->interpStackSize;
1092 #ifdef MALLOC_INTERP_STACK
1093 free(interpStackBottom);
1095 if (munmap(interpStackBottom, thread->interpStackSize) != 0)
1096 LOGW("munmap(thread stack) failed\n");
1100 #ifdef USE_INDIRECT_REF
1101 dvmClearIndirectRefTable(&thread->jniLocalRefTable);
1103 dvmClearReferenceTable(&thread->jniLocalRefTable);
1105 dvmClearReferenceTable(&thread->internalLocalRefTable);
1106 if (&thread->jniMonitorRefTable.table != NULL)
1107 dvmClearReferenceTable(&thread->jniMonitorRefTable);
1109 #if defined(WITH_SELF_VERIFICATION)
1110 dvmSelfVerificationShadowSpaceFree(thread);
1116 * Like pthread_self(), but on a Thread*.
1118 Thread* dvmThreadSelf(void)
1120 return (Thread*) pthread_getspecific(gDvm.pthreadKeySelf);
1124 * Explore our sense of self. Stuffs the thread pointer into TLS.
1126 static void setThreadSelf(Thread* thread)
1130 cc = pthread_setspecific(gDvm.pthreadKeySelf, thread);
1133 * Sometimes this fails under Bionic with EINVAL during shutdown.
1134 * This can happen if the timing is just right, e.g. a thread
1135 * fails to attach during shutdown, but the "fail" path calls
1136 * here to ensure we clean up after ourselves.
1138 if (thread != NULL) {
1139 LOGE("pthread_setspecific(%p) failed, err=%d\n", thread, cc);
1140 dvmAbort(); /* the world is fundamentally hosed */
1146 * This is associated with the pthreadKeySelf key. It's called by the
1147 * pthread library when a thread is exiting and the "self" pointer in TLS
1148 * is non-NULL, meaning the VM hasn't had a chance to clean up. In normal
1149 * operation this will not be called.
1151 * This is mainly of use to ensure that we don't leak resources if, for
1152 * example, a thread attaches itself to us with AttachCurrentThread and
1153 * then exits without notifying the VM.
1155 * We could do the detach here instead of aborting, but this will lead to
1156 * portability problems. Other implementations do not do this check and
1157 * will simply be unaware that the thread has exited, leading to resource
1158 * leaks (and, if this is a non-daemon thread, an infinite hang when the
1159 * VM tries to shut down).
1161 * Because some implementations may want to use the pthread destructor
1162 * to initiate the detach, and the ordering of destructors is not defined,
1163 * we want to iterate a couple of times to give those a chance to run.
1165 static void threadExitCheck(void* arg)
1167 const int kMaxCount = 2;
1169 Thread* self = (Thread*) arg;
1170 assert(self != NULL);
1172 LOGV("threadid=%d: threadExitCheck(%p) count=%d\n",
1173 self->threadId, arg, self->threadExitCheckCount);
1175 if (self->status == THREAD_ZOMBIE) {
1176 LOGW("threadid=%d: Weird -- shouldn't be in threadExitCheck\n",
1181 if (self->threadExitCheckCount < kMaxCount) {
1183 * Spin a couple of times to let other destructors fire.
1185 LOGD("threadid=%d: thread exiting, not yet detached (count=%d)\n",
1186 self->threadId, self->threadExitCheckCount);
1187 self->threadExitCheckCount++;
1188 int cc = pthread_setspecific(gDvm.pthreadKeySelf, self);
1190 LOGE("threadid=%d: unable to re-add thread to TLS\n",
1195 LOGE("threadid=%d: native thread exited without detaching\n",
1203 * Assign the threadId. This needs to be a small integer so that our
1204 * "thin" locks fit in a small number of bits.
1206 * We reserve zero for use as an invalid ID.
1208 * This must be called with threadListLock held.
1210 static void assignThreadId(Thread* thread)
1213 * Find a small unique integer. threadIdMap is a vector of
1214 * kMaxThreadId bits; dvmAllocBit() returns the index of a
1215 * bit, meaning that it will always be < kMaxThreadId.
1217 int num = dvmAllocBit(gDvm.threadIdMap);
1219 LOGE("Ran out of thread IDs\n");
1220 dvmAbort(); // TODO: make this a non-fatal error result
1223 thread->threadId = num + 1;
1225 assert(thread->threadId != 0);
1226 assert(thread->threadId != DVM_LOCK_INITIAL_THIN_VALUE);
1230 * Give back the thread ID.
1232 static void releaseThreadId(Thread* thread)
1234 assert(thread->threadId > 0);
1235 dvmClearBit(gDvm.threadIdMap, thread->threadId - 1);
1236 thread->threadId = 0;
1241 * Add a stack frame that makes it look like the native code in the main
1242 * thread was originally invoked from interpreted code. This gives us a
1243 * place to hang JNI local references. The VM spec says (v2 5.2) that the
1244 * VM begins by executing "main" in a class, so in a way this brings us
1245 * closer to the spec.
1247 static bool createFakeEntryFrame(Thread* thread)
1249 assert(thread->threadId == kMainThreadId); // main thread only
1251 /* find the method on first use */
1252 if (gDvm.methFakeNativeEntry == NULL) {
1253 ClassObject* nativeStart;
1256 nativeStart = dvmFindSystemClassNoInit(
1257 "Ldalvik/system/NativeStart;");
1258 if (nativeStart == NULL) {
1259 LOGE("Unable to find dalvik.system.NativeStart class\n");
1264 * Because we are creating a frame that represents application code, we
1265 * want to stuff the application class loader into the method's class
1266 * loader field, even though we're using the system class loader to
1267 * load it. This makes life easier over in JNI FindClass (though it
1268 * could bite us in other ways).
1270 * Unfortunately this is occurring too early in the initialization,
1271 * of necessity coming before JNI is initialized, and we're not quite
1272 * ready to set up the application class loader.
1274 * So we save a pointer to the method in gDvm.methFakeNativeEntry
1275 * and check it in FindClass. The method is private so nobody else
1278 //nativeStart->classLoader = dvmGetSystemClassLoader();
1280 mainMeth = dvmFindDirectMethodByDescriptor(nativeStart,
1281 "main", "([Ljava/lang/String;)V");
1282 if (mainMeth == NULL) {
1283 LOGE("Unable to find 'main' in dalvik.system.NativeStart\n");
1287 gDvm.methFakeNativeEntry = mainMeth;
1290 if (!dvmPushJNIFrame(thread, gDvm.methFakeNativeEntry))
1294 * Null out the "String[] args" argument.
1296 assert(gDvm.methFakeNativeEntry->registersSize == 1);
1297 u4* framePtr = (u4*) thread->curFrame;
1305 * Add a stack frame that makes it look like the native thread has been
1306 * executing interpreted code. This gives us a place to hang JNI local
1309 static bool createFakeRunFrame(Thread* thread)
1311 ClassObject* nativeStart;
1315 * TODO: cache this result so we don't have to dig for it every time
1316 * somebody attaches a thread to the VM. Also consider changing this
1317 * to a static method so we don't have a null "this" pointer in the
1318 * "ins" on the stack. (Does it really need to look like a Runnable?)
1320 nativeStart = dvmFindSystemClassNoInit("Ldalvik/system/NativeStart;");
1321 if (nativeStart == NULL) {
1322 LOGE("Unable to find dalvik.system.NativeStart class\n");
1326 runMeth = dvmFindVirtualMethodByDescriptor(nativeStart, "run", "()V");
1327 if (runMeth == NULL) {
1328 LOGE("Unable to find 'run' in dalvik.system.NativeStart\n");
1332 if (!dvmPushJNIFrame(thread, runMeth))
1336 * Provide a NULL 'this' argument. The method we've put at the top of
1337 * the stack looks like a virtual call to run() in a Runnable class.
1338 * (If we declared the method static, it wouldn't take any arguments
1339 * and we wouldn't have to do this.)
1341 assert(runMeth->registersSize == 1);
1342 u4* framePtr = (u4*) thread->curFrame;
1349 * Helper function to set the name of the current thread
1351 static void setThreadName(const char *threadName)
1355 const char *s = threadName;
1357 if (*s == '.') hasDot = 1;
1358 else if (*s == '@') hasAt = 1;
1361 int len = s - threadName;
1362 if (len < 15 || hasAt || !hasDot) {
1365 s = threadName + len - 15;
1367 #if defined(HAVE_ANDROID_PTHREAD_SETNAME_NP)
1368 /* pthread_setname_np fails rather than truncating long strings */
1369 char buf[16]; // MAX_TASK_COMM_LEN=16 is hard-coded into bionic
1370 strncpy(buf, s, sizeof(buf)-1);
1371 buf[sizeof(buf)-1] = '\0';
1372 int err = pthread_setname_np(pthread_self(), buf);
1374 LOGW("Unable to set the name of current thread to '%s': %s\n",
1375 buf, strerror(err));
1377 #elif defined(HAVE_PRCTL)
1378 prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
1380 LOGD("No way to set current thread's name (%s)\n", s);
1385 * Create a thread as a result of java.lang.Thread.start().
1387 * We do have to worry about some concurrency problems, e.g. programs
1388 * that try to call Thread.start() on the same object from multiple threads.
1389 * (This will fail for all but one, but we have to make sure that it succeeds
1392 * Some of the complexity here arises from our desire to mimic the
1393 * Thread vs. VMThread class decomposition we inherited. We've been given
1394 * a Thread, and now we need to create a VMThread and then populate both
1395 * objects. We also need to create one of our internal Thread objects.
1397 * Pass in a stack size of 0 to get the default.
1399 * The "threadObj" reference must be pinned by the caller to prevent the GC
1400 * from moving it around (e.g. added to the tracked allocation list).
1402 bool dvmCreateInterpThread(Object* threadObj, int reqStackSize)
1404 pthread_attr_t threadAttr;
1405 pthread_t threadHandle;
1407 Thread* newThread = NULL;
1408 Object* vmThreadObj = NULL;
1411 assert(threadObj != NULL);
1414 // Allow the sampling profiler thread. We shut it down before forking.
1415 StringObject* nameStr = (StringObject*) dvmGetFieldObject(threadObj,
1416 gDvm.offJavaLangThread_name);
1417 char* threadName = dvmCreateCstrFromString(nameStr);
1418 bool profilerThread = strcmp(threadName, "SamplingProfiler") == 0;
1419 if (!profilerThread) {
1420 dvmThrowExceptionFmt("Ljava/lang/IllegalStateException;",
1421 "No new threads in -Xzygote mode. "
1422 "Found thread named '%s'", threadName);
1430 self = dvmThreadSelf();
1431 if (reqStackSize == 0)
1432 stackSize = gDvm.stackSize;
1433 else if (reqStackSize < kMinStackSize)
1434 stackSize = kMinStackSize;
1435 else if (reqStackSize > kMaxStackSize)
1436 stackSize = kMaxStackSize;
1438 stackSize = reqStackSize;
1440 pthread_attr_init(&threadAttr);
1441 pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1444 * To minimize the time spent in the critical section, we allocate the
1445 * vmThread object here.
1447 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
1448 if (vmThreadObj == NULL)
1451 newThread = allocThread(stackSize);
1452 if (newThread == NULL)
1454 newThread->threadObj = threadObj;
1456 assert(newThread->status == THREAD_INITIALIZING);
1459 * We need to lock out other threads while we test and set the
1460 * "vmThread" field in java.lang.Thread, because we use that to determine
1461 * if this thread has been started before. We use the thread list lock
1462 * because it's handy and we're going to need to grab it again soon
1465 dvmLockThreadList(self);
1467 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
1468 dvmUnlockThreadList();
1469 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
1470 "thread has already been started");
1475 * There are actually three data structures: Thread (object), VMThread
1476 * (object), and Thread (C struct). All of them point to at least one
1479 * As soon as "VMThread.vmData" is assigned, other threads can start
1480 * making calls into us (e.g. setPriority).
1482 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)newThread);
1483 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
1486 * Thread creation might take a while, so release the lock.
1488 dvmUnlockThreadList();
1490 ThreadStatus oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
1491 int cc = pthread_create(&threadHandle, &threadAttr, interpThreadStart,
1493 oldStatus = dvmChangeStatus(self, oldStatus);
1497 * Failure generally indicates that we have exceeded system
1498 * resource limits. VirtualMachineError is probably too severe,
1499 * so use OutOfMemoryError.
1501 LOGE("Thread creation failed (err=%s)\n", strerror(errno));
1503 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, NULL);
1505 dvmThrowException("Ljava/lang/OutOfMemoryError;",
1506 "thread creation failed");
1511 * We need to wait for the thread to start. Otherwise, depending on
1512 * the whims of the OS scheduler, we could return and the code in our
1513 * thread could try to do operations on the new thread before it had
1514 * finished starting.
1516 * The new thread will lock the thread list, change its state to
1517 * THREAD_STARTING, broadcast to gDvm.threadStartCond, and then sleep
1518 * on gDvm.threadStartCond (which uses the thread list lock). This
1519 * thread (the parent) will either see that the thread is already ready
1520 * after we grab the thread list lock, or will be awakened from the
1521 * condition variable on the broadcast.
1523 * We don't want to stall the rest of the VM while the new thread
1524 * starts, which can happen if the GC wakes up at the wrong moment.
1525 * So, we change our own status to VMWAIT, and self-suspend if
1526 * necessary after we finish adding the new thread.
1529 * We have to deal with an odd race with the GC/debugger suspension
1530 * mechanism when creating a new thread. The information about whether
1531 * or not a thread should be suspended is contained entirely within
1532 * the Thread struct; this is usually cleaner to deal with than having
1533 * one or more globally-visible suspension flags. The trouble is that
1534 * we could create the thread while the VM is trying to suspend all
1535 * threads. The suspend-count won't be nonzero for the new thread,
1536 * so dvmChangeStatus(THREAD_RUNNING) won't cause a suspension.
1538 * The easiest way to deal with this is to prevent the new thread from
1539 * running until the parent says it's okay. This results in the
1540 * following (correct) sequence of events for a "badly timed" GC
1541 * (where '-' is us, 'o' is the child, and '+' is some other thread):
1543 * - call pthread_create()
1544 * - lock thread list
1545 * - put self into THREAD_VMWAIT so GC doesn't wait for us
1546 * - sleep on condition var (mutex = thread list lock) until child starts
1547 * + GC triggered by another thread
1548 * + thread list locked; suspend counts updated; thread list unlocked
1549 * + loop waiting for all runnable threads to suspend
1550 * + success, start GC
1551 * o child thread wakes, signals condition var to wake parent
1552 * o child waits for parent ack on condition variable
1553 * - we wake up, locking thread list
1554 * - add child to thread list
1555 * - unlock thread list
1556 * - change our state back to THREAD_RUNNING; GC causes us to suspend
1557 * + GC finishes; all threads in thread list are resumed
1558 * - lock thread list
1559 * - set child to THREAD_VMWAIT, and signal it to start
1560 * - unlock thread list
1562 * o child changes state to THREAD_RUNNING
1564 * The above shows the GC starting up during thread creation, but if
1565 * it starts anywhere after VMThread.create() is called it will
1566 * produce the same series of events.
1568 * Once the child is in the thread list, it will be suspended and
1569 * resumed like any other thread. In the above scenario the resume-all
1570 * code will try to resume the new thread, which was never actually
1571 * suspended, and try to decrement the child's thread suspend count to -1.
1572 * We can catch this in the resume-all code.
1574 * Bouncing back and forth between threads like this adds a small amount
1575 * of scheduler overhead to thread startup.
1577 * One alternative to having the child wait for the parent would be
1578 * to have the child inherit the parents' suspension count. This
1579 * would work for a GC, since we can safely assume that the parent
1580 * thread didn't cause it, but we must only do so if the parent suspension
1581 * was caused by a suspend-all. If the parent was being asked to
1582 * suspend singly by the debugger, the child should not inherit the value.
1584 * We could also have a global "new thread suspend count" that gets
1585 * picked up by new threads before changing state to THREAD_RUNNING.
1586 * This would be protected by the thread list lock and set by a
1589 dvmLockThreadList(self);
1590 assert(self->status == THREAD_RUNNING);
1591 self->status = THREAD_VMWAIT;
1592 while (newThread->status != THREAD_STARTING)
1593 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1595 LOG_THREAD("threadid=%d: adding to list\n", newThread->threadId);
1596 newThread->next = gDvm.threadList->next;
1597 if (newThread->next != NULL)
1598 newThread->next->prev = newThread;
1599 newThread->prev = gDvm.threadList;
1600 gDvm.threadList->next = newThread;
1602 if (!dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon))
1603 gDvm.nonDaemonThreadCount++; // guarded by thread list lock
1605 dvmUnlockThreadList();
1607 /* change status back to RUNNING, self-suspending if necessary */
1608 dvmChangeStatus(self, THREAD_RUNNING);
1611 * Tell the new thread to start.
1613 * We must hold the thread list lock before messing with another thread.
1614 * In the general case we would also need to verify that newThread was
1615 * still in the thread list, but in our case the thread has not started
1616 * executing user code and therefore has not had a chance to exit.
1618 * We move it to VMWAIT, and it then shifts itself to RUNNING, which
1619 * comes with a suspend-pending check.
1621 dvmLockThreadList(self);
1623 assert(newThread->status == THREAD_STARTING);
1624 newThread->status = THREAD_VMWAIT;
1625 pthread_cond_broadcast(&gDvm.threadStartCond);
1627 dvmUnlockThreadList();
1629 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1633 freeThread(newThread);
1634 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1639 * pthread entry function for threads started from interpreted code.
1641 static void* interpThreadStart(void* arg)
1643 Thread* self = (Thread*) arg;
1645 char *threadName = dvmGetThreadName(self);
1646 setThreadName(threadName);
1650 * Finish initializing the Thread struct.
1652 dvmLockThreadList(self);
1653 prepareThread(self);
1655 LOG_THREAD("threadid=%d: created from interp\n", self->threadId);
1658 * Change our status and wake our parent, who will add us to the
1659 * thread list and advance our state to VMWAIT.
1661 self->status = THREAD_STARTING;
1662 pthread_cond_broadcast(&gDvm.threadStartCond);
1665 * Wait until the parent says we can go. Assuming there wasn't a
1666 * suspend pending, this will happen immediately. When it completes,
1667 * we're full-fledged citizens of the VM.
1669 * We have to use THREAD_VMWAIT here rather than THREAD_RUNNING
1670 * because the pthread_cond_wait below needs to reacquire a lock that
1671 * suspend-all is also interested in. If we get unlucky, the parent could
1672 * change us to THREAD_RUNNING, then a GC could start before we get
1673 * signaled, and suspend-all will grab the thread list lock and then
1674 * wait for us to suspend. We'll be in the tail end of pthread_cond_wait
1675 * trying to get the lock.
1677 while (self->status != THREAD_VMWAIT)
1678 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1680 dvmUnlockThreadList();
1683 * Add a JNI context.
1685 self->jniEnv = dvmCreateJNIEnv(self);
1688 * Change our state so the GC will wait for us from now on. If a GC is
1689 * in progress this call will suspend us.
1691 dvmChangeStatus(self, THREAD_RUNNING);
1694 * Notify the debugger & DDM. The debugger notification may cause
1695 * us to suspend ourselves (and others). The thread state may change
1696 * to VMWAIT briefly if network packets are sent.
1698 if (gDvm.debuggerConnected)
1699 dvmDbgPostThreadStart(self);
1702 * Set the system thread priority according to the Thread object's
1703 * priority level. We don't usually need to do this, because both the
1704 * Thread object and system thread priorities inherit from parents. The
1705 * tricky case is when somebody creates a Thread object, calls
1706 * setPriority(), and then starts the thread. We could manage this with
1707 * a "needs priority update" flag to avoid the redundant call.
1709 int priority = dvmGetFieldInt(self->threadObj,
1710 gDvm.offJavaLangThread_priority);
1711 dvmChangeThreadPriority(self, priority);
1714 * Execute the "run" method.
1716 * At this point our stack is empty, so somebody who comes looking for
1717 * stack traces right now won't have much to look at. This is normal.
1719 Method* run = self->threadObj->clazz->vtable[gDvm.voffJavaLangThread_run];
1722 LOGV("threadid=%d: calling run()\n", self->threadId);
1723 assert(strcmp(run->name, "run") == 0);
1724 dvmCallMethod(self, run, self->threadObj, &unused);
1725 LOGV("threadid=%d: exiting\n", self->threadId);
1728 * Remove the thread from various lists, report its death, and free
1731 dvmDetachCurrentThread();
1737 * The current thread is exiting with an uncaught exception. The
1738 * Java programming language allows the application to provide a
1739 * thread-exit-uncaught-exception handler for the VM, for a specific
1740 * Thread, and for all threads in a ThreadGroup.
1742 * Version 1.5 added the per-thread handler. We need to call
1743 * "uncaughtException" in the handler object, which is either the
1744 * ThreadGroup object or the Thread-specific handler.
1746 static void threadExitUncaughtException(Thread* self, Object* group)
1750 Method* uncaughtHandler = NULL;
1751 InstField* threadHandler;
1753 LOGW("threadid=%d: thread exiting with uncaught exception (group=%p)\n",
1754 self->threadId, group);
1755 assert(group != NULL);
1758 * Get a pointer to the exception, then clear out the one in the
1759 * thread. We don't want to have it set when executing interpreted code.
1761 exception = dvmGetException(self);
1762 dvmAddTrackedAlloc(exception, self);
1763 dvmClearException(self);
1766 * Get the Thread's "uncaughtHandler" object. Use it if non-NULL;
1767 * else use "group" (which is an instance of UncaughtExceptionHandler).
1769 threadHandler = dvmFindInstanceField(gDvm.classJavaLangThread,
1770 "uncaughtHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;");
1771 if (threadHandler == NULL) {
1772 LOGW("WARNING: no 'uncaughtHandler' field in java/lang/Thread\n");
1775 handlerObj = dvmGetFieldObject(self->threadObj, threadHandler->byteOffset);
1776 if (handlerObj == NULL)
1780 * Find the "uncaughtHandler" field in this object.
1782 uncaughtHandler = dvmFindVirtualMethodHierByDescriptor(handlerObj->clazz,
1783 "uncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
1785 if (uncaughtHandler != NULL) {
1786 //LOGI("+++ calling %s.uncaughtException\n",
1787 // handlerObj->clazz->descriptor);
1789 dvmCallMethod(self, uncaughtHandler, handlerObj, &unused,
1790 self->threadObj, exception);
1792 /* restore it and dump a stack trace */
1793 LOGW("WARNING: no 'uncaughtException' method in class %s\n",
1794 handlerObj->clazz->descriptor);
1795 dvmSetException(self, exception);
1796 dvmLogExceptionStackTrace();
1800 #if defined(WITH_JIT)
1801 /* Remove this thread's suspendCount from global suspendCount sum */
1802 lockThreadSuspendCount();
1803 dvmAddToThreadSuspendCount(&self->suspendCount, -self->suspendCount);
1804 unlockThreadSuspendCount();
1806 dvmReleaseTrackedAlloc(exception, self);
1811 * Create an internal VM thread, for things like JDWP and finalizers.
1813 * The easiest way to do this is create a new thread and then use the
1814 * JNI AttachCurrentThread implementation.
1816 * This does not return until after the new thread has begun executing.
1818 bool dvmCreateInternalThread(pthread_t* pHandle, const char* name,
1819 InternalThreadStart func, void* funcArg)
1821 InternalStartArgs* pArgs;
1822 Object* systemGroup;
1823 pthread_attr_t threadAttr;
1824 volatile Thread* newThread = NULL;
1825 volatile int createStatus = 0;
1827 systemGroup = dvmGetSystemThreadGroup();
1828 if (systemGroup == NULL)
1831 pArgs = (InternalStartArgs*) malloc(sizeof(*pArgs));
1833 pArgs->funcArg = funcArg;
1834 pArgs->name = strdup(name); // storage will be owned by new thread
1835 pArgs->group = systemGroup;
1836 pArgs->isDaemon = true;
1837 pArgs->pThread = &newThread;
1838 pArgs->pCreateStatus = &createStatus;
1840 pthread_attr_init(&threadAttr);
1841 //pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1843 if (pthread_create(pHandle, &threadAttr, internalThreadStart,
1846 LOGE("internal thread creation failed\n");
1853 * Wait for the child to start. This gives us an opportunity to make
1854 * sure that the thread started correctly, and allows our caller to
1855 * assume that the thread has started running.
1857 * Because we aren't holding a lock across the thread creation, it's
1858 * possible that the child will already have completed its
1859 * initialization. Because the child only adjusts "createStatus" while
1860 * holding the thread list lock, the initial condition on the "while"
1861 * loop will correctly avoid the wait if this occurs.
1863 * It's also possible that we'll have to wait for the thread to finish
1864 * being created, and as part of allocating a Thread object it might
1865 * need to initiate a GC. We switch to VMWAIT while we pause.
1867 Thread* self = dvmThreadSelf();
1868 ThreadStatus oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
1869 dvmLockThreadList(self);
1870 while (createStatus == 0)
1871 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1873 if (newThread == NULL) {
1874 LOGW("internal thread create failed (createStatus=%d)\n", createStatus);
1875 assert(createStatus < 0);
1876 /* don't free pArgs -- if pthread_create succeeded, child owns it */
1877 dvmUnlockThreadList();
1878 dvmChangeStatus(self, oldStatus);
1882 /* thread could be in any state now (except early init states) */
1883 //assert(newThread->status == THREAD_RUNNING);
1885 dvmUnlockThreadList();
1886 dvmChangeStatus(self, oldStatus);
1892 * pthread entry function for internally-created threads.
1894 * We are expected to free "arg" and its contents. If we're a daemon
1895 * thread, and we get cancelled abruptly when the VM shuts down, the
1896 * storage won't be freed. If this becomes a concern we can make a copy
1899 static void* internalThreadStart(void* arg)
1901 InternalStartArgs* pArgs = (InternalStartArgs*) arg;
1902 JavaVMAttachArgs jniArgs;
1904 jniArgs.version = JNI_VERSION_1_2;
1905 jniArgs.name = pArgs->name;
1906 jniArgs.group = pArgs->group;
1908 setThreadName(pArgs->name);
1910 /* use local jniArgs as stack top */
1911 if (dvmAttachCurrentThread(&jniArgs, pArgs->isDaemon)) {
1913 * Tell the parent of our success.
1915 * threadListLock is the mutex for threadStartCond.
1917 dvmLockThreadList(dvmThreadSelf());
1918 *pArgs->pCreateStatus = 1;
1919 *pArgs->pThread = dvmThreadSelf();
1920 pthread_cond_broadcast(&gDvm.threadStartCond);
1921 dvmUnlockThreadList();
1923 LOG_THREAD("threadid=%d: internal '%s'\n",
1924 dvmThreadSelf()->threadId, pArgs->name);
1927 (*pArgs->func)(pArgs->funcArg);
1929 /* detach ourselves */
1930 dvmDetachCurrentThread();
1933 * Tell the parent of our failure. We don't have a Thread struct,
1934 * so we can't be suspended, so we don't need to enter a critical
1937 dvmLockThreadList(dvmThreadSelf());
1938 *pArgs->pCreateStatus = -1;
1939 assert(*pArgs->pThread == NULL);
1940 pthread_cond_broadcast(&gDvm.threadStartCond);
1941 dvmUnlockThreadList();
1943 assert(*pArgs->pThread == NULL);
1952 * Attach the current thread to the VM.
1954 * Used for internally-created threads and JNI's AttachCurrentThread.
1956 bool dvmAttachCurrentThread(const JavaVMAttachArgs* pArgs, bool isDaemon)
1958 Thread* self = NULL;
1959 Object* threadObj = NULL;
1960 Object* vmThreadObj = NULL;
1961 StringObject* threadNameStr = NULL;
1965 /* allocate thread struct, and establish a basic sense of self */
1966 self = allocThread(gDvm.stackSize);
1969 setThreadSelf(self);
1972 * Finish our thread prep. We need to do this before adding ourselves
1973 * to the thread list or invoking any interpreted code. prepareThread()
1974 * requires that we hold the thread list lock.
1976 dvmLockThreadList(self);
1977 ok = prepareThread(self);
1978 dvmUnlockThreadList();
1982 self->jniEnv = dvmCreateJNIEnv(self);
1983 if (self->jniEnv == NULL)
1987 * Create a "fake" JNI frame at the top of the main thread interp stack.
1988 * It isn't really necessary for the internal threads, but it gives
1989 * the debugger something to show. It is essential for the JNI-attached
1992 if (!createFakeRunFrame(self))
1996 * The native side of the thread is ready; add it to the list. Once
1997 * it's on the list the thread is visible to the JDWP code and the GC.
1999 LOG_THREAD("threadid=%d: adding to list (attached)\n", self->threadId);
2001 dvmLockThreadList(self);
2003 self->next = gDvm.threadList->next;
2004 if (self->next != NULL)
2005 self->next->prev = self;
2006 self->prev = gDvm.threadList;
2007 gDvm.threadList->next = self;
2009 gDvm.nonDaemonThreadCount++;
2011 dvmUnlockThreadList();
2014 * Switch state from initializing to running.
2016 * It's possible that a GC began right before we added ourselves
2017 * to the thread list, and is still going. That means our thread
2018 * suspend count won't reflect the fact that we should be suspended.
2019 * To deal with this, we transition to VMWAIT, pulse the heap lock,
2020 * and then advance to RUNNING. That will ensure that we stall until
2023 * Once we're in RUNNING, we're like any other thread in the VM (except
2024 * for the lack of an initialized threadObj). We're then free to
2025 * allocate and initialize objects.
2027 assert(self->status == THREAD_INITIALIZING);
2028 dvmChangeStatus(self, THREAD_VMWAIT);
2029 dvmLockMutex(&gDvm.gcHeapLock);
2030 dvmUnlockMutex(&gDvm.gcHeapLock);
2031 dvmChangeStatus(self, THREAD_RUNNING);
2034 * Create Thread and VMThread objects.
2036 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_DEFAULT);
2037 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
2038 if (threadObj == NULL || vmThreadObj == NULL)
2042 * This makes threadObj visible to the GC. We still have it in the
2043 * tracked allocation table, so it can't move around on us.
2045 self->threadObj = threadObj;
2046 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)self);
2049 * Create a string for the thread name.
2051 if (pArgs->name != NULL) {
2052 threadNameStr = dvmCreateStringFromCstr(pArgs->name);
2053 if (threadNameStr == NULL) {
2054 assert(dvmCheckException(dvmThreadSelf()));
2059 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
2060 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
2062 assert(dvmCheckException(self));
2067 * Now we're ready to run some interpreted code.
2069 * We need to construct the Thread object and set the VMThread field.
2070 * Setting VMThread tells interpreted code that we're alive.
2072 * Call the (group, name, priority, daemon) constructor on the Thread.
2073 * This sets the thread's name and adds it to the specified group, and
2074 * provides values for priority and daemon (which are normally inherited
2075 * from the current thread).
2078 dvmCallMethod(self, init, threadObj, &unused, (Object*)pArgs->group,
2079 threadNameStr, getThreadPriorityFromSystem(), isDaemon);
2080 if (dvmCheckException(self)) {
2081 LOGE("exception thrown while constructing attached thread object\n");
2086 * Set the VMThread field, which tells interpreted code that we're alive.
2088 * The risk of a thread start collision here is very low; somebody
2089 * would have to be deliberately polling the ThreadGroup list and
2090 * trying to start threads against anything it sees, which would
2091 * generally cause problems for all thread creation. However, for
2092 * correctness we test "vmThread" before setting it.
2094 * TODO: this still has a race, it's just smaller. Not sure this is
2095 * worth putting effort into fixing. Need to hold a lock while
2096 * fiddling with the field, or maybe initialize the Thread object in a
2097 * way that ensures another thread can't call start() on it.
2099 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
2100 LOGW("WOW: thread start hijack\n");
2101 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
2102 "thread has already been started");
2103 /* We don't want to free anything associated with the thread
2104 * because someone is obviously interested in it. Just let
2105 * it go and hope it will clean itself up when its finished.
2106 * This case should never happen anyway.
2108 * Since we're letting it live, we need to finish setting it up.
2109 * We just have to let the caller know that the intended operation
2112 * [ This seems strange -- stepping on the vmThread object that's
2113 * already present seems like a bad idea. TODO: figure this out. ]
2119 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
2121 /* we can now safely un-pin these */
2122 dvmReleaseTrackedAlloc(threadObj, self);
2123 dvmReleaseTrackedAlloc(vmThreadObj, self);
2124 dvmReleaseTrackedAlloc((Object*)threadNameStr, self);
2126 LOG_THREAD("threadid=%d: attached from native, name=%s\n",
2127 self->threadId, pArgs->name);
2129 /* tell the debugger & DDM */
2130 if (gDvm.debuggerConnected)
2131 dvmDbgPostThreadStart(self);
2136 dvmLockThreadList(self);
2139 gDvm.nonDaemonThreadCount--;
2140 dvmUnlockThreadList();
2141 /* fall through to "fail" */
2143 dvmReleaseTrackedAlloc(threadObj, self);
2144 dvmReleaseTrackedAlloc(vmThreadObj, self);
2145 dvmReleaseTrackedAlloc((Object*)threadNameStr, self);
2147 if (self->jniEnv != NULL) {
2148 dvmDestroyJNIEnv(self->jniEnv);
2149 self->jniEnv = NULL;
2153 setThreadSelf(NULL);
2158 * Detach the thread from the various data structures, notify other threads
2159 * that are waiting to "join" it, and free up all heap-allocated storage.
2161 * Used for all threads.
2163 * When we get here the interpreted stack should be empty. The JNI 1.6 spec
2164 * requires us to enforce this for the DetachCurrentThread call, probably
2165 * because it also says that DetachCurrentThread causes all monitors
2166 * associated with the thread to be released. (Because the stack is empty,
2167 * we only have to worry about explicit JNI calls to MonitorEnter.)
2170 * We might want to avoid freeing our internal Thread structure until the
2171 * associated Thread/VMThread objects get GCed. Our Thread is impossible to
2172 * get to once the thread shuts down, but there is a small possibility of
2173 * an operation starting in another thread before this thread halts, and
2174 * finishing much later (perhaps the thread got stalled by a weird OS bug).
2175 * We don't want something like Thread.isInterrupted() crawling through
2176 * freed storage. Can do with a Thread finalizer, or by creating a
2177 * dedicated ThreadObject class for java/lang/Thread and moving all of our
2180 void dvmDetachCurrentThread(void)
2182 Thread* self = dvmThreadSelf();
2187 * Make sure we're not detaching a thread that's still running. (This
2188 * could happen with an explicit JNI detach call.)
2190 * A thread created by interpreted code will finish with a depth of
2191 * zero, while a JNI-attached thread will have the synthetic "stack
2192 * starter" native method at the top.
2194 int curDepth = dvmComputeExactFrameDepth(self->curFrame);
2195 if (curDepth != 0) {
2196 bool topIsNative = false;
2198 if (curDepth == 1) {
2199 /* not expecting a lingering break frame; just look at curFrame */
2200 assert(!dvmIsBreakFrame(self->curFrame));
2201 StackSaveArea* ssa = SAVEAREA_FROM_FP(self->curFrame);
2202 if (dvmIsNativeMethod(ssa->method))
2207 LOGE("ERROR: detaching thread with interp frames (count=%d)\n",
2209 dvmDumpThread(self, false);
2214 group = dvmGetFieldObject(self->threadObj, gDvm.offJavaLangThread_group);
2215 LOG_THREAD("threadid=%d: detach (group=%p)\n", self->threadId, group);
2218 * Release any held monitors. Since there are no interpreted stack
2219 * frames, the only thing left are the monitors held by JNI MonitorEnter
2222 dvmReleaseJniMonitors(self);
2225 * Do some thread-exit uncaught exception processing if necessary.
2227 if (dvmCheckException(self))
2228 threadExitUncaughtException(self, group);
2231 * Remove the thread from the thread group.
2233 if (group != NULL) {
2234 Method* removeThread =
2235 group->clazz->vtable[gDvm.voffJavaLangThreadGroup_removeThread];
2237 dvmCallMethod(self, removeThread, group, &unused, self->threadObj);
2241 * Clear the vmThread reference in the Thread object. Interpreted code
2242 * will now see that this Thread is not running. As this may be the
2243 * only reference to the VMThread object that the VM knows about, we
2244 * have to create an internal reference to it first.
2246 vmThread = dvmGetFieldObject(self->threadObj,
2247 gDvm.offJavaLangThread_vmThread);
2248 dvmAddTrackedAlloc(vmThread, self);
2249 dvmSetFieldObject(self->threadObj, gDvm.offJavaLangThread_vmThread, NULL);
2251 /* clear out our struct Thread pointer, since it's going away */
2252 dvmSetFieldObject(vmThread, gDvm.offJavaLangVMThread_vmData, NULL);
2255 * Tell the debugger & DDM. This may cause the current thread or all
2256 * threads to suspend.
2258 * The JDWP spec is somewhat vague about when this happens, other than
2259 * that it's issued by the dying thread, which may still appear in
2260 * an "all threads" listing.
2262 if (gDvm.debuggerConnected)
2263 dvmDbgPostThreadDeath(self);
2266 * Thread.join() is implemented as an Object.wait() on the VMThread
2267 * object. Signal anyone who is waiting.
2269 dvmLockObject(self, vmThread);
2270 dvmObjectNotifyAll(self, vmThread);
2271 dvmUnlockObject(self, vmThread);
2273 dvmReleaseTrackedAlloc(vmThread, self);
2277 * We're done manipulating objects, so it's okay if the GC runs in
2278 * parallel with us from here out. It's important to do this if
2279 * profiling is enabled, since we can wait indefinitely.
2281 android_atomic_release_store(THREAD_VMWAIT, &self->status);
2284 * If we're doing method trace profiling, we don't want threads to exit,
2285 * because if they do we'll end up reusing thread IDs. This complicates
2286 * analysis and makes it impossible to have reasonable output in the
2287 * "threads" section of the "key" file.
2289 * We need to do this after Thread.join() completes, or other threads
2290 * could get wedged. Since self->threadObj is still valid, the Thread
2291 * object will not get GCed even though we're no longer in the ThreadGroup
2292 * list (which is important since the profiling thread needs to get
2293 * the thread's name).
2295 MethodTraceState* traceState = &gDvm.methodTrace;
2297 dvmLockMutex(&traceState->startStopLock);
2298 if (traceState->traceEnabled) {
2299 LOGI("threadid=%d: waiting for method trace to finish\n",
2301 while (traceState->traceEnabled) {
2302 dvmWaitCond(&traceState->threadExitCond,
2303 &traceState->startStopLock);
2306 dvmUnlockMutex(&traceState->startStopLock);
2308 dvmLockThreadList(self);
2311 * Lose the JNI context.
2313 dvmDestroyJNIEnv(self->jniEnv);
2314 self->jniEnv = NULL;
2316 self->status = THREAD_ZOMBIE;
2319 * Remove ourselves from the internal thread list.
2324 * If we're the last one standing, signal anybody waiting in
2325 * DestroyJavaVM that it's okay to exit.
2327 if (!dvmGetFieldBoolean(self->threadObj, gDvm.offJavaLangThread_daemon)) {
2328 gDvm.nonDaemonThreadCount--; // guarded by thread list lock
2330 if (gDvm.nonDaemonThreadCount == 0) {
2333 LOGV("threadid=%d: last non-daemon thread\n", self->threadId);
2334 //dvmDumpAllThreads(false);
2335 // cond var guarded by threadListLock, which we already hold
2336 cc = pthread_cond_signal(&gDvm.vmExitCond);
2341 LOGV("threadid=%d: bye!\n", self->threadId);
2342 releaseThreadId(self);
2343 dvmUnlockThreadList();
2345 setThreadSelf(NULL);
2352 * Suspend a single thread. Do not use to suspend yourself.
2354 * This is used primarily for debugger/DDMS activity. Does not return
2355 * until the thread has suspended or is in a "safe" state (e.g. executing
2356 * native code outside the VM).
2358 * The thread list lock should be held before calling here -- it's not
2359 * entirely safe to hang on to a Thread* from another thread otherwise.
2360 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2362 void dvmSuspendThread(Thread* thread)
2364 assert(thread != NULL);
2365 assert(thread != dvmThreadSelf());
2366 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2368 lockThreadSuspendCount();
2369 dvmAddToThreadSuspendCount(&thread->suspendCount, 1);
2370 thread->dbgSuspendCount++;
2372 LOG_THREAD("threadid=%d: suspend++, now=%d\n",
2373 thread->threadId, thread->suspendCount);
2374 unlockThreadSuspendCount();
2376 waitForThreadSuspend(dvmThreadSelf(), thread);
2380 * Reduce the suspend count of a thread. If it hits zero, tell it to
2383 * Used primarily for debugger/DDMS activity. The thread in question
2384 * might have been suspended singly or as part of a suspend-all operation.
2386 * The thread list lock should be held before calling here -- it's not
2387 * entirely safe to hang on to a Thread* from another thread otherwise.
2388 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2390 void dvmResumeThread(Thread* thread)
2392 assert(thread != NULL);
2393 assert(thread != dvmThreadSelf());
2394 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2396 lockThreadSuspendCount();
2397 if (thread->suspendCount > 0) {
2398 dvmAddToThreadSuspendCount(&thread->suspendCount, -1);
2399 thread->dbgSuspendCount--;
2401 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2405 LOG_THREAD("threadid=%d: suspend--, now=%d\n",
2406 thread->threadId, thread->suspendCount);
2408 if (thread->suspendCount == 0) {
2409 dvmBroadcastCond(&gDvm.threadSuspendCountCond);
2412 unlockThreadSuspendCount();
2416 * Suspend yourself, as a result of debugger activity.
2418 void dvmSuspendSelf(bool jdwpActivity)
2420 Thread* self = dvmThreadSelf();
2422 /* debugger thread must not suspend itself due to debugger activity! */
2423 assert(gDvm.jdwpState != NULL);
2424 if (self->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2430 * Collisions with other suspends aren't really interesting. We want
2431 * to ensure that we're the only one fiddling with the suspend count
2434 lockThreadSuspendCount();
2435 dvmAddToThreadSuspendCount(&self->suspendCount, 1);
2436 self->dbgSuspendCount++;
2439 * Suspend ourselves.
2441 assert(self->suspendCount > 0);
2442 self->status = THREAD_SUSPENDED;
2443 LOG_THREAD("threadid=%d: self-suspending (dbg)\n", self->threadId);
2446 * Tell JDWP that we've completed suspension. The JDWP thread can't
2447 * tell us to resume before we're fully asleep because we hold the
2448 * suspend count lock.
2450 * If we got here via waitForDebugger(), don't do this part.
2453 //LOGI("threadid=%d: clearing wait-for-event (my handle=%08x)\n",
2454 // self->threadId, (int) self->handle);
2455 dvmJdwpClearWaitForEventThread(gDvm.jdwpState);
2458 while (self->suspendCount != 0) {
2459 dvmWaitCond(&gDvm.threadSuspendCountCond,
2460 &gDvm.threadSuspendCountLock);
2461 if (self->suspendCount != 0) {
2463 * The condition was signaled but we're still suspended. This
2464 * can happen if the debugger lets go while a SIGQUIT thread
2465 * dump event is pending (assuming SignalCatcher was resumed for
2466 * just long enough to try to grab the thread-suspend lock).
2468 LOGD("threadid=%d: still suspended after undo (sc=%d dc=%d)\n",
2469 self->threadId, self->suspendCount, self->dbgSuspendCount);
2472 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
2473 self->status = THREAD_RUNNING;
2474 LOG_THREAD("threadid=%d: self-reviving (dbg), status=%d\n",
2475 self->threadId, self->status);
2477 unlockThreadSuspendCount();
2482 # define NUM_FRAMES 20
2483 # include <execinfo.h>
2485 * glibc-only stack dump function. Requires link with "--export-dynamic".
2487 * TODO: move this into libs/cutils and make it work for all platforms.
2489 static void printBackTrace(void)
2491 void* array[NUM_FRAMES];
2496 size = backtrace(array, NUM_FRAMES);
2497 strings = backtrace_symbols(array, size);
2499 LOGW("Obtained %zd stack frames.\n", size);
2501 for (i = 0; i < size; i++)
2502 LOGW("%s\n", strings[i]);
2507 static void printBackTrace(void) {}
2511 * Dump the state of the current thread and that of another thread that
2512 * we think is wedged.
2514 static void dumpWedgedThread(Thread* thread)
2516 dvmDumpThread(dvmThreadSelf(), false);
2519 // dumping a running thread is risky, but could be useful
2520 dvmDumpThread(thread, true);
2522 // stop now and get a core dump
2527 * If the thread is running at below-normal priority, temporarily elevate
2530 * Returns zero if no changes were made. Otherwise, returns bit flags
2531 * indicating what was changed, storing the previous values in the
2532 * provided locations.
2534 int dvmRaiseThreadPriorityIfNeeded(Thread* thread, int* pSavedThreadPrio,
2535 SchedPolicy* pSavedThreadPolicy)
2538 *pSavedThreadPrio = getpriority(PRIO_PROCESS, thread->systemTid);
2540 LOGW("Unable to get priority for threadid=%d sysTid=%d\n",
2541 thread->threadId, thread->systemTid);
2544 if (get_sched_policy(thread->systemTid, pSavedThreadPolicy) != 0) {
2545 LOGW("Unable to get policy for threadid=%d sysTid=%d\n",
2546 thread->threadId, thread->systemTid);
2550 int changeFlags = 0;
2553 * Change the priority if we're in the background group.
2555 if (*pSavedThreadPolicy == SP_BACKGROUND) {
2556 if (set_sched_policy(thread->systemTid, SP_FOREGROUND) != 0) {
2557 LOGW("Couldn't set fg policy on tid %d\n", thread->systemTid);
2559 changeFlags |= kChangedPolicy;
2560 LOGD("Temporarily moving tid %d to fg (was %d)\n",
2561 thread->systemTid, *pSavedThreadPolicy);
2566 * getpriority() returns the "nice" value, so larger numbers indicate
2567 * lower priority, with 0 being normal.
2569 if (*pSavedThreadPrio > 0) {
2570 const int kHigher = 0;
2571 if (setpriority(PRIO_PROCESS, thread->systemTid, kHigher) != 0) {
2572 LOGW("Couldn't raise priority on tid %d to %d\n",
2573 thread->systemTid, kHigher);
2575 changeFlags |= kChangedPriority;
2576 LOGD("Temporarily raised priority on tid %d (%d -> %d)\n",
2577 thread->systemTid, *pSavedThreadPrio, kHigher);
2585 * Reset the priority values for the thread in question.
2587 void dvmResetThreadPriority(Thread* thread, int changeFlags,
2588 int savedThreadPrio, SchedPolicy savedThreadPolicy)
2590 if ((changeFlags & kChangedPolicy) != 0) {
2591 if (set_sched_policy(thread->systemTid, savedThreadPolicy) != 0) {
2592 LOGW("NOTE: couldn't reset tid %d to (%d)\n",
2593 thread->systemTid, savedThreadPolicy);
2595 LOGD("Restored policy of %d to %d\n",
2596 thread->systemTid, savedThreadPolicy);
2600 if ((changeFlags & kChangedPriority) != 0) {
2601 if (setpriority(PRIO_PROCESS, thread->systemTid, savedThreadPrio) != 0)
2603 LOGW("NOTE: couldn't reset priority on thread %d to %d\n",
2604 thread->systemTid, savedThreadPrio);
2606 LOGD("Restored priority on %d to %d\n",
2607 thread->systemTid, savedThreadPrio);
2613 * Wait for another thread to see the pending suspension and stop running.
2614 * It can either suspend itself or go into a non-running state such as
2615 * VMWAIT or NATIVE in which it cannot interact with the GC.
2617 * If we're running at a higher priority, sched_yield() may not do anything,
2618 * so we need to sleep for "long enough" to guarantee that the other
2619 * thread has a chance to finish what it's doing. Sleeping for too short
2620 * a period (e.g. less than the resolution of the sleep clock) might cause
2621 * the scheduler to return immediately, so we want to start with a
2622 * "reasonable" value and expand.
2624 * This does not return until the other thread has stopped running.
2625 * Eventually we time out and the VM aborts.
2627 * This does not try to detect the situation where two threads are
2628 * waiting for each other to suspend. In normal use this is part of a
2629 * suspend-all, which implies that the suspend-all lock is held, or as
2630 * part of a debugger action in which the JDWP thread is always the one
2631 * doing the suspending. (We may need to re-evaluate this now that
2632 * getThreadStackTrace is implemented as suspend-snapshot-resume.)
2634 * TODO: track basic stats about time required to suspend VM.
2636 #define FIRST_SLEEP (250*1000) /* 0.25s */
2637 #define MORE_SLEEP (750*1000) /* 0.75s */
2638 static void waitForThreadSuspend(Thread* self, Thread* thread)
2640 const int kMaxRetries = 10;
2641 int spinSleepTime = FIRST_SLEEP;
2642 bool complained = false;
2643 int priChangeFlags = 0;
2644 int savedThreadPrio = -500;
2645 SchedPolicy savedThreadPolicy = SP_FOREGROUND;
2649 u8 startWhen = 0; // init req'd to placate gcc
2650 u8 firstStartWhen = 0;
2652 while (thread->status == THREAD_RUNNING) {
2653 if (sleepIter == 0) { // get current time on first iteration
2654 startWhen = dvmGetRelativeTimeUsec();
2655 if (firstStartWhen == 0) // first iteration of first attempt
2656 firstStartWhen = startWhen;
2659 * After waiting for a bit, check to see if the target thread is
2660 * running at a reduced priority. If so, bump it up temporarily
2661 * to give it more CPU time.
2663 if (retryCount == 2) {
2664 assert(thread->systemTid != 0);
2665 priChangeFlags = dvmRaiseThreadPriorityIfNeeded(thread,
2666 &savedThreadPrio, &savedThreadPolicy);
2670 #if defined (WITH_JIT)
2672 * If we're still waiting after the first timeout, unchain all
2674 * 1) There are new chains formed since the last unchain
2675 * 2) The top VM frame of the running thread is running JIT'ed code
2677 if (gDvmJit.pJitEntryTable && retryCount > 0 &&
2678 gDvmJit.hasNewChain && thread->inJitCodeCache) {
2679 LOGD("JIT unchain all for threadid=%d", thread->threadId);
2685 * Sleep briefly. The iterative sleep call returns false if we've
2686 * exceeded the total time limit for this round of sleeping.
2688 if (!dvmIterativeSleep(sleepIter++, spinSleepTime, startWhen)) {
2689 if (spinSleepTime != FIRST_SLEEP) {
2690 LOGW("threadid=%d: spin on suspend #%d threadid=%d (pcf=%d)\n",
2691 self->threadId, retryCount,
2692 thread->threadId, priChangeFlags);
2693 if (retryCount > 1) {
2694 /* stack trace logging is slow; skip on first iter */
2695 dumpWedgedThread(thread);
2700 // keep going; could be slow due to valgrind
2702 spinSleepTime = MORE_SLEEP;
2704 if (retryCount++ == kMaxRetries) {
2705 LOGE("Fatal spin-on-suspend, dumping threads\n");
2706 dvmDumpAllThreads(false);
2708 /* log this after -- long traces will scroll off log */
2709 LOGE("threadid=%d: stuck on threadid=%d, giving up\n",
2710 self->threadId, thread->threadId);
2712 /* try to get a debuggerd dump from the spinning thread */
2713 dvmNukeThread(thread);
2721 LOGW("threadid=%d: spin on suspend resolved in %lld msec\n",
2723 (dvmGetRelativeTimeUsec() - firstStartWhen) / 1000);
2724 //dvmDumpThread(thread, false); /* suspended, so dump is safe */
2726 if (priChangeFlags != 0) {
2727 dvmResetThreadPriority(thread, priChangeFlags, savedThreadPrio,
2733 * Suspend all threads except the current one. This is used by the GC,
2734 * the debugger, and by any thread that hits a "suspend all threads"
2735 * debugger event (e.g. breakpoint or exception).
2737 * If thread N hits a "suspend all threads" breakpoint, we don't want it
2738 * to suspend the JDWP thread. For the GC, we do, because the debugger can
2739 * create objects and even execute arbitrary code. The "why" argument
2740 * allows the caller to say why the suspension is taking place.
2742 * This can be called when a global suspend has already happened, due to
2743 * various debugger gymnastics, so keeping an "everybody is suspended" flag
2746 * DO NOT grab any locks before calling here. We grab & release the thread
2747 * lock and suspend lock here (and we're not using recursive threads), and
2748 * we might have to self-suspend if somebody else beats us here.
2750 * We know the current thread is in the thread list, because we attach the
2751 * thread before doing anything that could cause VM suspension (like object
2754 void dvmSuspendAllThreads(SuspendCause why)
2756 Thread* self = dvmThreadSelf();
2762 * Start by grabbing the thread suspend lock. If we can't get it, most
2763 * likely somebody else is in the process of performing a suspend or
2764 * resume, so lockThreadSuspend() will cause us to self-suspend.
2766 * We keep the lock until all other threads are suspended.
2768 lockThreadSuspend("susp-all", why);
2770 LOG_THREAD("threadid=%d: SuspendAll starting\n", self->threadId);
2773 * This is possible if the current thread was in VMWAIT mode when a
2774 * suspend-all happened, and then decided to do its own suspend-all.
2775 * This can happen when a couple of threads have simultaneous events
2776 * of interest to the debugger.
2778 //assert(self->suspendCount == 0);
2781 * Increment everybody's suspend count (except our own).
2783 dvmLockThreadList(self);
2785 lockThreadSuspendCount();
2786 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2790 /* debugger events don't suspend JDWP thread */
2791 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2792 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2795 dvmAddToThreadSuspendCount(&thread->suspendCount, 1);
2796 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2797 thread->dbgSuspendCount++;
2799 unlockThreadSuspendCount();
2802 * Wait for everybody in THREAD_RUNNING state to stop. Other states
2803 * indicate the code is either running natively or sleeping quietly.
2804 * Any attempt to transition back to THREAD_RUNNING will cause a check
2805 * for suspension, so it should be impossible for anything to execute
2806 * interpreted code or modify objects (assuming native code plays nicely).
2808 * It's also okay if the thread transitions to a non-RUNNING state.
2810 * Note we released the threadSuspendCountLock before getting here,
2811 * so if another thread is fiddling with its suspend count (perhaps
2812 * self-suspending for the debugger) it won't block while we're waiting
2815 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2819 /* debugger events don't suspend JDWP thread */
2820 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2821 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2824 /* wait for the other thread to see the pending suspend */
2825 waitForThreadSuspend(self, thread);
2827 LOG_THREAD("threadid=%d: threadid=%d status=%d sc=%d dc=%d\n",
2829 thread->threadId, thread->status, thread->suspendCount,
2830 thread->dbgSuspendCount);
2833 dvmUnlockThreadList();
2834 unlockThreadSuspend();
2836 LOG_THREAD("threadid=%d: SuspendAll complete\n", self->threadId);
2840 * Resume all threads that are currently suspended.
2842 * The "why" must match with the previous suspend.
2844 void dvmResumeAllThreads(SuspendCause why)
2846 Thread* self = dvmThreadSelf();
2850 lockThreadSuspend("res-all", why); /* one suspend/resume at a time */
2851 LOG_THREAD("threadid=%d: ResumeAll starting\n", self->threadId);
2854 * Decrement the suspend counts for all threads. No need for atomic
2855 * writes, since nobody should be moving until we decrement the count.
2856 * We do need to hold the thread list because of JNI attaches.
2858 dvmLockThreadList(self);
2859 lockThreadSuspendCount();
2860 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2864 /* debugger events don't suspend JDWP thread */
2865 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2866 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2871 if (thread->suspendCount > 0) {
2872 dvmAddToThreadSuspendCount(&thread->suspendCount, -1);
2873 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2874 thread->dbgSuspendCount--;
2876 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2880 unlockThreadSuspendCount();
2881 dvmUnlockThreadList();
2884 * In some ways it makes sense to continue to hold the thread-suspend
2885 * lock while we issue the wakeup broadcast. It allows us to complete
2886 * one operation before moving on to the next, which simplifies the
2887 * thread activity debug traces.
2889 * This approach caused us some difficulty under Linux, because the
2890 * condition variable broadcast not only made the threads runnable,
2891 * but actually caused them to execute, and it was a while before
2892 * the thread performing the wakeup had an opportunity to release the
2893 * thread-suspend lock.
2895 * This is a problem because, when a thread tries to acquire that
2896 * lock, it times out after 3 seconds. If at some point the thread
2897 * is told to suspend, the clock resets; but since the VM is still
2898 * theoretically mid-resume, there's no suspend pending. If, for
2899 * example, the GC was waking threads up while the SIGQUIT handler
2900 * was trying to acquire the lock, we would occasionally time out on
2901 * a busy system and SignalCatcher would abort.
2903 * We now perform the unlock before the wakeup broadcast. The next
2904 * suspend can't actually start until the broadcast completes and
2905 * returns, because we're holding the thread-suspend-count lock, but the
2906 * suspending thread is now able to make progress and we avoid the abort.
2908 * (Technically there is a narrow window between when we release
2909 * the thread-suspend lock and grab the thread-suspend-count lock.
2910 * This could cause us to send a broadcast to threads with nonzero
2911 * suspend counts, but this is expected and they'll all just fall
2912 * right back to sleep. It's probably safe to grab the suspend-count
2913 * lock before releasing thread-suspend, since we're still following
2914 * the correct order of acquisition, but it feels weird.)
2917 LOG_THREAD("threadid=%d: ResumeAll waking others\n", self->threadId);
2918 unlockThreadSuspend();
2921 * Broadcast a notification to all suspended threads, some or all of
2922 * which may choose to wake up. No need to wait for them.
2924 lockThreadSuspendCount();
2925 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2927 unlockThreadSuspendCount();
2929 LOG_THREAD("threadid=%d: ResumeAll complete\n", self->threadId);
2933 * Undo any debugger suspensions. This is called when the debugger
2936 void dvmUndoDebuggerSuspensions(void)
2938 Thread* self = dvmThreadSelf();
2942 lockThreadSuspend("undo", SUSPEND_FOR_DEBUG);
2943 LOG_THREAD("threadid=%d: UndoDebuggerSusp starting\n", self->threadId);
2946 * Decrement the suspend counts for all threads. No need for atomic
2947 * writes, since nobody should be moving until we decrement the count.
2948 * We do need to hold the thread list because of JNI attaches.
2950 dvmLockThreadList(self);
2951 lockThreadSuspendCount();
2952 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2956 /* debugger events don't suspend JDWP thread */
2957 if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2958 assert(thread->dbgSuspendCount == 0);
2962 assert(thread->suspendCount >= thread->dbgSuspendCount);
2963 dvmAddToThreadSuspendCount(&thread->suspendCount,
2964 -thread->dbgSuspendCount);
2965 thread->dbgSuspendCount = 0;
2967 unlockThreadSuspendCount();
2968 dvmUnlockThreadList();
2971 * Broadcast a notification to all suspended threads, some or all of
2972 * which may choose to wake up. No need to wait for them.
2974 lockThreadSuspendCount();
2975 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2977 unlockThreadSuspendCount();
2979 unlockThreadSuspend();
2981 LOG_THREAD("threadid=%d: UndoDebuggerSusp complete\n", self->threadId);
2985 * Determine if a thread is suspended.
2987 * As with all operations on foreign threads, the caller should hold
2988 * the thread list lock before calling.
2990 * If the thread is suspending or waking, these fields could be changing
2991 * out from under us (or the thread could change state right after we
2992 * examine it), making this generally unreliable. This is chiefly
2993 * intended for use by the debugger.
2995 bool dvmIsSuspended(const Thread* thread)
2998 * The thread could be:
2999 * (1) Running happily. status is RUNNING, suspendCount is zero.
3001 * (2) Pending suspend. status is RUNNING, suspendCount is nonzero.
3003 * (3) Suspended. suspendCount is nonzero, and status is !RUNNING.
3005 * (4) Waking up. suspendCount is zero, status is SUSPENDED
3006 * Return "false" (since it could change out from under us, unless
3007 * we hold suspendCountLock).
3010 return (thread->suspendCount != 0 && thread->status != THREAD_RUNNING);
3014 * Wait until another thread self-suspends. This is specifically for
3015 * synchronization between the JDWP thread and a thread that has decided
3016 * to suspend itself after sending an event to the debugger.
3018 * Threads that encounter "suspend all" events work as well -- the thread
3019 * in question suspends everybody else and then itself.
3021 * We can't hold a thread lock here or in the caller, because we could
3022 * get here just before the to-be-waited-for-thread issues a "suspend all".
3023 * There's an opportunity for badness if the thread we're waiting for exits
3024 * and gets cleaned up, but since the thread in question is processing a
3025 * debugger event, that's not really a possibility. (To avoid deadlock,
3026 * it's important that we not be in THREAD_RUNNING while we wait.)
3028 void dvmWaitForSuspend(Thread* thread)
3030 Thread* self = dvmThreadSelf();
3032 LOG_THREAD("threadid=%d: waiting for threadid=%d to sleep\n",
3033 self->threadId, thread->threadId);
3035 assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
3036 assert(thread != self);
3037 assert(self->status != THREAD_RUNNING);
3039 waitForThreadSuspend(self, thread);
3041 LOG_THREAD("threadid=%d: threadid=%d is now asleep\n",
3042 self->threadId, thread->threadId);
3046 * Check to see if we need to suspend ourselves. If so, go to sleep on
3047 * a condition variable.
3049 * Returns "true" if we suspended ourselves.
3051 static bool fullSuspendCheck(Thread* self)
3053 assert(self != NULL);
3054 assert(self->suspendCount >= 0);
3057 * Grab gDvm.threadSuspendCountLock. This gives us exclusive write
3058 * access to self->suspendCount.
3060 lockThreadSuspendCount(); /* grab gDvm.threadSuspendCountLock */
3062 bool needSuspend = (self->suspendCount != 0);
3064 LOG_THREAD("threadid=%d: self-suspending\n", self->threadId);
3065 ThreadStatus oldStatus = self->status; /* should be RUNNING */
3066 self->status = THREAD_SUSPENDED;
3068 while (self->suspendCount != 0) {
3070 * Wait for wakeup signal, releasing lock. The act of releasing
3071 * and re-acquiring the lock provides the memory barriers we
3072 * need for correct behavior on SMP.
3074 dvmWaitCond(&gDvm.threadSuspendCountCond,
3075 &gDvm.threadSuspendCountLock);
3077 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
3078 self->status = oldStatus;
3079 LOG_THREAD("threadid=%d: self-reviving, status=%d\n",
3080 self->threadId, self->status);
3083 unlockThreadSuspendCount();
3089 * Check to see if a suspend is pending. If so, suspend the current
3090 * thread, and return "true" after we have been resumed.
3092 bool dvmCheckSuspendPending(Thread* self)
3094 assert(self != NULL);
3095 if (self->suspendCount == 0) {
3098 return fullSuspendCheck(self);
3103 * Update our status.
3105 * The "self" argument, which may be NULL, is accepted as an optimization.
3107 * Returns the old status.
3109 ThreadStatus dvmChangeStatus(Thread* self, ThreadStatus newStatus)
3111 ThreadStatus oldStatus;
3114 self = dvmThreadSelf();
3116 LOGVV("threadid=%d: (status %d -> %d)\n",
3117 self->threadId, self->status, newStatus);
3119 oldStatus = self->status;
3120 if (oldStatus == newStatus)
3123 if (newStatus == THREAD_RUNNING) {
3125 * Change our status to THREAD_RUNNING. The transition requires
3126 * that we check for pending suspension, because the VM considers
3127 * us to be "asleep" in all other states, and another thread could
3128 * be performing a GC now.
3130 * The order of operations is very significant here. One way to
3133 * GCing thread Our thread (in NATIVE)
3134 * ------------ ----------------------
3135 * check suspend count (== 0)
3136 * dvmSuspendAllThreads()
3137 * grab suspend-count lock
3138 * increment all suspend counts
3139 * release suspend-count lock
3140 * check thread state (== NATIVE)
3141 * all are suspended, begin GC
3142 * set state to RUNNING
3143 * (continue executing)
3145 * We can correct this by grabbing the suspend-count lock and
3146 * performing both of our operations (check suspend count, set
3147 * state) while holding it, now we need to grab a mutex on every
3148 * transition to RUNNING.
3150 * What we do instead is change the order of operations so that
3151 * the transition to RUNNING happens first. If we then detect
3152 * that the suspend count is nonzero, we switch to SUSPENDED.
3154 * Appropriate compiler and memory barriers are required to ensure
3155 * that the operations are observed in the expected order.
3157 * This does create a small window of opportunity where a GC in
3158 * progress could observe what appears to be a running thread (if
3159 * it happens to look between when we set to RUNNING and when we
3160 * switch to SUSPENDED). At worst this only affects assertions
3161 * and thread logging. (We could work around it with some sort
3162 * of intermediate "pre-running" state that is generally treated
3163 * as equivalent to running, but that doesn't seem worthwhile.)
3165 * We can also solve this by combining the "status" and "suspend
3166 * count" fields into a single 32-bit value. This trades the
3167 * store/load barrier on transition to RUNNING for an atomic RMW
3168 * op on all transitions and all suspend count updates (also, all
3169 * accesses to status or the thread count require bit-fiddling).
3170 * It also eliminates the brief transition through RUNNING when
3171 * the thread is supposed to be suspended. This is possibly faster
3172 * on SMP and slightly more correct, but less convenient.
3174 android_atomic_acquire_store(newStatus, &self->status);
3175 if (self->suspendCount != 0) {
3176 fullSuspendCheck(self);
3180 * Not changing to THREAD_RUNNING. No additional work required.
3182 * We use a releasing store to ensure that, if we were RUNNING,
3183 * any updates we previously made to objects on the managed heap
3184 * will be observed before the state change.
3186 assert(newStatus != THREAD_SUSPENDED);
3187 android_atomic_release_store(newStatus, &self->status);
3194 * Get a statically defined thread group from a field in the ThreadGroup
3195 * Class object. Expected arguments are "mMain" and "mSystem".
3197 static Object* getStaticThreadGroup(const char* fieldName)
3199 StaticField* groupField;
3202 groupField = dvmFindStaticField(gDvm.classJavaLangThreadGroup,
3203 fieldName, "Ljava/lang/ThreadGroup;");
3204 if (groupField == NULL) {
3205 LOGE("java.lang.ThreadGroup does not have an '%s' field\n", fieldName);
3206 dvmThrowException("Ljava/lang/IncompatibleClassChangeError;", NULL);
3209 groupObj = dvmGetStaticFieldObject(groupField);
3210 if (groupObj == NULL) {
3211 LOGE("java.lang.ThreadGroup.%s not initialized\n", fieldName);
3212 dvmThrowException("Ljava/lang/InternalError;", NULL);
3218 Object* dvmGetSystemThreadGroup(void)
3220 return getStaticThreadGroup("mSystem");
3222 Object* dvmGetMainThreadGroup(void)
3224 return getStaticThreadGroup("mMain");
3228 * Given a VMThread object, return the associated Thread*.
3230 * NOTE: if the thread detaches, the struct Thread will disappear, and
3231 * we will be touching invalid data. For safety, lock the thread list
3232 * before calling this.
3234 Thread* dvmGetThreadFromThreadObject(Object* vmThreadObj)
3238 vmData = dvmGetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData);
3241 Thread* thread = gDvm.threadList;
3242 while (thread != NULL) {
3243 if ((Thread*)vmData == thread)
3246 thread = thread->next;
3249 if (thread == NULL) {
3250 LOGW("WARNING: vmThreadObj=%p has thread=%p, not in thread list\n",
3251 vmThreadObj, (Thread*)vmData);
3256 return (Thread*) vmData;
3260 * Given a pthread handle, return the associated Thread*.
3261 * Caller must hold the thread list lock.
3263 * Returns NULL if the thread was not found.
3265 Thread* dvmGetThreadByHandle(pthread_t handle)
3268 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
3269 if (thread->handle == handle)
3276 * Given a threadId, return the associated Thread*.
3277 * Caller must hold the thread list lock.
3279 * Returns NULL if the thread was not found.
3281 Thread* dvmGetThreadByThreadId(u4 threadId)
3284 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
3285 if (thread->threadId == threadId)
3293 * Conversion map for "nice" values.
3295 * We use Android thread priority constants to be consistent with the rest
3296 * of the system. In some cases adjacent entries may overlap.
3298 static const int kNiceValues[10] = {
3299 ANDROID_PRIORITY_LOWEST, /* 1 (MIN_PRIORITY) */
3300 ANDROID_PRIORITY_BACKGROUND + 6,
3301 ANDROID_PRIORITY_BACKGROUND + 3,
3302 ANDROID_PRIORITY_BACKGROUND,
3303 ANDROID_PRIORITY_NORMAL, /* 5 (NORM_PRIORITY) */
3304 ANDROID_PRIORITY_NORMAL - 2,
3305 ANDROID_PRIORITY_NORMAL - 4,
3306 ANDROID_PRIORITY_URGENT_DISPLAY + 3,
3307 ANDROID_PRIORITY_URGENT_DISPLAY + 2,
3308 ANDROID_PRIORITY_URGENT_DISPLAY /* 10 (MAX_PRIORITY) */
3312 * Change the priority of a system thread to match that of the Thread object.
3314 * We map a priority value from 1-10 to Linux "nice" values, where lower
3315 * numbers indicate higher priority.
3317 void dvmChangeThreadPriority(Thread* thread, int newPriority)
3319 pid_t pid = thread->systemTid;
3322 if (newPriority < 1 || newPriority > 10) {
3323 LOGW("bad priority %d\n", newPriority);
3326 newNice = kNiceValues[newPriority-1];
3328 if (newNice >= ANDROID_PRIORITY_BACKGROUND) {
3329 set_sched_policy(dvmGetSysThreadId(), SP_BACKGROUND);
3330 } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
3331 set_sched_policy(dvmGetSysThreadId(), SP_FOREGROUND);
3334 if (setpriority(PRIO_PROCESS, pid, newNice) != 0) {
3335 char* str = dvmGetThreadName(thread);
3336 LOGI("setPriority(%d) '%s' to prio=%d(n=%d) failed: %s\n",
3337 pid, str, newPriority, newNice, strerror(errno));
3340 LOGV("setPriority(%d) to prio=%d(n=%d)\n",
3341 pid, newPriority, newNice);
3346 * Get the thread priority for the current thread by querying the system.
3347 * This is useful when attaching a thread through JNI.
3349 * Returns a value from 1 to 10 (compatible with java.lang.Thread values).
3351 static int getThreadPriorityFromSystem(void)
3353 int i, sysprio, jprio;
3356 sysprio = getpriority(PRIO_PROCESS, 0);
3357 if (sysprio == -1 && errno != 0) {
3358 LOGW("getpriority() failed: %s\n", strerror(errno));
3359 return THREAD_NORM_PRIORITY;
3362 jprio = THREAD_MIN_PRIORITY;
3363 for (i = 0; i < NELEM(kNiceValues); i++) {
3364 if (sysprio >= kNiceValues[i])
3368 if (jprio > THREAD_MAX_PRIORITY)
3369 jprio = THREAD_MAX_PRIORITY;
3376 * Return true if the thread is on gDvm.threadList.
3377 * Caller should not hold gDvm.threadListLock.
3379 bool dvmIsOnThreadList(const Thread* thread)
3383 dvmLockThreadList(NULL);
3384 if (thread == gDvm.threadList) {
3387 ret = thread->prev != NULL || thread->next != NULL;
3389 dvmUnlockThreadList();
3395 * Dump a thread to the log file -- just calls dvmDumpThreadEx() with an
3398 void dvmDumpThread(Thread* thread, bool isRunning)
3400 DebugOutputTarget target;
3402 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
3403 dvmDumpThreadEx(&target, thread, isRunning);
3407 * Try to get the scheduler group.
3409 * The data from /proc/<pid>/cgroup looks (something) like:
3410 * 2:cpu:/bg_non_interactive
3413 * We return the part on the "cpu" line after the '/', which will be an
3414 * empty string for the default cgroup. If the string is longer than
3415 * "bufLen", the string will be truncated.
3417 * On error, -1 is returned, and an error description will be stored in
3420 static int getSchedulerGroup(int tid, char* buf, size_t bufLen)
3422 #ifdef HAVE_ANDROID_OS
3427 snprintf(pathBuf, sizeof(pathBuf), "/proc/%d/cgroup", tid);
3428 if ((fp = fopen(pathBuf, "r")) == NULL) {
3429 snprintf(buf, bufLen, "[fopen-error:%d]", errno);
3433 while (fgets(lineBuf, sizeof(lineBuf) -1, fp) != NULL) {
3438 /* Junk the first field */
3439 subsys = strchr(lineBuf, ':');
3440 if (subsys == NULL) {
3444 if (strncmp(subsys, ":cpu:", 5) != 0) {
3445 /* Not the subsys we're looking for */
3449 grp = strchr(subsys, '/');
3453 grp++; /* Drop the leading '/' */
3456 grp[len-1] = '\0'; /* Drop the trailing '\n' */
3458 if (bufLen <= len) {
3461 strncpy(buf, grp, len);
3467 snprintf(buf, bufLen, "[no-cpu-subsys]");
3472 LOGE("Bad cgroup data {%s}", lineBuf);
3473 snprintf(buf, bufLen, "[data-parse-failed]");
3478 snprintf(buf, bufLen, "[n/a]");
3484 * Convert ThreadStatus to a string.
3486 const char* dvmGetThreadStatusStr(ThreadStatus status)
3489 case THREAD_ZOMBIE: return "ZOMBIE";
3490 case THREAD_RUNNING: return "RUNNABLE";
3491 case THREAD_TIMED_WAIT: return "TIMED_WAIT";
3492 case THREAD_MONITOR: return "MONITOR";
3493 case THREAD_WAIT: return "WAIT";
3494 case THREAD_INITIALIZING: return "INITIALIZING";
3495 case THREAD_STARTING: return "STARTING";
3496 case THREAD_NATIVE: return "NATIVE";
3497 case THREAD_VMWAIT: return "VMWAIT";
3498 case THREAD_SUSPENDED: return "SUSPENDED";
3499 default: return "UNKNOWN";
3504 * Print information about the specified thread.
3506 * Works best when the thread in question is "self" or has been suspended.
3507 * When dumping a separate thread that's still running, set "isRunning" to
3508 * use a more cautious thread dump function.
3510 void dvmDumpThreadEx(const DebugOutputTarget* target, Thread* thread,
3515 StringObject* nameStr;
3516 char* threadName = NULL;
3517 char* groupName = NULL;
3518 char schedulerGroupBuf[32];
3520 int priority; // java.lang.Thread priority
3521 int policy; // pthread policy
3522 struct sched_param sp; // pthread scheduling parameters
3523 char schedstatBuf[64]; // contents of /proc/[pid]/task/[tid]/schedstat
3526 * Get the java.lang.Thread object. This function gets called from
3527 * some weird debug contexts, so it's possible that there's a GC in
3528 * progress on some other thread. To decrease the chances of the
3529 * thread object being moved out from under us, we add the reference
3530 * to the tracked allocation list, which pins it in place.
3532 * If threadObj is NULL, the thread is still in the process of being
3533 * attached to the VM, and there's really nothing interesting to
3536 threadObj = thread->threadObj;
3537 if (threadObj == NULL) {
3538 LOGI("Can't dump thread %d: threadObj not set\n", thread->threadId);
3541 dvmAddTrackedAlloc(threadObj, NULL);
3543 nameStr = (StringObject*) dvmGetFieldObject(threadObj,
3544 gDvm.offJavaLangThread_name);
3545 threadName = dvmCreateCstrFromString(nameStr);
3547 priority = dvmGetFieldInt(threadObj, gDvm.offJavaLangThread_priority);
3548 isDaemon = dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon);
3550 if (pthread_getschedparam(pthread_self(), &policy, &sp) != 0) {
3551 LOGW("Warning: pthread_getschedparam failed\n");
3553 sp.sched_priority = -1;
3555 if (getSchedulerGroup(thread->systemTid, schedulerGroupBuf,
3556 sizeof(schedulerGroupBuf)) == 0 &&
3557 schedulerGroupBuf[0] == '\0') {
3558 strcpy(schedulerGroupBuf, "default");
3561 /* a null value for group is not expected, but deal with it anyway */
3562 groupObj = (Object*) dvmGetFieldObject(threadObj,
3563 gDvm.offJavaLangThread_group);
3564 if (groupObj != NULL) {
3565 int offset = dvmFindFieldOffset(gDvm.classJavaLangThreadGroup,
3566 "name", "Ljava/lang/String;");
3568 LOGW("Unable to find 'name' field in ThreadGroup\n");
3570 nameStr = (StringObject*) dvmGetFieldObject(groupObj, offset);
3571 groupName = dvmCreateCstrFromString(nameStr);
3574 if (groupName == NULL)
3575 groupName = strdup("(null; initializing?)");
3577 dvmPrintDebugMessage(target,
3578 "\"%s\"%s prio=%d tid=%d %s%s\n",
3579 threadName, isDaemon ? " daemon" : "",
3580 priority, thread->threadId, dvmGetThreadStatusStr(thread->status),
3581 #if defined(WITH_JIT)
3582 thread->inJitCodeCache ? " JIT" : ""
3587 dvmPrintDebugMessage(target,
3588 " | group=\"%s\" sCount=%d dsCount=%d obj=%p self=%p\n",
3589 groupName, thread->suspendCount, thread->dbgSuspendCount,
3590 thread->threadObj, thread);
3591 dvmPrintDebugMessage(target,
3592 " | sysTid=%d nice=%d sched=%d/%d cgrp=%s handle=%d\n",
3593 thread->systemTid, getpriority(PRIO_PROCESS, thread->systemTid),
3594 policy, sp.sched_priority, schedulerGroupBuf, (int)thread->handle);
3596 /* get some bits from /proc/self/stat */
3597 ProcStatData procStatData;
3598 if (!dvmGetThreadStats(&procStatData, thread->systemTid)) {
3599 /* failed, use zeroed values */
3600 memset(&procStatData, 0, sizeof(procStatData));
3603 /* grab the scheduler stats for this thread */
3604 snprintf(schedstatBuf, sizeof(schedstatBuf), "/proc/self/task/%d/schedstat",
3606 int schedstatFd = open(schedstatBuf, O_RDONLY);
3607 strcpy(schedstatBuf, "0 0 0"); /* show this if open/read fails */
3608 if (schedstatFd >= 0) {
3610 bytes = read(schedstatFd, schedstatBuf, sizeof(schedstatBuf) - 1);
3613 schedstatBuf[bytes-1] = '\0'; /* remove trailing newline */
3617 /* show what we got */
3618 dvmPrintDebugMessage(target,
3619 " | schedstat=( %s ) utm=%lu stm=%lu core=%d\n",
3620 schedstatBuf, procStatData.utime, procStatData.stime,
3621 procStatData.processor);
3623 #ifdef WITH_MONITOR_TRACKING
3625 LockedObjectData* lod = thread->pLockedObjects;
3627 dvmPrintDebugMessage(target, " | monitors held:\n");
3629 dvmPrintDebugMessage(target, " | monitors held: <none>\n");
3630 while (lod != NULL) {
3631 Object* obj = lod->obj;
3632 if (obj->clazz == gDvm.classJavaLangClass) {
3633 ClassObject* clazz = (ClassObject*) obj;
3634 dvmPrintDebugMessage(target, " > %p[%d] (%s object for class %s)\n",
3635 obj, lod->recursionCount, obj->clazz->descriptor,
3638 dvmPrintDebugMessage(target, " > %p[%d] (%s)\n",
3639 obj, lod->recursionCount, obj->clazz->descriptor);
3647 dvmDumpRunningThreadStack(target, thread);
3649 dvmDumpThreadStack(target, thread);
3651 dvmReleaseTrackedAlloc(threadObj, NULL);
3657 * Get the name of a thread.
3659 * For correctness, the caller should hold the thread list lock to ensure
3660 * that the thread doesn't go away mid-call.
3662 * Returns a newly-allocated string, or NULL if the Thread doesn't have a name.
3664 char* dvmGetThreadName(Thread* thread)
3666 StringObject* nameObj;
3668 if (thread->threadObj == NULL) {
3669 LOGW("threadObj is NULL, name not available\n");
3670 return strdup("-unknown-");
3673 nameObj = (StringObject*)
3674 dvmGetFieldObject(thread->threadObj, gDvm.offJavaLangThread_name);
3675 return dvmCreateCstrFromString(nameObj);
3679 * Dump all threads to the log file -- just calls dvmDumpAllThreadsEx() with
3682 void dvmDumpAllThreads(bool grabLock)
3684 DebugOutputTarget target;
3686 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
3687 dvmDumpAllThreadsEx(&target, grabLock);
3691 * Print information about all known threads. Assumes they have been
3692 * suspended (or are in a non-interpreting state, e.g. WAIT or NATIVE).
3694 * If "grabLock" is true, we grab the thread lock list. This is important
3695 * to do unless the caller already holds the lock.
3697 void dvmDumpAllThreadsEx(const DebugOutputTarget* target, bool grabLock)
3701 dvmPrintDebugMessage(target, "DALVIK THREADS:\n");
3703 #ifdef HAVE_ANDROID_OS
3704 dvmPrintDebugMessage(target,
3705 "(mutexes: tll=%x tsl=%x tscl=%x ghl=%x hwl=%x hwll=%x)\n",
3706 gDvm.threadListLock.value,
3707 gDvm._threadSuspendLock.value,
3708 gDvm.threadSuspendCountLock.value,
3709 gDvm.gcHeapLock.value,
3710 gDvm.heapWorkerLock.value,
3711 gDvm.heapWorkerListLock.value);
3715 dvmLockThreadList(dvmThreadSelf());
3717 thread = gDvm.threadList;
3718 while (thread != NULL) {
3719 dvmDumpThreadEx(target, thread, false);
3722 assert(thread->next == NULL || thread->next->prev == thread);
3724 thread = thread->next;
3728 dvmUnlockThreadList();
3732 * Nuke the target thread from orbit.
3734 * The idea is to send a "crash" signal to the target thread so that
3735 * debuggerd will take notice and dump an appropriate stack trace.
3736 * Because of the way debuggerd works, we have to throw the same signal
3739 * This does not necessarily cause the entire process to stop, but once a
3740 * thread has been nuked the rest of the system is likely to be unstable.
3741 * This returns so that some limited set of additional operations may be
3742 * performed, but it's advisable (and expected) to call dvmAbort soon.
3743 * (This is NOT a way to simply cancel a thread.)
3745 void dvmNukeThread(Thread* thread)
3749 /* suppress the heapworker watchdog to assist anyone using a debugger */
3750 gDvm.nativeDebuggerActive = true;
3753 * Send the signals, separated by a brief interval to allow debuggerd
3754 * to work its magic. An uncommon signal like SIGFPE or SIGSTKFLT
3755 * can be used instead of SIGSEGV to avoid making it look like the
3756 * code actually crashed at the current point of execution.
3758 * (Observed behavior: with SIGFPE, debuggerd will dump the target
3759 * thread and then the thread that calls dvmAbort. With SIGSEGV,
3760 * you don't get the second stack trace; possibly something in the
3761 * kernel decides that a signal has already been sent and it's time
3762 * to just kill the process. The position in the current thread is
3763 * generally known, so the second dump is not useful.)
3765 * The target thread can continue to execute between the two signals.
3766 * (The first just causes debuggerd to attach to it.)
3768 LOGD("threadid=%d: sending two SIGSTKFLTs to threadid=%d (tid=%d) to"
3769 " cause debuggerd dump\n",
3770 dvmThreadSelf()->threadId, thread->threadId, thread->systemTid);
3771 killResult = pthread_kill(thread->handle, SIGSTKFLT);
3772 if (killResult != 0) {
3773 LOGD("NOTE: pthread_kill #1 failed: %s\n", strerror(killResult));
3775 usleep(2 * 1000 * 1000); // TODO: timed-wait until debuggerd attaches
3776 killResult = pthread_kill(thread->handle, SIGSTKFLT);
3777 if (killResult != 0) {
3778 LOGD("NOTE: pthread_kill #2 failed: %s\n", strerror(killResult));
3780 LOGD("Sent, pausing to let debuggerd run\n");
3781 usleep(8 * 1000 * 1000); // TODO: timed-wait until debuggerd finishes
3783 /* ignore SIGSEGV so the eventual dmvAbort() doesn't notify debuggerd */
3784 signal(SIGSEGV, SIG_IGN);
3785 LOGD("Continuing\n");
3788 #ifdef WITH_MONITOR_TRACKING
3790 * Count up the #of locked objects in the current thread.
3792 static int getThreadObjectCount(const Thread* self)
3794 LockedObjectData* lod;
3797 lod = self->pLockedObjects;
3798 while (lod != NULL) {
3806 * Add the object to the thread's locked object list if it doesn't already
3807 * exist. The most recently added object is the most likely to be released
3808 * next, so we insert at the head of the list.
3810 * If it already exists, we increase the recursive lock count.
3812 * The object's lock may be thin or fat.
3814 void dvmAddToMonitorList(Thread* self, Object* obj, bool withTrace)
3816 LockedObjectData* newLod;
3817 LockedObjectData* lod;
3821 lod = self->pLockedObjects;
3822 while (lod != NULL) {
3823 if (lod->obj == obj) {
3824 lod->recursionCount++;
3825 LOGV("+++ +recursive lock %p -> %d\n", obj, lod->recursionCount);
3831 newLod = (LockedObjectData*) calloc(1, sizeof(LockedObjectData));
3832 if (newLod == NULL) {
3833 LOGE("malloc failed on %d bytes\n", sizeof(LockedObjectData));
3837 newLod->recursionCount = 0;
3840 trace = dvmFillInStackTraceRaw(self, &depth);
3841 newLod->rawStackTrace = trace;
3842 newLod->stackDepth = depth;
3845 newLod->next = self->pLockedObjects;
3846 self->pLockedObjects = newLod;
3848 LOGV("+++ threadid=%d: added %p, now %d\n",
3849 self->threadId, newLod, getThreadObjectCount(self));
3853 * Remove the object from the thread's locked object list. If the entry
3854 * has a nonzero recursion count, we just decrement the count instead.
3856 void dvmRemoveFromMonitorList(Thread* self, Object* obj)
3858 LockedObjectData* lod;
3859 LockedObjectData* prevLod;
3861 lod = self->pLockedObjects;
3863 while (lod != NULL) {
3864 if (lod->obj == obj) {
3865 if (lod->recursionCount > 0) {
3866 lod->recursionCount--;
3867 LOGV("+++ -recursive lock %p -> %d\n",
3868 obj, lod->recursionCount);
3879 LOGW("BUG: object %p not found in thread's lock list\n", obj);
3882 if (prevLod == NULL) {
3883 /* first item in list */
3884 assert(self->pLockedObjects == lod);
3885 self->pLockedObjects = lod->next;
3887 /* middle/end of list */
3888 prevLod->next = lod->next;
3891 LOGV("+++ threadid=%d: removed %p, now %d\n",
3892 self->threadId, lod, getThreadObjectCount(self));
3893 free(lod->rawStackTrace);
3898 * If the specified object is already in the thread's locked object list,
3899 * return the LockedObjectData struct. Otherwise return NULL.
3901 LockedObjectData* dvmFindInMonitorList(const Thread* self, const Object* obj)
3903 LockedObjectData* lod;
3905 lod = self->pLockedObjects;
3906 while (lod != NULL) {
3907 if (lod->obj == obj)
3913 #endif /*WITH_MONITOR_TRACKING*/