blob: e46715d81ea8c043b61128b31f5dbb50f5eb708e [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
The Android Open Source Project99409882009-03-18 22:20:24 -070016
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080017/*
18 * Thread support.
19 */
20#include "Dalvik.h"
Bob Lee2fe146a2009-09-10 00:36:29 +020021#include "native/SystemThread.h"
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080022
23#include "utils/threads.h" // need Android thread priorities
24
25#include <stdlib.h>
26#include <unistd.h>
27#include <sys/time.h>
Andy McFadden384ef6b2010-03-15 17:24:55 -070028#include <sys/types.h>
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080029#include <sys/resource.h>
30#include <sys/mman.h>
Andy McFadden384ef6b2010-03-15 17:24:55 -070031#include <signal.h>
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080032#include <errno.h>
Andy McFaddend62c0b52009-08-04 15:02:12 -070033#include <fcntl.h>
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080034
35#if defined(HAVE_PRCTL)
36#include <sys/prctl.h>
37#endif
38
Ben Chengfe1be872009-08-21 16:18:46 -070039#if defined(WITH_SELF_VERIFICATION)
40#include "interp/Jit.h" // need for self verification
41#endif
42
43
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080044/* desktop Linux needs a little help with gettid() */
45#if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS)
46#define __KERNEL__
47# include <linux/unistd.h>
48#ifdef _syscall0
49_syscall0(pid_t,gettid)
50#else
51pid_t gettid() { return syscall(__NR_gettid);}
52#endif
53#undef __KERNEL__
54#endif
55
San Mehat256fc152009-04-21 14:03:06 -070056// Change this to enable logging on cgroup errors
57#define ENABLE_CGROUP_ERR_LOGGING 0
58
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080059// change this to LOGV/LOGD to debug thread activity
60#define LOG_THREAD LOGVV
61
62/*
63Notes on Threading
64
65All threads are native pthreads. All threads, except the JDWP debugger
66thread, are visible to code running in the VM and to the debugger. (We
67don't want the debugger to try to manipulate the thread that listens for
68instructions from the debugger.) Internal VM threads are in the "system"
69ThreadGroup, all others are in the "main" ThreadGroup, per convention.
70
71The GC only runs when all threads have been suspended. Threads are
72expected to suspend themselves, using a "safe point" mechanism. We check
73for a suspend request at certain points in the main interpreter loop,
74and on requests coming in from native code (e.g. all JNI functions).
75Certain debugger events may inspire threads to self-suspend.
76
77Native methods must use JNI calls to modify object references to avoid
78clashes with the GC. JNI doesn't provide a way for native code to access
79arrays of objects as such -- code must always get/set individual entries --
80so it should be possible to fully control access through JNI.
81
82Internal native VM threads, such as the finalizer thread, must explicitly
83check for suspension periodically. In most cases they will be sound
84asleep on a condition variable, and won't notice the suspension anyway.
85
86Threads may be suspended by the GC, debugger, or the SIGQUIT listener
87thread. The debugger may suspend or resume individual threads, while the
88GC always suspends all threads. Each thread has a "suspend count" that
89is incremented on suspend requests and decremented on resume requests.
90When the count is zero, the thread is runnable. This allows us to fulfill
91a debugger requirement: if the debugger suspends a thread, the thread is
92not allowed to run again until the debugger resumes it (or disconnects,
93in which case we must resume all debugger-suspended threads).
94
95Paused threads sleep on a condition variable, and are awoken en masse.
96Certain "slow" VM operations, such as starting up a new thread, will be
97done in a separate "VMWAIT" state, so that the rest of the VM doesn't
98freeze up waiting for the operation to finish. Threads must check for
99pending suspension when leaving VMWAIT.
100
101Because threads suspend themselves while interpreting code or when native
102code makes JNI calls, there is no risk of suspending while holding internal
103VM locks. All threads can enter a suspended (or native-code-only) state.
104Also, we don't have to worry about object references existing solely
105in hardware registers.
106
107We do, however, have to worry about objects that were allocated internally
108and aren't yet visible to anything else in the VM. If we allocate an
109object, and then go to sleep on a mutex after changing to a non-RUNNING
110state (e.g. while trying to allocate a second object), the first object
111could be garbage-collected out from under us while we sleep. To manage
112this, we automatically add all allocated objects to an internal object
113tracking list, and only remove them when we know we won't be suspended
114before the object appears in the GC root set.
115
116The debugger may choose to suspend or resume a single thread, which can
117lead to application-level deadlocks; this is expected behavior. The VM
118will only check for suspension of single threads when the debugger is
119active (the java.lang.Thread calls for this are deprecated and hence are
120not supported). Resumption of a single thread is handled by decrementing
121the thread's suspend count and sending a broadcast signal to the condition
122variable. (This will cause all threads to wake up and immediately go back
123to sleep, which isn't tremendously efficient, but neither is having the
124debugger attached.)
125
126The debugger is not allowed to resume threads suspended by the GC. This
127is trivially enforced by ignoring debugger requests while the GC is running
128(the JDWP thread is suspended during GC).
129
130The VM maintains a Thread struct for every pthread known to the VM. There
131is a java/lang/Thread object associated with every Thread. At present,
132there is no safe way to go from a Thread object to a Thread struct except by
133locking and scanning the list; this is necessary because the lifetimes of
134the two are not closely coupled. We may want to change this behavior,
135though at present the only performance impact is on the debugger (see
136threadObjToThread()). See also notes about dvmDetachCurrentThread().
137*/
138/*
139Alternate implementation (signal-based):
140
141Threads run without safe points -- zero overhead. The VM uses a signal
142(e.g. pthread_kill(SIGUSR1)) to notify threads of suspension or resumption.
143
144The trouble with using signals to suspend threads is that it means a thread
145can be in the middle of an operation when garbage collection starts.
146To prevent some sticky situations, we have to introduce critical sections
147to the VM code.
148
149Critical sections temporarily block suspension for a given thread.
150The thread must move to a non-blocked state (and self-suspend) after
151finishing its current task. If the thread blocks on a resource held
152by a suspended thread, we're hosed.
153
154One approach is to require that no blocking operations, notably
155acquisition of mutexes, can be performed within a critical section.
156This is too limiting. For example, if thread A gets suspended while
157holding the thread list lock, it will prevent the GC or debugger from
158being able to safely access the thread list. We need to wrap the critical
159section around the entire operation (enter critical, get lock, do stuff,
160release lock, exit critical).
161
162A better approach is to declare that certain resources can only be held
163within critical sections. A thread that enters a critical section and
164then gets blocked on the thread list lock knows that the thread it is
165waiting for is also in a critical section, and will release the lock
166before suspending itself. Eventually all threads will complete their
167operations and self-suspend. For this to work, the VM must:
168
169 (1) Determine the set of resources that may be accessed from the GC or
170 debugger threads. The mutexes guarding those go into the "critical
171 resource set" (CRS).
172 (2) Ensure that no resource in the CRS can be acquired outside of a
173 critical section. This can be verified with an assert().
174 (3) Ensure that only resources in the CRS can be held while in a critical
175 section. This is harder to enforce.
176
177If any of these conditions are not met, deadlock can ensue when grabbing
178resources in the GC or debugger (#1) or waiting for threads to suspend
179(#2,#3). (You won't actually deadlock in the GC, because if the semantics
180above are followed you don't need to lock anything in the GC. The risk is
181rather that the GC will access data structures in an intermediate state.)
182
183This approach requires more care and awareness in the VM than
184safe-pointing. Because the GC and debugger are fairly intrusive, there
185really aren't any internal VM resources that aren't shared. Thus, the
186enter/exit critical calls can be added to internal mutex wrappers, which
187makes it easy to get #1 and #2 right.
188
189An ordering should be established for all locks to avoid deadlocks.
190
191Monitor locks, which are also implemented with pthread calls, should not
192cause any problems here. Threads fighting over such locks will not be in
193critical sections and can be suspended freely.
194
195This can get tricky if we ever need exclusive access to VM and non-VM
196resources at the same time. It's not clear if this is a real concern.
197
198There are (at least) two ways to handle the incoming signals:
199
200 (a) Always accept signals. If we're in a critical section, the signal
201 handler just returns without doing anything (the "suspend level"
202 should have been incremented before the signal was sent). Otherwise,
203 if the "suspend level" is nonzero, we go to sleep.
204 (b) Block signals in critical sections. This ensures that we can't be
205 interrupted in a critical section, but requires pthread_sigmask()
206 calls on entry and exit.
207
208This is a choice between blocking the message and blocking the messenger.
209Because UNIX signals are unreliable (you can only know that you have been
210signaled, not whether you were signaled once or 10 times), the choice is
211not significant for correctness. The choice depends on the efficiency
212of pthread_sigmask() and the desire to actually block signals. Either way,
213it is best to ensure that there is only one indication of "blocked";
214having two (i.e. block signals and set a flag, then only send a signal
215if the flag isn't set) can lead to race conditions.
216
217The signal handler must take care to copy registers onto the stack (via
218setjmp), so that stack scans find all references. Because we have to scan
219native stacks, "exact" GC is not possible with this approach.
220
221Some other concerns with flinging signals around:
222 - Odd interactions with some debuggers (e.g. gdb on the Mac)
223 - Restrictions on some standard library calls during GC (e.g. don't
224 use printf on stdout to print GC debug messages)
225*/
226
Carl Shapiro59a93122010-01-26 17:12:51 -0800227#define kMaxThreadId ((1 << 16) - 1)
228#define kMainThreadId 1
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800229
230
231static Thread* allocThread(int interpStackSize);
232static bool prepareThread(Thread* thread);
233static void setThreadSelf(Thread* thread);
234static void unlinkThread(Thread* thread);
235static void freeThread(Thread* thread);
236static void assignThreadId(Thread* thread);
237static bool createFakeEntryFrame(Thread* thread);
238static bool createFakeRunFrame(Thread* thread);
239static void* interpThreadStart(void* arg);
240static void* internalThreadStart(void* arg);
241static void threadExitUncaughtException(Thread* thread, Object* group);
242static void threadExitCheck(void* arg);
243static void waitForThreadSuspend(Thread* self, Thread* thread);
244static int getThreadPriorityFromSystem(void);
245
Bill Buzbee46cd5b62009-06-05 15:36:06 -0700246/*
247 * The JIT needs to know if any thread is suspended. We do this by
248 * maintaining a global sum of all threads' suspend counts. All suspendCount
249 * updates should go through this after aquiring threadSuspendCountLock.
250 */
251static inline void dvmAddToThreadSuspendCount(int *pSuspendCount, int delta)
252{
253 *pSuspendCount += delta;
254 gDvm.sumThreadSuspendCount += delta;
255}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800256
257/*
258 * Initialize thread list and main thread's environment. We need to set
259 * up some basic stuff so that dvmThreadSelf() will work when we start
260 * loading classes (e.g. to check for exceptions).
261 */
262bool dvmThreadStartup(void)
263{
264 Thread* thread;
265
266 /* allocate a TLS slot */
267 if (pthread_key_create(&gDvm.pthreadKeySelf, threadExitCheck) != 0) {
268 LOGE("ERROR: pthread_key_create failed\n");
269 return false;
270 }
271
272 /* test our pthread lib */
273 if (pthread_getspecific(gDvm.pthreadKeySelf) != NULL)
274 LOGW("WARNING: newly-created pthread TLS slot is not NULL\n");
275
276 /* prep thread-related locks and conditions */
277 dvmInitMutex(&gDvm.threadListLock);
278 pthread_cond_init(&gDvm.threadStartCond, NULL);
279 //dvmInitMutex(&gDvm.vmExitLock);
280 pthread_cond_init(&gDvm.vmExitCond, NULL);
281 dvmInitMutex(&gDvm._threadSuspendLock);
282 dvmInitMutex(&gDvm.threadSuspendCountLock);
283 pthread_cond_init(&gDvm.threadSuspendCountCond, NULL);
284#ifdef WITH_DEADLOCK_PREDICTION
285 dvmInitMutex(&gDvm.deadlockHistoryLock);
286#endif
287
288 /*
289 * Dedicated monitor for Thread.sleep().
290 * TODO: change this to an Object* so we don't have to expose this
291 * call, and we interact better with JDWP monitor calls. Requires
292 * deferring the object creation to much later (e.g. final "main"
293 * thread prep) or until first use.
294 */
295 gDvm.threadSleepMon = dvmCreateMonitor(NULL);
296
297 gDvm.threadIdMap = dvmAllocBitVector(kMaxThreadId, false);
298
299 thread = allocThread(gDvm.stackSize);
300 if (thread == NULL)
301 return false;
302
303 /* switch mode for when we run initializers */
304 thread->status = THREAD_RUNNING;
305
306 /*
307 * We need to assign the threadId early so we can lock/notify
308 * object monitors. We'll set the "threadObj" field later.
309 */
310 prepareThread(thread);
311 gDvm.threadList = thread;
312
313#ifdef COUNT_PRECISE_METHODS
314 gDvm.preciseMethods = dvmPointerSetAlloc(200);
315#endif
316
317 return true;
318}
319
320/*
321 * We're a little farther up now, and can load some basic classes.
322 *
323 * We're far enough along that we can poke at java.lang.Thread and friends,
324 * but should not assume that static initializers have run (or cause them
325 * to do so). That means no object allocations yet.
326 */
327bool dvmThreadObjStartup(void)
328{
329 /*
330 * Cache the locations of these classes. It's likely that we're the
331 * first to reference them, so they're being loaded now.
332 */
333 gDvm.classJavaLangThread =
334 dvmFindSystemClassNoInit("Ljava/lang/Thread;");
335 gDvm.classJavaLangVMThread =
336 dvmFindSystemClassNoInit("Ljava/lang/VMThread;");
337 gDvm.classJavaLangThreadGroup =
338 dvmFindSystemClassNoInit("Ljava/lang/ThreadGroup;");
339 if (gDvm.classJavaLangThread == NULL ||
340 gDvm.classJavaLangThreadGroup == NULL ||
341 gDvm.classJavaLangThreadGroup == NULL)
342 {
343 LOGE("Could not find one or more essential thread classes\n");
344 return false;
345 }
346
347 /*
348 * Cache field offsets. This makes things a little faster, at the
349 * expense of hard-coding non-public field names into the VM.
350 */
351 gDvm.offJavaLangThread_vmThread =
352 dvmFindFieldOffset(gDvm.classJavaLangThread,
353 "vmThread", "Ljava/lang/VMThread;");
354 gDvm.offJavaLangThread_group =
355 dvmFindFieldOffset(gDvm.classJavaLangThread,
356 "group", "Ljava/lang/ThreadGroup;");
357 gDvm.offJavaLangThread_daemon =
358 dvmFindFieldOffset(gDvm.classJavaLangThread, "daemon", "Z");
359 gDvm.offJavaLangThread_name =
360 dvmFindFieldOffset(gDvm.classJavaLangThread,
361 "name", "Ljava/lang/String;");
362 gDvm.offJavaLangThread_priority =
363 dvmFindFieldOffset(gDvm.classJavaLangThread, "priority", "I");
364
365 if (gDvm.offJavaLangThread_vmThread < 0 ||
366 gDvm.offJavaLangThread_group < 0 ||
367 gDvm.offJavaLangThread_daemon < 0 ||
368 gDvm.offJavaLangThread_name < 0 ||
369 gDvm.offJavaLangThread_priority < 0)
370 {
371 LOGE("Unable to find all fields in java.lang.Thread\n");
372 return false;
373 }
374
375 gDvm.offJavaLangVMThread_thread =
376 dvmFindFieldOffset(gDvm.classJavaLangVMThread,
377 "thread", "Ljava/lang/Thread;");
378 gDvm.offJavaLangVMThread_vmData =
379 dvmFindFieldOffset(gDvm.classJavaLangVMThread, "vmData", "I");
380 if (gDvm.offJavaLangVMThread_thread < 0 ||
381 gDvm.offJavaLangVMThread_vmData < 0)
382 {
383 LOGE("Unable to find all fields in java.lang.VMThread\n");
384 return false;
385 }
386
387 /*
388 * Cache the vtable offset for "run()".
389 *
390 * We don't want to keep the Method* because then we won't find see
391 * methods defined in subclasses.
392 */
393 Method* meth;
394 meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThread, "run", "()V");
395 if (meth == NULL) {
396 LOGE("Unable to find run() in java.lang.Thread\n");
397 return false;
398 }
399 gDvm.voffJavaLangThread_run = meth->methodIndex;
400
401 /*
402 * Cache vtable offsets for ThreadGroup methods.
403 */
404 meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThreadGroup,
405 "removeThread", "(Ljava/lang/Thread;)V");
406 if (meth == NULL) {
407 LOGE("Unable to find removeThread(Thread) in java.lang.ThreadGroup\n");
408 return false;
409 }
410 gDvm.voffJavaLangThreadGroup_removeThread = meth->methodIndex;
411
412 return true;
413}
414
415/*
416 * All threads should be stopped by now. Clean up some thread globals.
417 */
418void dvmThreadShutdown(void)
419{
420 if (gDvm.threadList != NULL) {
Andy McFaddenf17638e2009-08-04 16:38:40 -0700421 /*
422 * If we walk through the thread list and try to free the
423 * lingering thread structures (which should only be for daemon
424 * threads), the daemon threads may crash if they execute before
425 * the process dies. Let them leak.
426 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800427 freeThread(gDvm.threadList);
428 gDvm.threadList = NULL;
429 }
430
431 dvmFreeBitVector(gDvm.threadIdMap);
432
433 dvmFreeMonitorList();
434
435 pthread_key_delete(gDvm.pthreadKeySelf);
436}
437
438
439/*
440 * Grab the suspend count global lock.
441 */
442static inline void lockThreadSuspendCount(void)
443{
444 /*
445 * Don't try to change to VMWAIT here. When we change back to RUNNING
446 * we have to check for a pending suspend, which results in grabbing
447 * this lock recursively. Doesn't work with "fast" pthread mutexes.
448 *
449 * This lock is always held for very brief periods, so as long as
450 * mutex ordering is respected we shouldn't stall.
451 */
Brian Carlstromfbdcfb92010-05-28 15:42:12 -0700452 dvmLockMutex(&gDvm.threadSuspendCountLock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800453}
454
455/*
456 * Release the suspend count global lock.
457 */
458static inline void unlockThreadSuspendCount(void)
459{
460 dvmUnlockMutex(&gDvm.threadSuspendCountLock);
461}
462
463/*
464 * Grab the thread list global lock.
465 *
466 * This is held while "suspend all" is trying to make everybody stop. If
467 * the shutdown is in progress, and somebody tries to grab the lock, they'll
468 * have to wait for the GC to finish. Therefore it's important that the
469 * thread not be in RUNNING mode.
470 *
471 * We don't have to check to see if we should be suspended once we have
472 * the lock. Nobody can suspend all threads without holding the thread list
473 * lock while they do it, so by definition there isn't a GC in progress.
Andy McFadden44860362009-08-06 17:56:14 -0700474 *
Andy McFadden3469a7e2010-08-04 16:09:10 -0700475 * This function deliberately avoids the use of dvmChangeStatus(),
476 * which could grab threadSuspendCountLock. To avoid deadlock, threads
477 * are required to grab the thread list lock before the thread suspend
478 * count lock. (See comment in DvmGlobals.)
479 *
Andy McFadden44860362009-08-06 17:56:14 -0700480 * TODO: consider checking for suspend after acquiring the lock, and
481 * backing off if set. As stated above, it can't happen during normal
482 * execution, but it *can* happen during shutdown when daemon threads
483 * are being suspended.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800484 */
485void dvmLockThreadList(Thread* self)
486{
487 ThreadStatus oldStatus;
488
489 if (self == NULL) /* try to get it from TLS */
490 self = dvmThreadSelf();
491
492 if (self != NULL) {
493 oldStatus = self->status;
494 self->status = THREAD_VMWAIT;
495 } else {
Andy McFadden44860362009-08-06 17:56:14 -0700496 /* happens during VM shutdown */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800497 //LOGW("NULL self in dvmLockThreadList\n");
498 oldStatus = -1; // shut up gcc
499 }
500
Brian Carlstromfbdcfb92010-05-28 15:42:12 -0700501 dvmLockMutex(&gDvm.threadListLock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800502
503 if (self != NULL)
504 self->status = oldStatus;
505}
506
507/*
508 * Release the thread list global lock.
509 */
510void dvmUnlockThreadList(void)
511{
Brian Carlstromfbdcfb92010-05-28 15:42:12 -0700512 dvmUnlockMutex(&gDvm.threadListLock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800513}
514
The Android Open Source Project99409882009-03-18 22:20:24 -0700515/*
516 * Convert SuspendCause to a string.
517 */
518static const char* getSuspendCauseStr(SuspendCause why)
519{
520 switch (why) {
521 case SUSPEND_NOT: return "NOT?";
522 case SUSPEND_FOR_GC: return "gc";
523 case SUSPEND_FOR_DEBUG: return "debug";
524 case SUSPEND_FOR_DEBUG_EVENT: return "debug-event";
525 case SUSPEND_FOR_STACK_DUMP: return "stack-dump";
Brian Carlstromfbdcfb92010-05-28 15:42:12 -0700526 case SUSPEND_FOR_VERIFY: return "verify";
Ben Chenga8e64a72009-10-20 13:01:36 -0700527#if defined(WITH_JIT)
528 case SUSPEND_FOR_TBL_RESIZE: return "table-resize";
529 case SUSPEND_FOR_IC_PATCH: return "inline-cache-patch";
Ben Cheng60c24f42010-01-04 12:29:56 -0800530 case SUSPEND_FOR_CC_RESET: return "reset-code-cache";
Bill Buzbee964a7b02010-01-28 12:54:19 -0800531 case SUSPEND_FOR_REFRESH: return "refresh jit status";
Ben Chenga8e64a72009-10-20 13:01:36 -0700532#endif
The Android Open Source Project99409882009-03-18 22:20:24 -0700533 default: return "UNKNOWN";
534 }
535}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800536
537/*
538 * Grab the "thread suspend" lock. This is required to prevent the
539 * GC and the debugger from simultaneously suspending all threads.
540 *
541 * If we fail to get the lock, somebody else is trying to suspend all
542 * threads -- including us. If we go to sleep on the lock we'll deadlock
543 * the VM. Loop until we get it or somebody puts us to sleep.
544 */
545static void lockThreadSuspend(const char* who, SuspendCause why)
546{
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800547 const int kSpinSleepTime = 3*1000*1000; /* 3s */
548 u8 startWhen = 0; // init req'd to placate gcc
549 int sleepIter = 0;
550 int cc;
Jeff Hao97319a82009-08-12 16:57:15 -0700551
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800552 do {
Brian Carlstromfbdcfb92010-05-28 15:42:12 -0700553 cc = dvmTryLockMutex(&gDvm._threadSuspendLock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800554 if (cc != 0) {
Brian Carlstromfbdcfb92010-05-28 15:42:12 -0700555 Thread* self = dvmThreadSelf();
556
557 if (!dvmCheckSuspendPending(self)) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800558 /*
Andy McFadden2aa43612009-06-17 16:29:30 -0700559 * Could be that a resume-all is in progress, and something
560 * grabbed the CPU when the wakeup was broadcast. The thread
561 * performing the resume hasn't had a chance to release the
Andy McFaddene8059be2009-06-04 14:34:14 -0700562 * thread suspend lock. (We release before the broadcast,
563 * so this should be a narrow window.)
Andy McFadden2aa43612009-06-17 16:29:30 -0700564 *
565 * Could be we hit the window as a suspend was started,
566 * and the lock has been grabbed but the suspend counts
567 * haven't been incremented yet.
The Android Open Source Project99409882009-03-18 22:20:24 -0700568 *
569 * Could be an unusual JNI thread-attach thing.
570 *
571 * Could be the debugger telling us to resume at roughly
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800572 * the same time we're posting an event.
Ben Chenga8e64a72009-10-20 13:01:36 -0700573 *
574 * Could be two app threads both want to patch predicted
575 * chaining cells around the same time.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800576 */
The Android Open Source Project99409882009-03-18 22:20:24 -0700577 LOGI("threadid=%d ODD: want thread-suspend lock (%s:%s),"
578 " it's held, no suspend pending\n",
Brian Carlstromfbdcfb92010-05-28 15:42:12 -0700579 self->threadId, who, getSuspendCauseStr(why));
The Android Open Source Project99409882009-03-18 22:20:24 -0700580 } else {
581 /* we suspended; reset timeout */
582 sleepIter = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800583 }
584
585 /* give the lock-holder a chance to do some work */
586 if (sleepIter == 0)
587 startWhen = dvmGetRelativeTimeUsec();
588 if (!dvmIterativeSleep(sleepIter++, kSpinSleepTime, startWhen)) {
The Android Open Source Project99409882009-03-18 22:20:24 -0700589 LOGE("threadid=%d: couldn't get thread-suspend lock (%s:%s),"
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800590 " bailing\n",
Brian Carlstromfbdcfb92010-05-28 15:42:12 -0700591 self->threadId, who, getSuspendCauseStr(why));
Andy McFadden2aa43612009-06-17 16:29:30 -0700592 /* threads are not suspended, thread dump could crash */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800593 dvmDumpAllThreads(false);
594 dvmAbort();
595 }
596 }
597 } while (cc != 0);
598 assert(cc == 0);
599}
600
601/*
602 * Release the "thread suspend" lock.
603 */
604static inline void unlockThreadSuspend(void)
605{
Brian Carlstromfbdcfb92010-05-28 15:42:12 -0700606 dvmUnlockMutex(&gDvm._threadSuspendLock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800607}
608
609
610/*
611 * Kill any daemon threads that still exist. All of ours should be
612 * stopped, so these should be Thread objects or JNI-attached threads
613 * started by the application. Actively-running threads are likely
614 * to crash the process if they continue to execute while the VM
615 * shuts down, so we really need to kill or suspend them. (If we want
616 * the VM to restart within this process, we need to kill them, but that
617 * leaves open the possibility of orphaned resources.)
618 *
619 * Waiting for the thread to suspend may be unwise at this point, but
620 * if one of these is wedged in a critical section then we probably
621 * would've locked up on the last GC attempt.
622 *
623 * It's possible for this function to get called after a failed
624 * initialization, so be careful with assumptions about the environment.
Andy McFadden44860362009-08-06 17:56:14 -0700625 *
626 * This will be called from whatever thread calls DestroyJavaVM, usually
627 * but not necessarily the main thread. It's likely, but not guaranteed,
628 * that the current thread has already been cleaned up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800629 */
630void dvmSlayDaemons(void)
631{
Andy McFadden44860362009-08-06 17:56:14 -0700632 Thread* self = dvmThreadSelf(); // may be null
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800633 Thread* target;
Andy McFadden44860362009-08-06 17:56:14 -0700634 int threadId = 0;
635 bool doWait = false;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800636
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800637 dvmLockThreadList(self);
638
Andy McFadden44860362009-08-06 17:56:14 -0700639 if (self != NULL)
640 threadId = self->threadId;
641
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800642 target = gDvm.threadList;
643 while (target != NULL) {
644 if (target == self) {
645 target = target->next;
646 continue;
647 }
648
649 if (!dvmGetFieldBoolean(target->threadObj,
650 gDvm.offJavaLangThread_daemon))
651 {
Andy McFadden44860362009-08-06 17:56:14 -0700652 /* should never happen; suspend it with the rest */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800653 LOGW("threadid=%d: non-daemon id=%d still running at shutdown?!\n",
Andy McFadden44860362009-08-06 17:56:14 -0700654 threadId, target->threadId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800655 }
656
Andy McFadden44860362009-08-06 17:56:14 -0700657 char* threadName = dvmGetThreadName(target);
658 LOGD("threadid=%d: suspending daemon id=%d name='%s'\n",
659 threadId, target->threadId, threadName);
660 free(threadName);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800661
Andy McFadden44860362009-08-06 17:56:14 -0700662 /* mark as suspended */
663 lockThreadSuspendCount();
664 dvmAddToThreadSuspendCount(&target->suspendCount, 1);
665 unlockThreadSuspendCount();
666 doWait = true;
667
668 target = target->next;
669 }
670
671 //dvmDumpAllThreads(false);
672
673 /*
674 * Unlock the thread list, relocking it later if necessary. It's
675 * possible a thread is in VMWAIT after calling dvmLockThreadList,
676 * and that function *doesn't* check for pending suspend after
677 * acquiring the lock. We want to let them finish their business
678 * and see the pending suspend before we continue here.
679 *
680 * There's no guarantee of mutex fairness, so this might not work.
681 * (The alternative is to have dvmLockThreadList check for suspend
682 * after acquiring the lock and back off, something we should consider.)
683 */
684 dvmUnlockThreadList();
685
686 if (doWait) {
Andy McFaddend2afbcf2010-03-02 14:23:04 -0800687 bool complained = false;
688
Andy McFadden44860362009-08-06 17:56:14 -0700689 usleep(200 * 1000);
690
691 dvmLockThreadList(self);
692
693 /*
694 * Sleep for a bit until the threads have suspended. We're trying
695 * to exit, so don't wait for too long.
696 */
697 int i;
698 for (i = 0; i < 10; i++) {
699 bool allSuspended = true;
700
701 target = gDvm.threadList;
702 while (target != NULL) {
703 if (target == self) {
704 target = target->next;
705 continue;
706 }
707
708 if (target->status == THREAD_RUNNING && !target->isSuspended) {
Andy McFaddend2afbcf2010-03-02 14:23:04 -0800709 if (!complained)
710 LOGD("threadid=%d not ready yet\n", target->threadId);
Andy McFadden44860362009-08-06 17:56:14 -0700711 allSuspended = false;
Andy McFaddend2afbcf2010-03-02 14:23:04 -0800712 /* keep going so we log each running daemon once */
Andy McFadden44860362009-08-06 17:56:14 -0700713 }
714
715 target = target->next;
716 }
717
718 if (allSuspended) {
719 LOGD("threadid=%d: all daemons have suspended\n", threadId);
720 break;
721 } else {
Andy McFaddend2afbcf2010-03-02 14:23:04 -0800722 if (!complained) {
723 complained = true;
724 LOGD("threadid=%d: waiting briefly for daemon suspension\n",
725 threadId);
Andy McFaddend2afbcf2010-03-02 14:23:04 -0800726 }
Andy McFadden44860362009-08-06 17:56:14 -0700727 }
728
729 usleep(200 * 1000);
730 }
731 dvmUnlockThreadList();
732 }
733
734#if 0 /* bad things happen if they come out of JNI or "spuriously" wake up */
735 /*
736 * Abandon the threads and recover their resources.
737 */
738 target = gDvm.threadList;
739 while (target != NULL) {
740 Thread* nextTarget = target->next;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800741 unlinkThread(target);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800742 freeThread(target);
743 target = nextTarget;
744 }
Andy McFadden44860362009-08-06 17:56:14 -0700745#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800746
Andy McFadden44860362009-08-06 17:56:14 -0700747 //dvmDumpAllThreads(true);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800748}
749
750
751/*
752 * Finish preparing the parts of the Thread struct required to support
753 * JNI registration.
754 */
755bool dvmPrepMainForJni(JNIEnv* pEnv)
756{
757 Thread* self;
758
759 /* main thread is always first in list at this point */
760 self = gDvm.threadList;
761 assert(self->threadId == kMainThreadId);
762
763 /* create a "fake" JNI frame at the top of the main thread interp stack */
764 if (!createFakeEntryFrame(self))
765 return false;
766
767 /* fill these in, since they weren't ready at dvmCreateJNIEnv time */
768 dvmSetJniEnvThreadId(pEnv, self);
769 dvmSetThreadJNIEnv(self, (JNIEnv*) pEnv);
770
771 return true;
772}
773
774
775/*
776 * Finish preparing the main thread, allocating some objects to represent
777 * it. As part of doing so, we finish initializing Thread and ThreadGroup.
Andy McFaddena1a7a342009-05-04 13:29:30 -0700778 * This will execute some interpreted code (e.g. class initializers).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800779 */
780bool dvmPrepMainThread(void)
781{
782 Thread* thread;
783 Object* groupObj;
784 Object* threadObj;
785 Object* vmThreadObj;
786 StringObject* threadNameStr;
787 Method* init;
788 JValue unused;
789
790 LOGV("+++ finishing prep on main VM thread\n");
791
792 /* main thread is always first in list at this point */
793 thread = gDvm.threadList;
794 assert(thread->threadId == kMainThreadId);
795
796 /*
797 * Make sure the classes are initialized. We have to do this before
798 * we create an instance of them.
799 */
800 if (!dvmInitClass(gDvm.classJavaLangClass)) {
801 LOGE("'Class' class failed to initialize\n");
802 return false;
803 }
804 if (!dvmInitClass(gDvm.classJavaLangThreadGroup) ||
805 !dvmInitClass(gDvm.classJavaLangThread) ||
806 !dvmInitClass(gDvm.classJavaLangVMThread))
807 {
808 LOGE("thread classes failed to initialize\n");
809 return false;
810 }
811
812 groupObj = dvmGetMainThreadGroup();
813 if (groupObj == NULL)
814 return false;
815
816 /*
817 * Allocate and construct a Thread with the internal-creation
818 * constructor.
819 */
820 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_DEFAULT);
821 if (threadObj == NULL) {
822 LOGE("unable to allocate main thread object\n");
823 return false;
824 }
825 dvmReleaseTrackedAlloc(threadObj, NULL);
826
Barry Hayes81f3ebe2010-06-15 16:17:37 -0700827 threadNameStr = dvmCreateStringFromCstr("main");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800828 if (threadNameStr == NULL)
829 return false;
830 dvmReleaseTrackedAlloc((Object*)threadNameStr, NULL);
831
832 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
833 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
834 assert(init != NULL);
835 dvmCallMethod(thread, init, threadObj, &unused, groupObj, threadNameStr,
836 THREAD_NORM_PRIORITY, false);
837 if (dvmCheckException(thread)) {
838 LOGE("exception thrown while constructing main thread object\n");
839 return false;
840 }
841
842 /*
843 * Allocate and construct a VMThread.
844 */
845 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
846 if (vmThreadObj == NULL) {
847 LOGE("unable to allocate main vmthread object\n");
848 return false;
849 }
850 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
851
852 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangVMThread, "<init>",
853 "(Ljava/lang/Thread;)V");
854 dvmCallMethod(thread, init, vmThreadObj, &unused, threadObj);
855 if (dvmCheckException(thread)) {
856 LOGE("exception thrown while constructing main vmthread object\n");
857 return false;
858 }
859
860 /* set the VMThread.vmData field to our Thread struct */
861 assert(gDvm.offJavaLangVMThread_vmData != 0);
862 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)thread);
863
864 /*
865 * Stuff the VMThread back into the Thread. From this point on, other
Andy McFaddena1a7a342009-05-04 13:29:30 -0700866 * Threads will see that this Thread is running (at least, they would,
867 * if there were any).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800868 */
869 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread,
870 vmThreadObj);
871
872 thread->threadObj = threadObj;
873
874 /*
Andy McFaddena1a7a342009-05-04 13:29:30 -0700875 * Set the context class loader. This invokes a ClassLoader method,
876 * which could conceivably call Thread.currentThread(), so we want the
877 * Thread to be fully configured before we do this.
878 */
879 Object* systemLoader = dvmGetSystemClassLoader();
880 if (systemLoader == NULL) {
881 LOGW("WARNING: system class loader is NULL (setting main ctxt)\n");
882 /* keep going */
883 }
884 int ctxtClassLoaderOffset = dvmFindFieldOffset(gDvm.classJavaLangThread,
885 "contextClassLoader", "Ljava/lang/ClassLoader;");
886 if (ctxtClassLoaderOffset < 0) {
887 LOGE("Unable to find contextClassLoader field in Thread\n");
888 return false;
889 }
890 dvmSetFieldObject(threadObj, ctxtClassLoaderOffset, systemLoader);
891
892 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800893 * Finish our thread prep.
894 */
895
896 /* include self in non-daemon threads (mainly for AttachCurrentThread) */
897 gDvm.nonDaemonThreadCount++;
898
899 return true;
900}
901
902
903/*
904 * Alloc and initialize a Thread struct.
905 *
Andy McFaddene3346d82010-06-02 15:37:21 -0700906 * Does not create any objects, just stuff on the system (malloc) heap.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800907 */
908static Thread* allocThread(int interpStackSize)
909{
910 Thread* thread;
911 u1* stackBottom;
912
913 thread = (Thread*) calloc(1, sizeof(Thread));
914 if (thread == NULL)
915 return NULL;
916
Jeff Hao97319a82009-08-12 16:57:15 -0700917#if defined(WITH_SELF_VERIFICATION)
918 if (dvmSelfVerificationShadowSpaceAlloc(thread) == NULL)
919 return NULL;
920#endif
921
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800922 assert(interpStackSize >= kMinStackSize && interpStackSize <=kMaxStackSize);
923
924 thread->status = THREAD_INITIALIZING;
925 thread->suspendCount = 0;
926
927#ifdef WITH_ALLOC_LIMITS
928 thread->allocLimit = -1;
929#endif
930
931 /*
932 * Allocate and initialize the interpreted code stack. We essentially
933 * "lose" the alloc pointer, which points at the bottom of the stack,
934 * but we can get it back later because we know how big the stack is.
935 *
936 * The stack must be aligned on a 4-byte boundary.
937 */
938#ifdef MALLOC_INTERP_STACK
939 stackBottom = (u1*) malloc(interpStackSize);
940 if (stackBottom == NULL) {
Jeff Hao97319a82009-08-12 16:57:15 -0700941#if defined(WITH_SELF_VERIFICATION)
942 dvmSelfVerificationShadowSpaceFree(thread);
943#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800944 free(thread);
945 return NULL;
946 }
947 memset(stackBottom, 0xc5, interpStackSize); // stop valgrind complaints
948#else
949 stackBottom = mmap(NULL, interpStackSize, PROT_READ | PROT_WRITE,
950 MAP_PRIVATE | MAP_ANON, -1, 0);
951 if (stackBottom == MAP_FAILED) {
Jeff Hao97319a82009-08-12 16:57:15 -0700952#if defined(WITH_SELF_VERIFICATION)
953 dvmSelfVerificationShadowSpaceFree(thread);
954#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800955 free(thread);
956 return NULL;
957 }
958#endif
959
960 assert(((u4)stackBottom & 0x03) == 0); // looks like our malloc ensures this
961 thread->interpStackSize = interpStackSize;
962 thread->interpStackStart = stackBottom + interpStackSize;
963 thread->interpStackEnd = stackBottom + STACK_OVERFLOW_RESERVE;
964
965 /* give the thread code a chance to set things up */
966 dvmInitInterpStack(thread, interpStackSize);
967
968 return thread;
969}
970
971/*
972 * Get a meaningful thread ID. At present this only has meaning under Linux,
973 * where getpid() and gettid() sometimes agree and sometimes don't depending
974 * on your thread model (try "export LD_ASSUME_KERNEL=2.4.19").
975 */
976pid_t dvmGetSysThreadId(void)
977{
978#ifdef HAVE_GETTID
979 return gettid();
980#else
981 return getpid();
982#endif
983}
984
985/*
986 * Finish initialization of a Thread struct.
987 *
988 * This must be called while executing in the new thread, but before the
989 * thread is added to the thread list.
990 *
Brian Carlstromfbdcfb92010-05-28 15:42:12 -0700991 * NOTE: The threadListLock must be held by the caller (needed for
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800992 * assignThreadId()).
993 */
994static bool prepareThread(Thread* thread)
995{
996 assignThreadId(thread);
997 thread->handle = pthread_self();
998 thread->systemTid = dvmGetSysThreadId();
999
1000 //LOGI("SYSTEM TID IS %d (pid is %d)\n", (int) thread->systemTid,
1001 // (int) getpid());
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07001002 /*
1003 * If we were called by dvmAttachCurrentThread, the self value is
1004 * already correctly established as "thread".
1005 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001006 setThreadSelf(thread);
1007
1008 LOGV("threadid=%d: interp stack at %p\n",
1009 thread->threadId, thread->interpStackStart - thread->interpStackSize);
1010
1011 /*
1012 * Initialize invokeReq.
1013 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001014 dvmInitMutex(&thread->invokeReq.lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001015 pthread_cond_init(&thread->invokeReq.cv, NULL);
1016
1017 /*
1018 * Initialize our reference tracking tables.
1019 *
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001020 * Most threads won't use jniMonitorRefTable, so we clear out the
1021 * structure but don't call the init function (which allocs storage).
1022 */
Andy McFaddend5ab7262009-08-25 07:19:34 -07001023#ifdef USE_INDIRECT_REF
1024 if (!dvmInitIndirectRefTable(&thread->jniLocalRefTable,
1025 kJniLocalRefMin, kJniLocalRefMax, kIndirectKindLocal))
1026 return false;
1027#else
1028 /*
1029 * The JNI local ref table *must* be fixed-size because we keep pointers
1030 * into the table in our stack frames.
1031 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001032 if (!dvmInitReferenceTable(&thread->jniLocalRefTable,
1033 kJniLocalRefMax, kJniLocalRefMax))
1034 return false;
Andy McFaddend5ab7262009-08-25 07:19:34 -07001035#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001036 if (!dvmInitReferenceTable(&thread->internalLocalRefTable,
1037 kInternalRefDefault, kInternalRefMax))
1038 return false;
1039
1040 memset(&thread->jniMonitorRefTable, 0, sizeof(thread->jniMonitorRefTable));
1041
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001042 pthread_cond_init(&thread->waitCond, NULL);
1043 dvmInitMutex(&thread->waitMutex);
1044
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001045 return true;
1046}
1047
1048/*
1049 * Remove a thread from the internal list.
1050 * Clear out the links to make it obvious that the thread is
1051 * no longer on the list. Caller must hold gDvm.threadListLock.
1052 */
1053static void unlinkThread(Thread* thread)
1054{
1055 LOG_THREAD("threadid=%d: removing from list\n", thread->threadId);
1056 if (thread == gDvm.threadList) {
1057 assert(thread->prev == NULL);
1058 gDvm.threadList = thread->next;
1059 } else {
1060 assert(thread->prev != NULL);
1061 thread->prev->next = thread->next;
1062 }
1063 if (thread->next != NULL)
1064 thread->next->prev = thread->prev;
1065 thread->prev = thread->next = NULL;
1066}
1067
1068/*
1069 * Free a Thread struct, and all the stuff allocated within.
1070 */
1071static void freeThread(Thread* thread)
1072{
1073 if (thread == NULL)
1074 return;
1075
1076 /* thread->threadId is zero at this point */
1077 LOGVV("threadid=%d: freeing\n", thread->threadId);
1078
1079 if (thread->interpStackStart != NULL) {
1080 u1* interpStackBottom;
1081
1082 interpStackBottom = thread->interpStackStart;
1083 interpStackBottom -= thread->interpStackSize;
1084#ifdef MALLOC_INTERP_STACK
1085 free(interpStackBottom);
1086#else
1087 if (munmap(interpStackBottom, thread->interpStackSize) != 0)
1088 LOGW("munmap(thread stack) failed\n");
1089#endif
1090 }
1091
Andy McFaddend5ab7262009-08-25 07:19:34 -07001092#ifdef USE_INDIRECT_REF
1093 dvmClearIndirectRefTable(&thread->jniLocalRefTable);
1094#else
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001095 dvmClearReferenceTable(&thread->jniLocalRefTable);
Andy McFaddend5ab7262009-08-25 07:19:34 -07001096#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001097 dvmClearReferenceTable(&thread->internalLocalRefTable);
1098 if (&thread->jniMonitorRefTable.table != NULL)
1099 dvmClearReferenceTable(&thread->jniMonitorRefTable);
1100
Jeff Hao97319a82009-08-12 16:57:15 -07001101#if defined(WITH_SELF_VERIFICATION)
1102 dvmSelfVerificationShadowSpaceFree(thread);
1103#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001104 free(thread);
1105}
1106
1107/*
1108 * Like pthread_self(), but on a Thread*.
1109 */
1110Thread* dvmThreadSelf(void)
1111{
1112 return (Thread*) pthread_getspecific(gDvm.pthreadKeySelf);
1113}
1114
1115/*
1116 * Explore our sense of self. Stuffs the thread pointer into TLS.
1117 */
1118static void setThreadSelf(Thread* thread)
1119{
1120 int cc;
1121
1122 cc = pthread_setspecific(gDvm.pthreadKeySelf, thread);
1123 if (cc != 0) {
1124 /*
1125 * Sometimes this fails under Bionic with EINVAL during shutdown.
1126 * This can happen if the timing is just right, e.g. a thread
1127 * fails to attach during shutdown, but the "fail" path calls
1128 * here to ensure we clean up after ourselves.
1129 */
1130 if (thread != NULL) {
1131 LOGE("pthread_setspecific(%p) failed, err=%d\n", thread, cc);
1132 dvmAbort(); /* the world is fundamentally hosed */
1133 }
1134 }
1135}
1136
1137/*
1138 * This is associated with the pthreadKeySelf key. It's called by the
1139 * pthread library when a thread is exiting and the "self" pointer in TLS
1140 * is non-NULL, meaning the VM hasn't had a chance to clean up. In normal
Andy McFadden909ce242009-12-10 16:38:30 -08001141 * operation this will not be called.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001142 *
1143 * This is mainly of use to ensure that we don't leak resources if, for
1144 * example, a thread attaches itself to us with AttachCurrentThread and
1145 * then exits without notifying the VM.
Andy McFadden34e25bb2009-04-15 13:27:12 -07001146 *
1147 * We could do the detach here instead of aborting, but this will lead to
1148 * portability problems. Other implementations do not do this check and
1149 * will simply be unaware that the thread has exited, leading to resource
1150 * leaks (and, if this is a non-daemon thread, an infinite hang when the
1151 * VM tries to shut down).
Andy McFadden909ce242009-12-10 16:38:30 -08001152 *
1153 * Because some implementations may want to use the pthread destructor
1154 * to initiate the detach, and the ordering of destructors is not defined,
1155 * we want to iterate a couple of times to give those a chance to run.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001156 */
1157static void threadExitCheck(void* arg)
1158{
Andy McFadden909ce242009-12-10 16:38:30 -08001159 const int kMaxCount = 2;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001160
Andy McFadden909ce242009-12-10 16:38:30 -08001161 Thread* self = (Thread*) arg;
1162 assert(self != NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001163
Andy McFadden909ce242009-12-10 16:38:30 -08001164 LOGV("threadid=%d: threadExitCheck(%p) count=%d\n",
1165 self->threadId, arg, self->threadExitCheckCount);
1166
1167 if (self->status == THREAD_ZOMBIE) {
1168 LOGW("threadid=%d: Weird -- shouldn't be in threadExitCheck\n",
1169 self->threadId);
1170 return;
1171 }
1172
1173 if (self->threadExitCheckCount < kMaxCount) {
1174 /*
1175 * Spin a couple of times to let other destructors fire.
1176 */
1177 LOGD("threadid=%d: thread exiting, not yet detached (count=%d)\n",
1178 self->threadId, self->threadExitCheckCount);
1179 self->threadExitCheckCount++;
1180 int cc = pthread_setspecific(gDvm.pthreadKeySelf, self);
1181 if (cc != 0) {
1182 LOGE("threadid=%d: unable to re-add thread to TLS\n",
1183 self->threadId);
1184 dvmAbort();
1185 }
1186 } else {
1187 LOGE("threadid=%d: native thread exited without detaching\n",
1188 self->threadId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001189 dvmAbort();
1190 }
1191}
1192
1193
1194/*
1195 * Assign the threadId. This needs to be a small integer so that our
1196 * "thin" locks fit in a small number of bits.
1197 *
1198 * We reserve zero for use as an invalid ID.
1199 *
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07001200 * This must be called with threadListLock held.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001201 */
1202static void assignThreadId(Thread* thread)
1203{
Carl Shapiro59a93122010-01-26 17:12:51 -08001204 /*
1205 * Find a small unique integer. threadIdMap is a vector of
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001206 * kMaxThreadId bits; dvmAllocBit() returns the index of a
1207 * bit, meaning that it will always be < kMaxThreadId.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001208 */
1209 int num = dvmAllocBit(gDvm.threadIdMap);
1210 if (num < 0) {
1211 LOGE("Ran out of thread IDs\n");
1212 dvmAbort(); // TODO: make this a non-fatal error result
1213 }
1214
Carl Shapiro59a93122010-01-26 17:12:51 -08001215 thread->threadId = num + 1;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001216
1217 assert(thread->threadId != 0);
1218 assert(thread->threadId != DVM_LOCK_INITIAL_THIN_VALUE);
1219}
1220
1221/*
1222 * Give back the thread ID.
1223 */
1224static void releaseThreadId(Thread* thread)
1225{
1226 assert(thread->threadId > 0);
Carl Shapiro7eed8082010-01-28 16:12:44 -08001227 dvmClearBit(gDvm.threadIdMap, thread->threadId - 1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001228 thread->threadId = 0;
1229}
1230
1231
1232/*
1233 * Add a stack frame that makes it look like the native code in the main
1234 * thread was originally invoked from interpreted code. This gives us a
1235 * place to hang JNI local references. The VM spec says (v2 5.2) that the
1236 * VM begins by executing "main" in a class, so in a way this brings us
1237 * closer to the spec.
1238 */
1239static bool createFakeEntryFrame(Thread* thread)
1240{
1241 assert(thread->threadId == kMainThreadId); // main thread only
1242
1243 /* find the method on first use */
1244 if (gDvm.methFakeNativeEntry == NULL) {
1245 ClassObject* nativeStart;
1246 Method* mainMeth;
1247
1248 nativeStart = dvmFindSystemClassNoInit(
1249 "Ldalvik/system/NativeStart;");
1250 if (nativeStart == NULL) {
1251 LOGE("Unable to find dalvik.system.NativeStart class\n");
1252 return false;
1253 }
1254
1255 /*
1256 * Because we are creating a frame that represents application code, we
1257 * want to stuff the application class loader into the method's class
1258 * loader field, even though we're using the system class loader to
1259 * load it. This makes life easier over in JNI FindClass (though it
1260 * could bite us in other ways).
1261 *
1262 * Unfortunately this is occurring too early in the initialization,
1263 * of necessity coming before JNI is initialized, and we're not quite
1264 * ready to set up the application class loader.
1265 *
1266 * So we save a pointer to the method in gDvm.methFakeNativeEntry
1267 * and check it in FindClass. The method is private so nobody else
1268 * can call it.
1269 */
1270 //nativeStart->classLoader = dvmGetSystemClassLoader();
1271
1272 mainMeth = dvmFindDirectMethodByDescriptor(nativeStart,
1273 "main", "([Ljava/lang/String;)V");
1274 if (mainMeth == NULL) {
1275 LOGE("Unable to find 'main' in dalvik.system.NativeStart\n");
1276 return false;
1277 }
1278
1279 gDvm.methFakeNativeEntry = mainMeth;
1280 }
1281
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07001282 if (!dvmPushJNIFrame(thread, gDvm.methFakeNativeEntry))
1283 return false;
1284
1285 /*
1286 * Null out the "String[] args" argument.
1287 */
1288 assert(gDvm.methFakeNativeEntry->registersSize == 1);
1289 u4* framePtr = (u4*) thread->curFrame;
1290 framePtr[0] = 0;
1291
1292 return true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001293}
1294
1295
1296/*
1297 * Add a stack frame that makes it look like the native thread has been
1298 * executing interpreted code. This gives us a place to hang JNI local
1299 * references.
1300 */
1301static bool createFakeRunFrame(Thread* thread)
1302{
1303 ClassObject* nativeStart;
1304 Method* runMeth;
1305
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07001306 /*
1307 * TODO: cache this result so we don't have to dig for it every time
1308 * somebody attaches a thread to the VM. Also consider changing this
1309 * to a static method so we don't have a null "this" pointer in the
1310 * "ins" on the stack. (Does it really need to look like a Runnable?)
1311 */
1312 nativeStart = dvmFindSystemClassNoInit("Ldalvik/system/NativeStart;");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001313 if (nativeStart == NULL) {
1314 LOGE("Unable to find dalvik.system.NativeStart class\n");
1315 return false;
1316 }
1317
1318 runMeth = dvmFindVirtualMethodByDescriptor(nativeStart, "run", "()V");
1319 if (runMeth == NULL) {
1320 LOGE("Unable to find 'run' in dalvik.system.NativeStart\n");
1321 return false;
1322 }
1323
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07001324 if (!dvmPushJNIFrame(thread, runMeth))
1325 return false;
1326
1327 /*
1328 * Provide a NULL 'this' argument. The method we've put at the top of
1329 * the stack looks like a virtual call to run() in a Runnable class.
1330 * (If we declared the method static, it wouldn't take any arguments
1331 * and we wouldn't have to do this.)
1332 */
1333 assert(runMeth->registersSize == 1);
1334 u4* framePtr = (u4*) thread->curFrame;
1335 framePtr[0] = 0;
1336
1337 return true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001338}
1339
1340/*
1341 * Helper function to set the name of the current thread
1342 */
1343static void setThreadName(const char *threadName)
1344{
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001345 int hasAt = 0;
1346 int hasDot = 0;
1347 const char *s = threadName;
1348 while (*s) {
1349 if (*s == '.') hasDot = 1;
1350 else if (*s == '@') hasAt = 1;
1351 s++;
1352 }
1353 int len = s - threadName;
1354 if (len < 15 || hasAt || !hasDot) {
1355 s = threadName;
1356 } else {
1357 s = threadName + len - 15;
1358 }
Andy McFadden22ec6092010-07-01 11:23:15 -07001359#if defined(HAVE_ANDROID_PTHREAD_SETNAME_NP)
Andy McFaddenb122c8b2010-07-08 15:43:19 -07001360 /* pthread_setname_np fails rather than truncating long strings */
1361 char buf[16]; // MAX_TASK_COMM_LEN=16 is hard-coded into bionic
1362 strncpy(buf, s, sizeof(buf)-1);
1363 buf[sizeof(buf)-1] = '\0';
1364 int err = pthread_setname_np(pthread_self(), buf);
1365 if (err != 0) {
1366 LOGW("Unable to set the name of current thread to '%s': %s\n",
1367 buf, strerror(err));
1368 }
André Goddard Rosabcd88cc2010-06-09 20:32:14 -03001369#elif defined(HAVE_PRCTL)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001370 prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
André Goddard Rosabcd88cc2010-06-09 20:32:14 -03001371#else
Andy McFaddenb122c8b2010-07-08 15:43:19 -07001372 LOGD("No way to set current thread's name (%s)\n", s);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001373#endif
1374}
1375
1376/*
1377 * Create a thread as a result of java.lang.Thread.start().
1378 *
1379 * We do have to worry about some concurrency problems, e.g. programs
1380 * that try to call Thread.start() on the same object from multiple threads.
1381 * (This will fail for all but one, but we have to make sure that it succeeds
1382 * for exactly one.)
1383 *
1384 * Some of the complexity here arises from our desire to mimic the
1385 * Thread vs. VMThread class decomposition we inherited. We've been given
1386 * a Thread, and now we need to create a VMThread and then populate both
1387 * objects. We also need to create one of our internal Thread objects.
1388 *
1389 * Pass in a stack size of 0 to get the default.
Andy McFaddene3346d82010-06-02 15:37:21 -07001390 *
1391 * The "threadObj" reference must be pinned by the caller to prevent the GC
1392 * from moving it around (e.g. added to the tracked allocation list).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001393 */
1394bool dvmCreateInterpThread(Object* threadObj, int reqStackSize)
1395{
1396 pthread_attr_t threadAttr;
1397 pthread_t threadHandle;
1398 Thread* self;
1399 Thread* newThread = NULL;
1400 Object* vmThreadObj = NULL;
1401 int stackSize;
1402
1403 assert(threadObj != NULL);
1404
1405 if(gDvm.zygote) {
Bob Lee9dc72a32009-09-04 18:28:16 -07001406 // Allow the sampling profiler thread. We shut it down before forking.
1407 StringObject* nameStr = (StringObject*) dvmGetFieldObject(threadObj,
1408 gDvm.offJavaLangThread_name);
1409 char* threadName = dvmCreateCstrFromString(nameStr);
1410 bool profilerThread = strcmp(threadName, "SamplingProfiler") == 0;
1411 free(threadName);
1412 if (!profilerThread) {
1413 dvmThrowException("Ljava/lang/IllegalStateException;",
1414 "No new threads in -Xzygote mode");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001415
Bob Lee9dc72a32009-09-04 18:28:16 -07001416 goto fail;
1417 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001418 }
1419
1420 self = dvmThreadSelf();
1421 if (reqStackSize == 0)
1422 stackSize = gDvm.stackSize;
1423 else if (reqStackSize < kMinStackSize)
1424 stackSize = kMinStackSize;
1425 else if (reqStackSize > kMaxStackSize)
1426 stackSize = kMaxStackSize;
1427 else
1428 stackSize = reqStackSize;
1429
1430 pthread_attr_init(&threadAttr);
1431 pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1432
1433 /*
1434 * To minimize the time spent in the critical section, we allocate the
1435 * vmThread object here.
1436 */
1437 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
1438 if (vmThreadObj == NULL)
1439 goto fail;
1440
1441 newThread = allocThread(stackSize);
1442 if (newThread == NULL)
1443 goto fail;
1444 newThread->threadObj = threadObj;
1445
1446 assert(newThread->status == THREAD_INITIALIZING);
1447
1448 /*
1449 * We need to lock out other threads while we test and set the
1450 * "vmThread" field in java.lang.Thread, because we use that to determine
1451 * if this thread has been started before. We use the thread list lock
1452 * because it's handy and we're going to need to grab it again soon
1453 * anyway.
1454 */
1455 dvmLockThreadList(self);
1456
1457 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
1458 dvmUnlockThreadList();
1459 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
1460 "thread has already been started");
1461 goto fail;
1462 }
1463
1464 /*
1465 * There are actually three data structures: Thread (object), VMThread
1466 * (object), and Thread (C struct). All of them point to at least one
1467 * other.
1468 *
1469 * As soon as "VMThread.vmData" is assigned, other threads can start
1470 * making calls into us (e.g. setPriority).
1471 */
1472 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)newThread);
1473 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
1474
1475 /*
1476 * Thread creation might take a while, so release the lock.
1477 */
1478 dvmUnlockThreadList();
1479
Carl Shapiro5617ad32010-07-02 10:50:57 -07001480 ThreadStatus oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
1481 int cc = pthread_create(&threadHandle, &threadAttr, interpThreadStart,
Andy McFadden2aa43612009-06-17 16:29:30 -07001482 newThread);
1483 oldStatus = dvmChangeStatus(self, oldStatus);
1484
1485 if (cc != 0) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001486 /*
1487 * Failure generally indicates that we have exceeded system
1488 * resource limits. VirtualMachineError is probably too severe,
1489 * so use OutOfMemoryError.
1490 */
1491 LOGE("Thread creation failed (err=%s)\n", strerror(errno));
1492
1493 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, NULL);
1494
1495 dvmThrowException("Ljava/lang/OutOfMemoryError;",
1496 "thread creation failed");
1497 goto fail;
1498 }
1499
1500 /*
1501 * We need to wait for the thread to start. Otherwise, depending on
1502 * the whims of the OS scheduler, we could return and the code in our
1503 * thread could try to do operations on the new thread before it had
1504 * finished starting.
1505 *
1506 * The new thread will lock the thread list, change its state to
1507 * THREAD_STARTING, broadcast to gDvm.threadStartCond, and then sleep
1508 * on gDvm.threadStartCond (which uses the thread list lock). This
1509 * thread (the parent) will either see that the thread is already ready
1510 * after we grab the thread list lock, or will be awakened from the
1511 * condition variable on the broadcast.
1512 *
1513 * We don't want to stall the rest of the VM while the new thread
1514 * starts, which can happen if the GC wakes up at the wrong moment.
1515 * So, we change our own status to VMWAIT, and self-suspend if
1516 * necessary after we finish adding the new thread.
1517 *
1518 *
1519 * We have to deal with an odd race with the GC/debugger suspension
1520 * mechanism when creating a new thread. The information about whether
1521 * or not a thread should be suspended is contained entirely within
1522 * the Thread struct; this is usually cleaner to deal with than having
1523 * one or more globally-visible suspension flags. The trouble is that
1524 * we could create the thread while the VM is trying to suspend all
1525 * threads. The suspend-count won't be nonzero for the new thread,
1526 * so dvmChangeStatus(THREAD_RUNNING) won't cause a suspension.
1527 *
1528 * The easiest way to deal with this is to prevent the new thread from
1529 * running until the parent says it's okay. This results in the
Andy McFadden2aa43612009-06-17 16:29:30 -07001530 * following (correct) sequence of events for a "badly timed" GC
1531 * (where '-' is us, 'o' is the child, and '+' is some other thread):
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001532 *
1533 * - call pthread_create()
1534 * - lock thread list
1535 * - put self into THREAD_VMWAIT so GC doesn't wait for us
1536 * - sleep on condition var (mutex = thread list lock) until child starts
1537 * + GC triggered by another thread
1538 * + thread list locked; suspend counts updated; thread list unlocked
1539 * + loop waiting for all runnable threads to suspend
1540 * + success, start GC
1541 * o child thread wakes, signals condition var to wake parent
1542 * o child waits for parent ack on condition variable
1543 * - we wake up, locking thread list
1544 * - add child to thread list
1545 * - unlock thread list
1546 * - change our state back to THREAD_RUNNING; GC causes us to suspend
1547 * + GC finishes; all threads in thread list are resumed
1548 * - lock thread list
1549 * - set child to THREAD_VMWAIT, and signal it to start
1550 * - unlock thread list
1551 * o child resumes
1552 * o child changes state to THREAD_RUNNING
1553 *
1554 * The above shows the GC starting up during thread creation, but if
1555 * it starts anywhere after VMThread.create() is called it will
1556 * produce the same series of events.
1557 *
1558 * Once the child is in the thread list, it will be suspended and
1559 * resumed like any other thread. In the above scenario the resume-all
1560 * code will try to resume the new thread, which was never actually
1561 * suspended, and try to decrement the child's thread suspend count to -1.
1562 * We can catch this in the resume-all code.
1563 *
1564 * Bouncing back and forth between threads like this adds a small amount
1565 * of scheduler overhead to thread startup.
1566 *
1567 * One alternative to having the child wait for the parent would be
1568 * to have the child inherit the parents' suspension count. This
1569 * would work for a GC, since we can safely assume that the parent
1570 * thread didn't cause it, but we must only do so if the parent suspension
1571 * was caused by a suspend-all. If the parent was being asked to
1572 * suspend singly by the debugger, the child should not inherit the value.
1573 *
1574 * We could also have a global "new thread suspend count" that gets
1575 * picked up by new threads before changing state to THREAD_RUNNING.
1576 * This would be protected by the thread list lock and set by a
1577 * suspend-all.
1578 */
1579 dvmLockThreadList(self);
1580 assert(self->status == THREAD_RUNNING);
1581 self->status = THREAD_VMWAIT;
1582 while (newThread->status != THREAD_STARTING)
1583 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1584
1585 LOG_THREAD("threadid=%d: adding to list\n", newThread->threadId);
1586 newThread->next = gDvm.threadList->next;
1587 if (newThread->next != NULL)
1588 newThread->next->prev = newThread;
1589 newThread->prev = gDvm.threadList;
1590 gDvm.threadList->next = newThread;
1591
1592 if (!dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon))
1593 gDvm.nonDaemonThreadCount++; // guarded by thread list lock
1594
1595 dvmUnlockThreadList();
1596
1597 /* change status back to RUNNING, self-suspending if necessary */
1598 dvmChangeStatus(self, THREAD_RUNNING);
1599
1600 /*
1601 * Tell the new thread to start.
1602 *
1603 * We must hold the thread list lock before messing with another thread.
1604 * In the general case we would also need to verify that newThread was
1605 * still in the thread list, but in our case the thread has not started
1606 * executing user code and therefore has not had a chance to exit.
1607 *
1608 * We move it to VMWAIT, and it then shifts itself to RUNNING, which
1609 * comes with a suspend-pending check.
1610 */
1611 dvmLockThreadList(self);
1612
1613 assert(newThread->status == THREAD_STARTING);
1614 newThread->status = THREAD_VMWAIT;
1615 pthread_cond_broadcast(&gDvm.threadStartCond);
1616
1617 dvmUnlockThreadList();
1618
1619 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1620 return true;
1621
1622fail:
1623 freeThread(newThread);
1624 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1625 return false;
1626}
1627
1628/*
1629 * pthread entry function for threads started from interpreted code.
1630 */
1631static void* interpThreadStart(void* arg)
1632{
1633 Thread* self = (Thread*) arg;
1634
1635 char *threadName = dvmGetThreadName(self);
1636 setThreadName(threadName);
1637 free(threadName);
1638
1639 /*
1640 * Finish initializing the Thread struct.
1641 */
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07001642 dvmLockThreadList(self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001643 prepareThread(self);
1644
1645 LOG_THREAD("threadid=%d: created from interp\n", self->threadId);
1646
1647 /*
1648 * Change our status and wake our parent, who will add us to the
1649 * thread list and advance our state to VMWAIT.
1650 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001651 self->status = THREAD_STARTING;
1652 pthread_cond_broadcast(&gDvm.threadStartCond);
1653
1654 /*
1655 * Wait until the parent says we can go. Assuming there wasn't a
1656 * suspend pending, this will happen immediately. When it completes,
1657 * we're full-fledged citizens of the VM.
1658 *
1659 * We have to use THREAD_VMWAIT here rather than THREAD_RUNNING
1660 * because the pthread_cond_wait below needs to reacquire a lock that
1661 * suspend-all is also interested in. If we get unlucky, the parent could
1662 * change us to THREAD_RUNNING, then a GC could start before we get
1663 * signaled, and suspend-all will grab the thread list lock and then
1664 * wait for us to suspend. We'll be in the tail end of pthread_cond_wait
1665 * trying to get the lock.
1666 */
1667 while (self->status != THREAD_VMWAIT)
1668 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1669
1670 dvmUnlockThreadList();
1671
1672 /*
1673 * Add a JNI context.
1674 */
1675 self->jniEnv = dvmCreateJNIEnv(self);
1676
1677 /*
1678 * Change our state so the GC will wait for us from now on. If a GC is
1679 * in progress this call will suspend us.
1680 */
1681 dvmChangeStatus(self, THREAD_RUNNING);
1682
1683 /*
1684 * Notify the debugger & DDM. The debugger notification may cause
1685 * us to suspend ourselves (and others).
1686 */
1687 if (gDvm.debuggerConnected)
1688 dvmDbgPostThreadStart(self);
1689
1690 /*
1691 * Set the system thread priority according to the Thread object's
1692 * priority level. We don't usually need to do this, because both the
1693 * Thread object and system thread priorities inherit from parents. The
1694 * tricky case is when somebody creates a Thread object, calls
1695 * setPriority(), and then starts the thread. We could manage this with
1696 * a "needs priority update" flag to avoid the redundant call.
1697 */
Andy McFadden4879df92009-08-07 14:49:40 -07001698 int priority = dvmGetFieldInt(self->threadObj,
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001699 gDvm.offJavaLangThread_priority);
1700 dvmChangeThreadPriority(self, priority);
1701
1702 /*
1703 * Execute the "run" method.
1704 *
1705 * At this point our stack is empty, so somebody who comes looking for
1706 * stack traces right now won't have much to look at. This is normal.
1707 */
1708 Method* run = self->threadObj->clazz->vtable[gDvm.voffJavaLangThread_run];
1709 JValue unused;
1710
1711 LOGV("threadid=%d: calling run()\n", self->threadId);
1712 assert(strcmp(run->name, "run") == 0);
1713 dvmCallMethod(self, run, self->threadObj, &unused);
1714 LOGV("threadid=%d: exiting\n", self->threadId);
1715
1716 /*
1717 * Remove the thread from various lists, report its death, and free
1718 * its resources.
1719 */
1720 dvmDetachCurrentThread();
1721
1722 return NULL;
1723}
1724
1725/*
1726 * The current thread is exiting with an uncaught exception. The
1727 * Java programming language allows the application to provide a
1728 * thread-exit-uncaught-exception handler for the VM, for a specific
1729 * Thread, and for all threads in a ThreadGroup.
1730 *
1731 * Version 1.5 added the per-thread handler. We need to call
1732 * "uncaughtException" in the handler object, which is either the
1733 * ThreadGroup object or the Thread-specific handler.
1734 */
1735static void threadExitUncaughtException(Thread* self, Object* group)
1736{
1737 Object* exception;
1738 Object* handlerObj;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001739 Method* uncaughtHandler = NULL;
1740 InstField* threadHandler;
1741
1742 LOGW("threadid=%d: thread exiting with uncaught exception (group=%p)\n",
1743 self->threadId, group);
1744 assert(group != NULL);
1745
1746 /*
1747 * Get a pointer to the exception, then clear out the one in the
1748 * thread. We don't want to have it set when executing interpreted code.
1749 */
1750 exception = dvmGetException(self);
1751 dvmAddTrackedAlloc(exception, self);
1752 dvmClearException(self);
1753
1754 /*
1755 * Get the Thread's "uncaughtHandler" object. Use it if non-NULL;
1756 * else use "group" (which is an instance of UncaughtExceptionHandler).
1757 */
1758 threadHandler = dvmFindInstanceField(gDvm.classJavaLangThread,
1759 "uncaughtHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;");
1760 if (threadHandler == NULL) {
1761 LOGW("WARNING: no 'uncaughtHandler' field in java/lang/Thread\n");
1762 goto bail;
1763 }
1764 handlerObj = dvmGetFieldObject(self->threadObj, threadHandler->byteOffset);
1765 if (handlerObj == NULL)
1766 handlerObj = group;
1767
1768 /*
1769 * Find the "uncaughtHandler" field in this object.
1770 */
1771 uncaughtHandler = dvmFindVirtualMethodHierByDescriptor(handlerObj->clazz,
1772 "uncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
1773
1774 if (uncaughtHandler != NULL) {
1775 //LOGI("+++ calling %s.uncaughtException\n",
1776 // handlerObj->clazz->descriptor);
1777 JValue unused;
1778 dvmCallMethod(self, uncaughtHandler, handlerObj, &unused,
1779 self->threadObj, exception);
1780 } else {
1781 /* restore it and dump a stack trace */
1782 LOGW("WARNING: no 'uncaughtException' method in class %s\n",
1783 handlerObj->clazz->descriptor);
1784 dvmSetException(self, exception);
1785 dvmLogExceptionStackTrace();
1786 }
1787
1788bail:
Bill Buzbee46cd5b62009-06-05 15:36:06 -07001789#if defined(WITH_JIT)
1790 /* Remove this thread's suspendCount from global suspendCount sum */
1791 lockThreadSuspendCount();
1792 dvmAddToThreadSuspendCount(&self->suspendCount, -self->suspendCount);
1793 unlockThreadSuspendCount();
1794#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001795 dvmReleaseTrackedAlloc(exception, self);
1796}
1797
1798
1799/*
1800 * Create an internal VM thread, for things like JDWP and finalizers.
1801 *
1802 * The easiest way to do this is create a new thread and then use the
1803 * JNI AttachCurrentThread implementation.
1804 *
1805 * This does not return until after the new thread has begun executing.
1806 */
1807bool dvmCreateInternalThread(pthread_t* pHandle, const char* name,
1808 InternalThreadStart func, void* funcArg)
1809{
1810 InternalStartArgs* pArgs;
1811 Object* systemGroup;
1812 pthread_attr_t threadAttr;
1813 volatile Thread* newThread = NULL;
1814 volatile int createStatus = 0;
1815
1816 systemGroup = dvmGetSystemThreadGroup();
1817 if (systemGroup == NULL)
1818 return false;
1819
1820 pArgs = (InternalStartArgs*) malloc(sizeof(*pArgs));
1821 pArgs->func = func;
1822 pArgs->funcArg = funcArg;
1823 pArgs->name = strdup(name); // storage will be owned by new thread
1824 pArgs->group = systemGroup;
1825 pArgs->isDaemon = true;
1826 pArgs->pThread = &newThread;
1827 pArgs->pCreateStatus = &createStatus;
1828
1829 pthread_attr_init(&threadAttr);
1830 //pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1831
1832 if (pthread_create(pHandle, &threadAttr, internalThreadStart,
1833 pArgs) != 0)
1834 {
1835 LOGE("internal thread creation failed\n");
1836 free(pArgs->name);
1837 free(pArgs);
1838 return false;
1839 }
1840
1841 /*
1842 * Wait for the child to start. This gives us an opportunity to make
1843 * sure that the thread started correctly, and allows our caller to
1844 * assume that the thread has started running.
1845 *
1846 * Because we aren't holding a lock across the thread creation, it's
1847 * possible that the child will already have completed its
1848 * initialization. Because the child only adjusts "createStatus" while
1849 * holding the thread list lock, the initial condition on the "while"
1850 * loop will correctly avoid the wait if this occurs.
1851 *
1852 * It's also possible that we'll have to wait for the thread to finish
1853 * being created, and as part of allocating a Thread object it might
1854 * need to initiate a GC. We switch to VMWAIT while we pause.
1855 */
1856 Thread* self = dvmThreadSelf();
Carl Shapiro5617ad32010-07-02 10:50:57 -07001857 ThreadStatus oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001858 dvmLockThreadList(self);
1859 while (createStatus == 0)
1860 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1861
1862 if (newThread == NULL) {
1863 LOGW("internal thread create failed (createStatus=%d)\n", createStatus);
1864 assert(createStatus < 0);
1865 /* don't free pArgs -- if pthread_create succeeded, child owns it */
1866 dvmUnlockThreadList();
1867 dvmChangeStatus(self, oldStatus);
1868 return false;
1869 }
1870
1871 /* thread could be in any state now (except early init states) */
1872 //assert(newThread->status == THREAD_RUNNING);
1873
1874 dvmUnlockThreadList();
1875 dvmChangeStatus(self, oldStatus);
1876
1877 return true;
1878}
1879
1880/*
1881 * pthread entry function for internally-created threads.
1882 *
1883 * We are expected to free "arg" and its contents. If we're a daemon
1884 * thread, and we get cancelled abruptly when the VM shuts down, the
1885 * storage won't be freed. If this becomes a concern we can make a copy
1886 * on the stack.
1887 */
1888static void* internalThreadStart(void* arg)
1889{
1890 InternalStartArgs* pArgs = (InternalStartArgs*) arg;
1891 JavaVMAttachArgs jniArgs;
1892
1893 jniArgs.version = JNI_VERSION_1_2;
1894 jniArgs.name = pArgs->name;
1895 jniArgs.group = pArgs->group;
1896
1897 setThreadName(pArgs->name);
1898
1899 /* use local jniArgs as stack top */
1900 if (dvmAttachCurrentThread(&jniArgs, pArgs->isDaemon)) {
1901 /*
1902 * Tell the parent of our success.
1903 *
1904 * threadListLock is the mutex for threadStartCond.
1905 */
1906 dvmLockThreadList(dvmThreadSelf());
1907 *pArgs->pCreateStatus = 1;
1908 *pArgs->pThread = dvmThreadSelf();
1909 pthread_cond_broadcast(&gDvm.threadStartCond);
1910 dvmUnlockThreadList();
1911
1912 LOG_THREAD("threadid=%d: internal '%s'\n",
1913 dvmThreadSelf()->threadId, pArgs->name);
1914
1915 /* execute */
1916 (*pArgs->func)(pArgs->funcArg);
1917
1918 /* detach ourselves */
1919 dvmDetachCurrentThread();
1920 } else {
1921 /*
1922 * Tell the parent of our failure. We don't have a Thread struct,
1923 * so we can't be suspended, so we don't need to enter a critical
1924 * section.
1925 */
1926 dvmLockThreadList(dvmThreadSelf());
1927 *pArgs->pCreateStatus = -1;
1928 assert(*pArgs->pThread == NULL);
1929 pthread_cond_broadcast(&gDvm.threadStartCond);
1930 dvmUnlockThreadList();
1931
1932 assert(*pArgs->pThread == NULL);
1933 }
1934
1935 free(pArgs->name);
1936 free(pArgs);
1937 return NULL;
1938}
1939
1940/*
1941 * Attach the current thread to the VM.
1942 *
1943 * Used for internally-created threads and JNI's AttachCurrentThread.
1944 */
1945bool dvmAttachCurrentThread(const JavaVMAttachArgs* pArgs, bool isDaemon)
1946{
1947 Thread* self = NULL;
1948 Object* threadObj = NULL;
1949 Object* vmThreadObj = NULL;
1950 StringObject* threadNameStr = NULL;
1951 Method* init;
1952 bool ok, ret;
1953
Andy McFaddene3346d82010-06-02 15:37:21 -07001954 /* allocate thread struct, and establish a basic sense of self */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001955 self = allocThread(gDvm.stackSize);
1956 if (self == NULL)
1957 goto fail;
1958 setThreadSelf(self);
1959
1960 /*
Andy McFaddene3346d82010-06-02 15:37:21 -07001961 * Finish our thread prep. We need to do this before adding ourselves
1962 * to the thread list or invoking any interpreted code. prepareThread()
1963 * requires that we hold the thread list lock.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001964 */
1965 dvmLockThreadList(self);
1966 ok = prepareThread(self);
1967 dvmUnlockThreadList();
1968 if (!ok)
1969 goto fail;
1970
1971 self->jniEnv = dvmCreateJNIEnv(self);
1972 if (self->jniEnv == NULL)
1973 goto fail;
1974
1975 /*
1976 * Create a "fake" JNI frame at the top of the main thread interp stack.
1977 * It isn't really necessary for the internal threads, but it gives
1978 * the debugger something to show. It is essential for the JNI-attached
1979 * threads.
1980 */
1981 if (!createFakeRunFrame(self))
1982 goto fail;
1983
1984 /*
Andy McFaddene3346d82010-06-02 15:37:21 -07001985 * The native side of the thread is ready; add it to the list. Once
1986 * it's on the list the thread is visible to the JDWP code and the GC.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001987 */
1988 LOG_THREAD("threadid=%d: adding to list (attached)\n", self->threadId);
1989
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001990 dvmLockThreadList(self);
1991
1992 self->next = gDvm.threadList->next;
1993 if (self->next != NULL)
1994 self->next->prev = self;
1995 self->prev = gDvm.threadList;
1996 gDvm.threadList->next = self;
1997 if (!isDaemon)
1998 gDvm.nonDaemonThreadCount++;
1999
2000 dvmUnlockThreadList();
2001
2002 /*
Andy McFaddene3346d82010-06-02 15:37:21 -07002003 * Switch state from initializing to running.
2004 *
2005 * It's possible that a GC began right before we added ourselves
2006 * to the thread list, and is still going. That means our thread
2007 * suspend count won't reflect the fact that we should be suspended.
2008 * To deal with this, we transition to VMWAIT, pulse the heap lock,
2009 * and then advance to RUNNING. That will ensure that we stall until
2010 * the GC completes.
2011 *
2012 * Once we're in RUNNING, we're like any other thread in the VM (except
2013 * for the lack of an initialized threadObj). We're then free to
2014 * allocate and initialize objects.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002015 */
Andy McFaddene3346d82010-06-02 15:37:21 -07002016 assert(self->status == THREAD_INITIALIZING);
2017 dvmChangeStatus(self, THREAD_VMWAIT);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002018 dvmLockMutex(&gDvm.gcHeapLock);
2019 dvmUnlockMutex(&gDvm.gcHeapLock);
Andy McFaddene3346d82010-06-02 15:37:21 -07002020 dvmChangeStatus(self, THREAD_RUNNING);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002021
2022 /*
Andy McFaddene3346d82010-06-02 15:37:21 -07002023 * Create Thread and VMThread objects.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002024 */
Andy McFaddene3346d82010-06-02 15:37:21 -07002025 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_DEFAULT);
2026 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
2027 if (threadObj == NULL || vmThreadObj == NULL)
2028 goto fail_unlink;
2029
2030 /*
2031 * This makes threadObj visible to the GC. We still have it in the
2032 * tracked allocation table, so it can't move around on us.
2033 */
2034 self->threadObj = threadObj;
2035 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)self);
2036
2037 /*
2038 * Create a string for the thread name.
2039 */
2040 if (pArgs->name != NULL) {
Barry Hayes81f3ebe2010-06-15 16:17:37 -07002041 threadNameStr = dvmCreateStringFromCstr(pArgs->name);
Andy McFaddene3346d82010-06-02 15:37:21 -07002042 if (threadNameStr == NULL) {
2043 assert(dvmCheckException(dvmThreadSelf()));
2044 goto fail_unlink;
2045 }
2046 }
2047
2048 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
2049 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
2050 if (init == NULL) {
2051 assert(dvmCheckException(self));
2052 goto fail_unlink;
2053 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002054
2055 /*
2056 * Now we're ready to run some interpreted code.
2057 *
2058 * We need to construct the Thread object and set the VMThread field.
2059 * Setting VMThread tells interpreted code that we're alive.
2060 *
2061 * Call the (group, name, priority, daemon) constructor on the Thread.
2062 * This sets the thread's name and adds it to the specified group, and
2063 * provides values for priority and daemon (which are normally inherited
2064 * from the current thread).
2065 */
2066 JValue unused;
2067 dvmCallMethod(self, init, threadObj, &unused, (Object*)pArgs->group,
2068 threadNameStr, getThreadPriorityFromSystem(), isDaemon);
2069 if (dvmCheckException(self)) {
2070 LOGE("exception thrown while constructing attached thread object\n");
2071 goto fail_unlink;
2072 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002073
2074 /*
2075 * Set the VMThread field, which tells interpreted code that we're alive.
2076 *
2077 * The risk of a thread start collision here is very low; somebody
2078 * would have to be deliberately polling the ThreadGroup list and
2079 * trying to start threads against anything it sees, which would
2080 * generally cause problems for all thread creation. However, for
2081 * correctness we test "vmThread" before setting it.
Andy McFaddene3346d82010-06-02 15:37:21 -07002082 *
2083 * TODO: this still has a race, it's just smaller. Not sure this is
2084 * worth putting effort into fixing. Need to hold a lock while
2085 * fiddling with the field, or maybe initialize the Thread object in a
2086 * way that ensures another thread can't call start() on it.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002087 */
2088 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
Andy McFaddene3346d82010-06-02 15:37:21 -07002089 LOGW("WOW: thread start hijack\n");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002090 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
2091 "thread has already been started");
2092 /* We don't want to free anything associated with the thread
2093 * because someone is obviously interested in it. Just let
2094 * it go and hope it will clean itself up when its finished.
2095 * This case should never happen anyway.
2096 *
2097 * Since we're letting it live, we need to finish setting it up.
2098 * We just have to let the caller know that the intended operation
2099 * has failed.
2100 *
2101 * [ This seems strange -- stepping on the vmThread object that's
2102 * already present seems like a bad idea. TODO: figure this out. ]
2103 */
2104 ret = false;
Andy McFaddene3346d82010-06-02 15:37:21 -07002105 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002106 ret = true;
Andy McFaddene3346d82010-06-02 15:37:21 -07002107 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002108 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
2109
Andy McFaddene3346d82010-06-02 15:37:21 -07002110 /* we can now safely un-pin these */
2111 dvmReleaseTrackedAlloc(threadObj, self);
2112 dvmReleaseTrackedAlloc(vmThreadObj, self);
2113 dvmReleaseTrackedAlloc((Object*)threadNameStr, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002114
2115 LOG_THREAD("threadid=%d: attached from native, name=%s\n",
2116 self->threadId, pArgs->name);
2117
2118 /* tell the debugger & DDM */
2119 if (gDvm.debuggerConnected)
2120 dvmDbgPostThreadStart(self);
2121
2122 return ret;
2123
2124fail_unlink:
2125 dvmLockThreadList(self);
2126 unlinkThread(self);
2127 if (!isDaemon)
2128 gDvm.nonDaemonThreadCount--;
2129 dvmUnlockThreadList();
2130 /* fall through to "fail" */
2131fail:
Andy McFaddene3346d82010-06-02 15:37:21 -07002132 dvmReleaseTrackedAlloc(threadObj, self);
2133 dvmReleaseTrackedAlloc(vmThreadObj, self);
2134 dvmReleaseTrackedAlloc((Object*)threadNameStr, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002135 if (self != NULL) {
2136 if (self->jniEnv != NULL) {
2137 dvmDestroyJNIEnv(self->jniEnv);
2138 self->jniEnv = NULL;
2139 }
2140 freeThread(self);
2141 }
2142 setThreadSelf(NULL);
2143 return false;
2144}
2145
2146/*
2147 * Detach the thread from the various data structures, notify other threads
2148 * that are waiting to "join" it, and free up all heap-allocated storage.
2149 *
2150 * Used for all threads.
2151 *
2152 * When we get here the interpreted stack should be empty. The JNI 1.6 spec
2153 * requires us to enforce this for the DetachCurrentThread call, probably
2154 * because it also says that DetachCurrentThread causes all monitors
2155 * associated with the thread to be released. (Because the stack is empty,
2156 * we only have to worry about explicit JNI calls to MonitorEnter.)
2157 *
2158 * THOUGHT:
2159 * We might want to avoid freeing our internal Thread structure until the
2160 * associated Thread/VMThread objects get GCed. Our Thread is impossible to
2161 * get to once the thread shuts down, but there is a small possibility of
2162 * an operation starting in another thread before this thread halts, and
2163 * finishing much later (perhaps the thread got stalled by a weird OS bug).
2164 * We don't want something like Thread.isInterrupted() crawling through
2165 * freed storage. Can do with a Thread finalizer, or by creating a
2166 * dedicated ThreadObject class for java/lang/Thread and moving all of our
2167 * state into that.
2168 */
2169void dvmDetachCurrentThread(void)
2170{
2171 Thread* self = dvmThreadSelf();
2172 Object* vmThread;
2173 Object* group;
2174
2175 /*
2176 * Make sure we're not detaching a thread that's still running. (This
2177 * could happen with an explicit JNI detach call.)
2178 *
2179 * A thread created by interpreted code will finish with a depth of
2180 * zero, while a JNI-attached thread will have the synthetic "stack
2181 * starter" native method at the top.
2182 */
2183 int curDepth = dvmComputeExactFrameDepth(self->curFrame);
2184 if (curDepth != 0) {
2185 bool topIsNative = false;
2186
2187 if (curDepth == 1) {
2188 /* not expecting a lingering break frame; just look at curFrame */
2189 assert(!dvmIsBreakFrame(self->curFrame));
2190 StackSaveArea* ssa = SAVEAREA_FROM_FP(self->curFrame);
2191 if (dvmIsNativeMethod(ssa->method))
2192 topIsNative = true;
2193 }
2194
2195 if (!topIsNative) {
2196 LOGE("ERROR: detaching thread with interp frames (count=%d)\n",
2197 curDepth);
2198 dvmDumpThread(self, false);
2199 dvmAbort();
2200 }
2201 }
2202
2203 group = dvmGetFieldObject(self->threadObj, gDvm.offJavaLangThread_group);
2204 LOG_THREAD("threadid=%d: detach (group=%p)\n", self->threadId, group);
2205
2206 /*
2207 * Release any held monitors. Since there are no interpreted stack
2208 * frames, the only thing left are the monitors held by JNI MonitorEnter
2209 * calls.
2210 */
2211 dvmReleaseJniMonitors(self);
2212
2213 /*
2214 * Do some thread-exit uncaught exception processing if necessary.
2215 */
2216 if (dvmCheckException(self))
2217 threadExitUncaughtException(self, group);
2218
2219 /*
2220 * Remove the thread from the thread group.
2221 */
2222 if (group != NULL) {
2223 Method* removeThread =
2224 group->clazz->vtable[gDvm.voffJavaLangThreadGroup_removeThread];
2225 JValue unused;
2226 dvmCallMethod(self, removeThread, group, &unused, self->threadObj);
2227 }
2228
2229 /*
2230 * Clear the vmThread reference in the Thread object. Interpreted code
2231 * will now see that this Thread is not running. As this may be the
2232 * only reference to the VMThread object that the VM knows about, we
2233 * have to create an internal reference to it first.
2234 */
2235 vmThread = dvmGetFieldObject(self->threadObj,
2236 gDvm.offJavaLangThread_vmThread);
2237 dvmAddTrackedAlloc(vmThread, self);
2238 dvmSetFieldObject(self->threadObj, gDvm.offJavaLangThread_vmThread, NULL);
2239
2240 /* clear out our struct Thread pointer, since it's going away */
2241 dvmSetFieldObject(vmThread, gDvm.offJavaLangVMThread_vmData, NULL);
2242
2243 /*
2244 * Tell the debugger & DDM. This may cause the current thread or all
2245 * threads to suspend.
2246 *
2247 * The JDWP spec is somewhat vague about when this happens, other than
2248 * that it's issued by the dying thread, which may still appear in
2249 * an "all threads" listing.
2250 */
2251 if (gDvm.debuggerConnected)
2252 dvmDbgPostThreadDeath(self);
2253
2254 /*
2255 * Thread.join() is implemented as an Object.wait() on the VMThread
2256 * object. Signal anyone who is waiting.
2257 */
2258 dvmLockObject(self, vmThread);
2259 dvmObjectNotifyAll(self, vmThread);
2260 dvmUnlockObject(self, vmThread);
2261
2262 dvmReleaseTrackedAlloc(vmThread, self);
2263 vmThread = NULL;
2264
2265 /*
2266 * We're done manipulating objects, so it's okay if the GC runs in
2267 * parallel with us from here out. It's important to do this if
2268 * profiling is enabled, since we can wait indefinitely.
2269 */
Andy McFadden3469a7e2010-08-04 16:09:10 -07002270 android_atomic_release_store(THREAD_VMWAIT, &self->status);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002271
2272#ifdef WITH_PROFILER
2273 /*
2274 * If we're doing method trace profiling, we don't want threads to exit,
2275 * because if they do we'll end up reusing thread IDs. This complicates
2276 * analysis and makes it impossible to have reasonable output in the
2277 * "threads" section of the "key" file.
2278 *
2279 * We need to do this after Thread.join() completes, or other threads
2280 * could get wedged. Since self->threadObj is still valid, the Thread
2281 * object will not get GCed even though we're no longer in the ThreadGroup
2282 * list (which is important since the profiling thread needs to get
2283 * the thread's name).
2284 */
2285 MethodTraceState* traceState = &gDvm.methodTrace;
2286
2287 dvmLockMutex(&traceState->startStopLock);
2288 if (traceState->traceEnabled) {
2289 LOGI("threadid=%d: waiting for method trace to finish\n",
2290 self->threadId);
2291 while (traceState->traceEnabled) {
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07002292 dvmWaitCond(&traceState->threadExitCond,
2293 &traceState->startStopLock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002294 }
2295 }
2296 dvmUnlockMutex(&traceState->startStopLock);
2297#endif
2298
2299 dvmLockThreadList(self);
2300
2301 /*
2302 * Lose the JNI context.
2303 */
2304 dvmDestroyJNIEnv(self->jniEnv);
2305 self->jniEnv = NULL;
2306
2307 self->status = THREAD_ZOMBIE;
2308
2309 /*
2310 * Remove ourselves from the internal thread list.
2311 */
2312 unlinkThread(self);
2313
2314 /*
2315 * If we're the last one standing, signal anybody waiting in
2316 * DestroyJavaVM that it's okay to exit.
2317 */
2318 if (!dvmGetFieldBoolean(self->threadObj, gDvm.offJavaLangThread_daemon)) {
2319 gDvm.nonDaemonThreadCount--; // guarded by thread list lock
2320
2321 if (gDvm.nonDaemonThreadCount == 0) {
2322 int cc;
2323
2324 LOGV("threadid=%d: last non-daemon thread\n", self->threadId);
2325 //dvmDumpAllThreads(false);
2326 // cond var guarded by threadListLock, which we already hold
2327 cc = pthread_cond_signal(&gDvm.vmExitCond);
2328 assert(cc == 0);
2329 }
2330 }
2331
2332 LOGV("threadid=%d: bye!\n", self->threadId);
2333 releaseThreadId(self);
2334 dvmUnlockThreadList();
2335
2336 setThreadSelf(NULL);
Bob Lee9dc72a32009-09-04 18:28:16 -07002337
Bob Lee2fe146a2009-09-10 00:36:29 +02002338 dvmDetachSystemThread(self);
Bob Lee9dc72a32009-09-04 18:28:16 -07002339
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002340 freeThread(self);
2341}
2342
2343
2344/*
2345 * Suspend a single thread. Do not use to suspend yourself.
2346 *
2347 * This is used primarily for debugger/DDMS activity. Does not return
2348 * until the thread has suspended or is in a "safe" state (e.g. executing
2349 * native code outside the VM).
2350 *
2351 * The thread list lock should be held before calling here -- it's not
2352 * entirely safe to hang on to a Thread* from another thread otherwise.
2353 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2354 */
2355void dvmSuspendThread(Thread* thread)
2356{
2357 assert(thread != NULL);
2358 assert(thread != dvmThreadSelf());
2359 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2360
2361 lockThreadSuspendCount();
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002362 dvmAddToThreadSuspendCount(&thread->suspendCount, 1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002363 thread->dbgSuspendCount++;
2364
2365 LOG_THREAD("threadid=%d: suspend++, now=%d\n",
2366 thread->threadId, thread->suspendCount);
2367 unlockThreadSuspendCount();
2368
2369 waitForThreadSuspend(dvmThreadSelf(), thread);
2370}
2371
2372/*
2373 * Reduce the suspend count of a thread. If it hits zero, tell it to
2374 * resume.
2375 *
2376 * Used primarily for debugger/DDMS activity. The thread in question
2377 * might have been suspended singly or as part of a suspend-all operation.
2378 *
2379 * The thread list lock should be held before calling here -- it's not
2380 * entirely safe to hang on to a Thread* from another thread otherwise.
2381 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2382 */
2383void dvmResumeThread(Thread* thread)
2384{
2385 assert(thread != NULL);
2386 assert(thread != dvmThreadSelf());
2387 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2388
2389 lockThreadSuspendCount();
2390 if (thread->suspendCount > 0) {
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002391 dvmAddToThreadSuspendCount(&thread->suspendCount, -1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002392 thread->dbgSuspendCount--;
2393 } else {
2394 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2395 thread->threadId);
2396 }
2397
2398 LOG_THREAD("threadid=%d: suspend--, now=%d\n",
2399 thread->threadId, thread->suspendCount);
2400
2401 if (thread->suspendCount == 0) {
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07002402 dvmBroadcastCond(&gDvm.threadSuspendCountCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002403 }
2404
2405 unlockThreadSuspendCount();
2406}
2407
2408/*
2409 * Suspend yourself, as a result of debugger activity.
2410 */
2411void dvmSuspendSelf(bool jdwpActivity)
2412{
2413 Thread* self = dvmThreadSelf();
2414
2415 /* debugger thread may not suspend itself due to debugger activity! */
2416 assert(gDvm.jdwpState != NULL);
2417 if (self->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2418 assert(false);
2419 return;
2420 }
2421
2422 /*
2423 * Collisions with other suspends aren't really interesting. We want
2424 * to ensure that we're the only one fiddling with the suspend count
2425 * though.
2426 */
2427 lockThreadSuspendCount();
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002428 dvmAddToThreadSuspendCount(&self->suspendCount, 1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002429 self->dbgSuspendCount++;
2430
2431 /*
2432 * Suspend ourselves.
2433 */
2434 assert(self->suspendCount > 0);
2435 self->isSuspended = true;
2436 LOG_THREAD("threadid=%d: self-suspending (dbg)\n", self->threadId);
2437
2438 /*
2439 * Tell JDWP that we've completed suspension. The JDWP thread can't
2440 * tell us to resume before we're fully asleep because we hold the
2441 * suspend count lock.
2442 *
2443 * If we got here via waitForDebugger(), don't do this part.
2444 */
2445 if (jdwpActivity) {
2446 //LOGI("threadid=%d: clearing wait-for-event (my handle=%08x)\n",
2447 // self->threadId, (int) self->handle);
2448 dvmJdwpClearWaitForEventThread(gDvm.jdwpState);
2449 }
2450
2451 while (self->suspendCount != 0) {
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07002452 dvmWaitCond(&gDvm.threadSuspendCountCond,
2453 &gDvm.threadSuspendCountLock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002454 if (self->suspendCount != 0) {
The Android Open Source Project99409882009-03-18 22:20:24 -07002455 /*
2456 * The condition was signaled but we're still suspended. This
2457 * can happen if the debugger lets go while a SIGQUIT thread
2458 * dump event is pending (assuming SignalCatcher was resumed for
2459 * just long enough to try to grab the thread-suspend lock).
2460 */
2461 LOGD("threadid=%d: still suspended after undo (sc=%d dc=%d s=%c)\n",
2462 self->threadId, self->suspendCount, self->dbgSuspendCount,
2463 self->isSuspended ? 'Y' : 'N');
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002464 }
2465 }
2466 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
2467 self->isSuspended = false;
2468 LOG_THREAD("threadid=%d: self-reviving (dbg), status=%d\n",
2469 self->threadId, self->status);
2470
2471 unlockThreadSuspendCount();
2472}
2473
2474
2475#ifdef HAVE_GLIBC
2476# define NUM_FRAMES 20
2477# include <execinfo.h>
2478/*
2479 * glibc-only stack dump function. Requires link with "--export-dynamic".
2480 *
2481 * TODO: move this into libs/cutils and make it work for all platforms.
2482 */
2483static void printBackTrace(void)
2484{
2485 void* array[NUM_FRAMES];
2486 size_t size;
2487 char** strings;
2488 size_t i;
2489
2490 size = backtrace(array, NUM_FRAMES);
2491 strings = backtrace_symbols(array, size);
2492
2493 LOGW("Obtained %zd stack frames.\n", size);
2494
2495 for (i = 0; i < size; i++)
2496 LOGW("%s\n", strings[i]);
2497
2498 free(strings);
2499}
2500#else
2501static void printBackTrace(void) {}
2502#endif
2503
2504/*
2505 * Dump the state of the current thread and that of another thread that
2506 * we think is wedged.
2507 */
2508static void dumpWedgedThread(Thread* thread)
2509{
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002510 dvmDumpThread(dvmThreadSelf(), false);
2511 printBackTrace();
2512
2513 // dumping a running thread is risky, but could be useful
2514 dvmDumpThread(thread, true);
2515
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002516 // stop now and get a core dump
2517 //abort();
2518}
2519
Andy McFaddend2afbcf2010-03-02 14:23:04 -08002520/*
2521 * If the thread is running at below-normal priority, temporarily elevate
2522 * it to "normal".
2523 *
2524 * Returns zero if no changes were made. Otherwise, returns bit flags
2525 * indicating what was changed, storing the previous values in the
2526 * provided locations.
2527 */
Andy McFadden2b94b302010-03-09 16:38:36 -08002528int dvmRaiseThreadPriorityIfNeeded(Thread* thread, int* pSavedThreadPrio,
Andy McFaddend2afbcf2010-03-02 14:23:04 -08002529 SchedPolicy* pSavedThreadPolicy)
2530{
2531 errno = 0;
2532 *pSavedThreadPrio = getpriority(PRIO_PROCESS, thread->systemTid);
2533 if (errno != 0) {
2534 LOGW("Unable to get priority for threadid=%d sysTid=%d\n",
2535 thread->threadId, thread->systemTid);
2536 return 0;
2537 }
2538 if (get_sched_policy(thread->systemTid, pSavedThreadPolicy) != 0) {
2539 LOGW("Unable to get policy for threadid=%d sysTid=%d\n",
2540 thread->threadId, thread->systemTid);
2541 return 0;
2542 }
2543
2544 int changeFlags = 0;
2545
2546 /*
2547 * Change the priority if we're in the background group.
2548 */
2549 if (*pSavedThreadPolicy == SP_BACKGROUND) {
2550 if (set_sched_policy(thread->systemTid, SP_FOREGROUND) != 0) {
2551 LOGW("Couldn't set fg policy on tid %d\n", thread->systemTid);
2552 } else {
2553 changeFlags |= kChangedPolicy;
2554 LOGD("Temporarily moving tid %d to fg (was %d)\n",
2555 thread->systemTid, *pSavedThreadPolicy);
2556 }
2557 }
2558
2559 /*
2560 * getpriority() returns the "nice" value, so larger numbers indicate
2561 * lower priority, with 0 being normal.
2562 */
2563 if (*pSavedThreadPrio > 0) {
2564 const int kHigher = 0;
2565 if (setpriority(PRIO_PROCESS, thread->systemTid, kHigher) != 0) {
2566 LOGW("Couldn't raise priority on tid %d to %d\n",
2567 thread->systemTid, kHigher);
2568 } else {
2569 changeFlags |= kChangedPriority;
2570 LOGD("Temporarily raised priority on tid %d (%d -> %d)\n",
2571 thread->systemTid, *pSavedThreadPrio, kHigher);
2572 }
2573 }
2574
2575 return changeFlags;
2576}
2577
2578/*
2579 * Reset the priority values for the thread in question.
2580 */
Andy McFadden2b94b302010-03-09 16:38:36 -08002581void dvmResetThreadPriority(Thread* thread, int changeFlags,
Andy McFaddend2afbcf2010-03-02 14:23:04 -08002582 int savedThreadPrio, SchedPolicy savedThreadPolicy)
2583{
2584 if ((changeFlags & kChangedPolicy) != 0) {
2585 if (set_sched_policy(thread->systemTid, savedThreadPolicy) != 0) {
2586 LOGW("NOTE: couldn't reset tid %d to (%d)\n",
2587 thread->systemTid, savedThreadPolicy);
2588 } else {
2589 LOGD("Restored policy of %d to %d\n",
2590 thread->systemTid, savedThreadPolicy);
2591 }
2592 }
2593
2594 if ((changeFlags & kChangedPriority) != 0) {
2595 if (setpriority(PRIO_PROCESS, thread->systemTid, savedThreadPrio) != 0)
2596 {
2597 LOGW("NOTE: couldn't reset priority on thread %d to %d\n",
2598 thread->systemTid, savedThreadPrio);
2599 } else {
2600 LOGD("Restored priority on %d to %d\n",
2601 thread->systemTid, savedThreadPrio);
2602 }
2603 }
2604}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002605
2606/*
2607 * Wait for another thread to see the pending suspension and stop running.
2608 * It can either suspend itself or go into a non-running state such as
2609 * VMWAIT or NATIVE in which it cannot interact with the GC.
2610 *
2611 * If we're running at a higher priority, sched_yield() may not do anything,
2612 * so we need to sleep for "long enough" to guarantee that the other
2613 * thread has a chance to finish what it's doing. Sleeping for too short
2614 * a period (e.g. less than the resolution of the sleep clock) might cause
2615 * the scheduler to return immediately, so we want to start with a
2616 * "reasonable" value and expand.
2617 *
2618 * This does not return until the other thread has stopped running.
2619 * Eventually we time out and the VM aborts.
2620 *
2621 * This does not try to detect the situation where two threads are
2622 * waiting for each other to suspend. In normal use this is part of a
2623 * suspend-all, which implies that the suspend-all lock is held, or as
2624 * part of a debugger action in which the JDWP thread is always the one
2625 * doing the suspending. (We may need to re-evaluate this now that
2626 * getThreadStackTrace is implemented as suspend-snapshot-resume.)
2627 *
2628 * TODO: track basic stats about time required to suspend VM.
2629 */
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002630#define FIRST_SLEEP (250*1000) /* 0.25s */
2631#define MORE_SLEEP (750*1000) /* 0.75s */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002632static void waitForThreadSuspend(Thread* self, Thread* thread)
2633{
2634 const int kMaxRetries = 10;
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002635 int spinSleepTime = FIRST_SLEEP;
Andy McFadden2aa43612009-06-17 16:29:30 -07002636 bool complained = false;
Andy McFaddend2afbcf2010-03-02 14:23:04 -08002637 int priChangeFlags = 0;
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002638 int savedThreadPrio = -500;
Andy McFaddend2afbcf2010-03-02 14:23:04 -08002639 SchedPolicy savedThreadPolicy = SP_FOREGROUND;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002640
2641 int sleepIter = 0;
2642 int retryCount = 0;
2643 u8 startWhen = 0; // init req'd to placate gcc
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002644 u8 firstStartWhen = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002645
2646 while (thread->status == THREAD_RUNNING && !thread->isSuspended) {
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002647 if (sleepIter == 0) { // get current time on first iteration
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002648 startWhen = dvmGetRelativeTimeUsec();
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002649 if (firstStartWhen == 0) // first iteration of first attempt
2650 firstStartWhen = startWhen;
2651
2652 /*
2653 * After waiting for a bit, check to see if the target thread is
2654 * running at a reduced priority. If so, bump it up temporarily
2655 * to give it more CPU time.
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002656 */
2657 if (retryCount == 2) {
2658 assert(thread->systemTid != 0);
Andy McFadden2b94b302010-03-09 16:38:36 -08002659 priChangeFlags = dvmRaiseThreadPriorityIfNeeded(thread,
Andy McFaddend2afbcf2010-03-02 14:23:04 -08002660 &savedThreadPrio, &savedThreadPolicy);
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002661 }
2662 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002663
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002664#if defined (WITH_JIT)
2665 /*
Ben Cheng6999d842010-01-26 16:46:15 -08002666 * If we're still waiting after the first timeout, unchain all
2667 * translations iff:
2668 * 1) There are new chains formed since the last unchain
2669 * 2) The top VM frame of the running thread is running JIT'ed code
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002670 */
Ben Cheng6999d842010-01-26 16:46:15 -08002671 if (gDvmJit.pJitEntryTable && retryCount > 0 &&
2672 gDvmJit.hasNewChain && thread->inJitCodeCache) {
Andy McFaddend2afbcf2010-03-02 14:23:04 -08002673 LOGD("JIT unchain all for threadid=%d", thread->threadId);
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002674 dvmJitUnchainAll();
2675 }
2676#endif
2677
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002678 /*
Andy McFadden1ede83b2009-12-02 17:03:41 -08002679 * Sleep briefly. The iterative sleep call returns false if we've
2680 * exceeded the total time limit for this round of sleeping.
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002681 */
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002682 if (!dvmIterativeSleep(sleepIter++, spinSleepTime, startWhen)) {
Andy McFadden1ede83b2009-12-02 17:03:41 -08002683 if (spinSleepTime != FIRST_SLEEP) {
Andy McFaddend2afbcf2010-03-02 14:23:04 -08002684 LOGW("threadid=%d: spin on suspend #%d threadid=%d (pcf=%d)\n",
Andy McFadden1ede83b2009-12-02 17:03:41 -08002685 self->threadId, retryCount,
Andy McFaddend2afbcf2010-03-02 14:23:04 -08002686 thread->threadId, priChangeFlags);
2687 if (retryCount > 1) {
2688 /* stack trace logging is slow; skip on first iter */
2689 dumpWedgedThread(thread);
2690 }
Andy McFadden1ede83b2009-12-02 17:03:41 -08002691 complained = true;
2692 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002693
2694 // keep going; could be slow due to valgrind
2695 sleepIter = 0;
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002696 spinSleepTime = MORE_SLEEP;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002697
2698 if (retryCount++ == kMaxRetries) {
Andy McFadden384ef6b2010-03-15 17:24:55 -07002699 LOGE("Fatal spin-on-suspend, dumping threads\n");
2700 dvmDumpAllThreads(false);
2701
2702 /* log this after -- long traces will scroll off log */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002703 LOGE("threadid=%d: stuck on threadid=%d, giving up\n",
2704 self->threadId, thread->threadId);
Andy McFadden384ef6b2010-03-15 17:24:55 -07002705
2706 /* try to get a debuggerd dump from the spinning thread */
2707 dvmNukeThread(thread);
2708 /* abort the VM */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002709 dvmAbort();
2710 }
2711 }
2712 }
Andy McFadden2aa43612009-06-17 16:29:30 -07002713
2714 if (complained) {
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002715 LOGW("threadid=%d: spin on suspend resolved in %lld msec\n",
2716 self->threadId,
2717 (dvmGetRelativeTimeUsec() - firstStartWhen) / 1000);
Andy McFadden2aa43612009-06-17 16:29:30 -07002718 //dvmDumpThread(thread, false); /* suspended, so dump is safe */
2719 }
Andy McFaddend2afbcf2010-03-02 14:23:04 -08002720 if (priChangeFlags != 0) {
Andy McFadden2b94b302010-03-09 16:38:36 -08002721 dvmResetThreadPriority(thread, priChangeFlags, savedThreadPrio,
Andy McFaddend2afbcf2010-03-02 14:23:04 -08002722 savedThreadPolicy);
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002723 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002724}
2725
2726/*
2727 * Suspend all threads except the current one. This is used by the GC,
2728 * the debugger, and by any thread that hits a "suspend all threads"
2729 * debugger event (e.g. breakpoint or exception).
2730 *
2731 * If thread N hits a "suspend all threads" breakpoint, we don't want it
2732 * to suspend the JDWP thread. For the GC, we do, because the debugger can
2733 * create objects and even execute arbitrary code. The "why" argument
2734 * allows the caller to say why the suspension is taking place.
2735 *
2736 * This can be called when a global suspend has already happened, due to
2737 * various debugger gymnastics, so keeping an "everybody is suspended" flag
2738 * doesn't work.
2739 *
2740 * DO NOT grab any locks before calling here. We grab & release the thread
2741 * lock and suspend lock here (and we're not using recursive threads), and
2742 * we might have to self-suspend if somebody else beats us here.
2743 *
Andy McFaddenc650d2b2010-08-16 16:14:06 -07002744 * We know the current thread is in the thread list, because we attach the
2745 * thread before doing anything that could cause VM suspension (like object
2746 * allocation).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002747 */
2748void dvmSuspendAllThreads(SuspendCause why)
2749{
2750 Thread* self = dvmThreadSelf();
2751 Thread* thread;
2752
2753 assert(why != 0);
2754
2755 /*
2756 * Start by grabbing the thread suspend lock. If we can't get it, most
2757 * likely somebody else is in the process of performing a suspend or
2758 * resume, so lockThreadSuspend() will cause us to self-suspend.
2759 *
2760 * We keep the lock until all other threads are suspended.
2761 */
2762 lockThreadSuspend("susp-all", why);
2763
2764 LOG_THREAD("threadid=%d: SuspendAll starting\n", self->threadId);
2765
2766 /*
2767 * This is possible if the current thread was in VMWAIT mode when a
2768 * suspend-all happened, and then decided to do its own suspend-all.
2769 * This can happen when a couple of threads have simultaneous events
2770 * of interest to the debugger.
2771 */
2772 //assert(self->suspendCount == 0);
2773
2774 /*
2775 * Increment everybody's suspend count (except our own).
2776 */
2777 dvmLockThreadList(self);
2778
2779 lockThreadSuspendCount();
2780 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2781 if (thread == self)
2782 continue;
2783
2784 /* debugger events don't suspend JDWP thread */
2785 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2786 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2787 continue;
2788
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002789 dvmAddToThreadSuspendCount(&thread->suspendCount, 1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002790 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2791 thread->dbgSuspendCount++;
2792 }
2793 unlockThreadSuspendCount();
2794
2795 /*
2796 * Wait for everybody in THREAD_RUNNING state to stop. Other states
2797 * indicate the code is either running natively or sleeping quietly.
2798 * Any attempt to transition back to THREAD_RUNNING will cause a check
2799 * for suspension, so it should be impossible for anything to execute
2800 * interpreted code or modify objects (assuming native code plays nicely).
2801 *
2802 * It's also okay if the thread transitions to a non-RUNNING state.
2803 *
2804 * Note we released the threadSuspendCountLock before getting here,
2805 * so if another thread is fiddling with its suspend count (perhaps
2806 * self-suspending for the debugger) it won't block while we're waiting
2807 * in here.
2808 */
2809 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2810 if (thread == self)
2811 continue;
2812
2813 /* debugger events don't suspend JDWP thread */
2814 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2815 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2816 continue;
2817
2818 /* wait for the other thread to see the pending suspend */
2819 waitForThreadSuspend(self, thread);
2820
Jeff Hao97319a82009-08-12 16:57:15 -07002821 LOG_THREAD("threadid=%d: threadid=%d status=%d c=%d dc=%d isSusp=%d\n",
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002822 self->threadId,
2823 thread->threadId, thread->status, thread->suspendCount,
2824 thread->dbgSuspendCount, thread->isSuspended);
2825 }
2826
2827 dvmUnlockThreadList();
2828 unlockThreadSuspend();
2829
2830 LOG_THREAD("threadid=%d: SuspendAll complete\n", self->threadId);
2831}
2832
2833/*
2834 * Resume all threads that are currently suspended.
2835 *
2836 * The "why" must match with the previous suspend.
2837 */
2838void dvmResumeAllThreads(SuspendCause why)
2839{
2840 Thread* self = dvmThreadSelf();
2841 Thread* thread;
2842 int cc;
2843
2844 lockThreadSuspend("res-all", why); /* one suspend/resume at a time */
2845 LOG_THREAD("threadid=%d: ResumeAll starting\n", self->threadId);
2846
2847 /*
2848 * Decrement the suspend counts for all threads. No need for atomic
2849 * writes, since nobody should be moving until we decrement the count.
2850 * We do need to hold the thread list because of JNI attaches.
2851 */
2852 dvmLockThreadList(self);
2853 lockThreadSuspendCount();
2854 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2855 if (thread == self)
2856 continue;
2857
2858 /* debugger events don't suspend JDWP thread */
2859 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2860 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
Andy McFadden2aa43612009-06-17 16:29:30 -07002861 {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002862 continue;
Andy McFadden2aa43612009-06-17 16:29:30 -07002863 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002864
2865 if (thread->suspendCount > 0) {
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002866 dvmAddToThreadSuspendCount(&thread->suspendCount, -1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002867 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2868 thread->dbgSuspendCount--;
2869 } else {
2870 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2871 thread->threadId);
2872 }
2873 }
2874 unlockThreadSuspendCount();
2875 dvmUnlockThreadList();
2876
2877 /*
Andy McFadden2aa43612009-06-17 16:29:30 -07002878 * In some ways it makes sense to continue to hold the thread-suspend
2879 * lock while we issue the wakeup broadcast. It allows us to complete
2880 * one operation before moving on to the next, which simplifies the
2881 * thread activity debug traces.
2882 *
2883 * This approach caused us some difficulty under Linux, because the
2884 * condition variable broadcast not only made the threads runnable,
2885 * but actually caused them to execute, and it was a while before
2886 * the thread performing the wakeup had an opportunity to release the
2887 * thread-suspend lock.
2888 *
2889 * This is a problem because, when a thread tries to acquire that
2890 * lock, it times out after 3 seconds. If at some point the thread
2891 * is told to suspend, the clock resets; but since the VM is still
2892 * theoretically mid-resume, there's no suspend pending. If, for
2893 * example, the GC was waking threads up while the SIGQUIT handler
2894 * was trying to acquire the lock, we would occasionally time out on
2895 * a busy system and SignalCatcher would abort.
2896 *
2897 * We now perform the unlock before the wakeup broadcast. The next
2898 * suspend can't actually start until the broadcast completes and
2899 * returns, because we're holding the thread-suspend-count lock, but the
2900 * suspending thread is now able to make progress and we avoid the abort.
2901 *
2902 * (Technically there is a narrow window between when we release
2903 * the thread-suspend lock and grab the thread-suspend-count lock.
2904 * This could cause us to send a broadcast to threads with nonzero
2905 * suspend counts, but this is expected and they'll all just fall
2906 * right back to sleep. It's probably safe to grab the suspend-count
2907 * lock before releasing thread-suspend, since we're still following
2908 * the correct order of acquisition, but it feels weird.)
2909 */
2910
2911 LOG_THREAD("threadid=%d: ResumeAll waking others\n", self->threadId);
2912 unlockThreadSuspend();
2913
2914 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002915 * Broadcast a notification to all suspended threads, some or all of
2916 * which may choose to wake up. No need to wait for them.
2917 */
2918 lockThreadSuspendCount();
2919 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2920 assert(cc == 0);
2921 unlockThreadSuspendCount();
2922
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002923 LOG_THREAD("threadid=%d: ResumeAll complete\n", self->threadId);
2924}
2925
2926/*
2927 * Undo any debugger suspensions. This is called when the debugger
2928 * disconnects.
2929 */
2930void dvmUndoDebuggerSuspensions(void)
2931{
2932 Thread* self = dvmThreadSelf();
2933 Thread* thread;
2934 int cc;
2935
2936 lockThreadSuspend("undo", SUSPEND_FOR_DEBUG);
2937 LOG_THREAD("threadid=%d: UndoDebuggerSusp starting\n", self->threadId);
2938
2939 /*
2940 * Decrement the suspend counts for all threads. No need for atomic
2941 * writes, since nobody should be moving until we decrement the count.
2942 * We do need to hold the thread list because of JNI attaches.
2943 */
2944 dvmLockThreadList(self);
2945 lockThreadSuspendCount();
2946 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2947 if (thread == self)
2948 continue;
2949
2950 /* debugger events don't suspend JDWP thread */
2951 if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2952 assert(thread->dbgSuspendCount == 0);
2953 continue;
2954 }
2955
2956 assert(thread->suspendCount >= thread->dbgSuspendCount);
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002957 dvmAddToThreadSuspendCount(&thread->suspendCount,
2958 -thread->dbgSuspendCount);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002959 thread->dbgSuspendCount = 0;
2960 }
2961 unlockThreadSuspendCount();
2962 dvmUnlockThreadList();
2963
2964 /*
2965 * Broadcast a notification to all suspended threads, some or all of
2966 * which may choose to wake up. No need to wait for them.
2967 */
2968 lockThreadSuspendCount();
2969 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2970 assert(cc == 0);
2971 unlockThreadSuspendCount();
2972
2973 unlockThreadSuspend();
2974
2975 LOG_THREAD("threadid=%d: UndoDebuggerSusp complete\n", self->threadId);
2976}
2977
2978/*
2979 * Determine if a thread is suspended.
2980 *
2981 * As with all operations on foreign threads, the caller should hold
2982 * the thread list lock before calling.
Andy McFadden3469a7e2010-08-04 16:09:10 -07002983 *
2984 * If the thread is suspending or waking, these fields could be changing
2985 * out from under us (or the thread could change state right after we
2986 * examine it), making this generally unreliable. This is chiefly
2987 * intended for use by the debugger.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002988 */
Andy McFadden3469a7e2010-08-04 16:09:10 -07002989bool dvmIsSuspended(const Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002990{
2991 /*
2992 * The thread could be:
2993 * (1) Running happily. status is RUNNING, isSuspended is false,
2994 * suspendCount is zero. Return "false".
2995 * (2) Pending suspend. status is RUNNING, isSuspended is false,
2996 * suspendCount is nonzero. Return "false".
2997 * (3) Suspended. suspendCount is nonzero, and either (status is
2998 * RUNNING and isSuspended is true) OR (status is !RUNNING).
2999 * Return "true".
3000 * (4) Waking up. suspendCount is zero, status is RUNNING and
3001 * isSuspended is true. Return "false" (since it could change
3002 * out from under us, unless we hold suspendCountLock).
3003 */
3004
3005 return (thread->suspendCount != 0 &&
3006 ((thread->status == THREAD_RUNNING && thread->isSuspended) ||
3007 (thread->status != THREAD_RUNNING)));
3008}
3009
3010/*
3011 * Wait until another thread self-suspends. This is specifically for
3012 * synchronization between the JDWP thread and a thread that has decided
3013 * to suspend itself after sending an event to the debugger.
3014 *
3015 * Threads that encounter "suspend all" events work as well -- the thread
3016 * in question suspends everybody else and then itself.
3017 *
3018 * We can't hold a thread lock here or in the caller, because we could
3019 * get here just before the to-be-waited-for-thread issues a "suspend all".
3020 * There's an opportunity for badness if the thread we're waiting for exits
3021 * and gets cleaned up, but since the thread in question is processing a
3022 * debugger event, that's not really a possibility. (To avoid deadlock,
3023 * it's important that we not be in THREAD_RUNNING while we wait.)
3024 */
3025void dvmWaitForSuspend(Thread* thread)
3026{
3027 Thread* self = dvmThreadSelf();
3028
3029 LOG_THREAD("threadid=%d: waiting for threadid=%d to sleep\n",
3030 self->threadId, thread->threadId);
3031
3032 assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
3033 assert(thread != self);
3034 assert(self->status != THREAD_RUNNING);
3035
3036 waitForThreadSuspend(self, thread);
3037
3038 LOG_THREAD("threadid=%d: threadid=%d is now asleep\n",
3039 self->threadId, thread->threadId);
3040}
3041
3042/*
3043 * Check to see if we need to suspend ourselves. If so, go to sleep on
3044 * a condition variable.
3045 *
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07003046 * If "newStatus" is not THREAD_UNDEFINED, we change to that state before
3047 * we release the thread suspend count lock.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003048 *
3049 * Returns "true" if we suspended ourselves.
3050 */
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07003051static bool checkSuspendAndChangeStatus(Thread* self, ThreadStatus newStatus)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003052{
3053 bool didSuspend;
3054
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07003055 assert(self != NULL);
3056 assert(self->suspendCount >= 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003057
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07003058 /* fast path: if count is zero and no state change, bail immediately */
3059 if (self->suspendCount == 0 && newStatus == THREAD_UNDEFINED) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003060 return false;
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07003061 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003062
3063 lockThreadSuspendCount(); /* grab gDvm.threadSuspendCountLock */
3064
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003065 didSuspend = (self->suspendCount != 0);
Andy McFadden3469a7e2010-08-04 16:09:10 -07003066 if (didSuspend) {
3067 self->isSuspended = true;
3068 LOG_THREAD("threadid=%d: self-suspending\n", self->threadId);
3069 while (self->suspendCount != 0) {
3070 /* wait for wakeup signal; releases lock */
3071 dvmWaitCond(&gDvm.threadSuspendCountCond,
3072 &gDvm.threadSuspendCountLock);
3073 }
3074 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
3075 self->isSuspended = false;
3076 LOG_THREAD("threadid=%d: self-reviving, status=%d\n",
3077 self->threadId, self->status);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003078 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003079
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07003080 /*
3081 * The status change needs to happen while the suspend count lock is
3082 * held. Otherwise we could switch to RUNNING after another thread
3083 * increases our suspend count, which isn't a "bad" state for us
3084 * (we'll suspend on the next check) but could be a problem for the
Andy McFadden3469a7e2010-08-04 16:09:10 -07003085 * other thread (which thinks we're still safely in VMWAIT or NATIVE
3086 * with a nonzero suspend count, and proceeds to initate GC).
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07003087 */
3088 if (newStatus != THREAD_UNDEFINED)
3089 self->status = newStatus;
3090
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003091 unlockThreadSuspendCount();
3092
3093 return didSuspend;
3094}
3095
3096/*
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07003097 * One-argument wrapper for checkSuspendAndChangeStatus().
3098 */
3099bool dvmCheckSuspendPending(Thread* self)
3100{
3101 return checkSuspendAndChangeStatus(self, THREAD_UNDEFINED);
3102}
3103
3104/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003105 * Update our status.
3106 *
3107 * The "self" argument, which may be NULL, is accepted as an optimization.
3108 *
3109 * Returns the old status.
3110 */
3111ThreadStatus dvmChangeStatus(Thread* self, ThreadStatus newStatus)
3112{
3113 ThreadStatus oldStatus;
3114
3115 if (self == NULL)
3116 self = dvmThreadSelf();
3117
3118 LOGVV("threadid=%d: (status %d -> %d)\n",
3119 self->threadId, self->status, newStatus);
3120
3121 oldStatus = self->status;
3122
3123 if (newStatus == THREAD_RUNNING) {
3124 /*
3125 * Change our status to THREAD_RUNNING. The transition requires
3126 * that we check for pending suspension, because the VM considers
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07003127 * us to be "asleep" in all other states, and another thread could
3128 * be performing a GC now.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003129 *
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07003130 * The check for suspension requires holding the thread suspend
3131 * count lock, which the suspend-all code also grabs. We want to
3132 * check our suspension status and change to RUNNING atomically
3133 * to avoid a situation where suspend-all thinks we're safe
3134 * (e.g. VMWAIT or NATIVE with suspendCount=1) but we've actually
3135 * switched to RUNNING and are executing code.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003136 */
3137 assert(self->status != THREAD_RUNNING);
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07003138 checkSuspendAndChangeStatus(self, newStatus);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003139 } else {
3140 /*
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07003141 * Not changing to THREAD_RUNNING. No additional work required.
Andy McFadden3469a7e2010-08-04 16:09:10 -07003142 *
3143 * We use a releasing store to ensure that, if we were RUNNING,
3144 * any updates we previously made to objects on the managed heap
3145 * will be observed before the state change.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003146 */
Andy McFadden3469a7e2010-08-04 16:09:10 -07003147 android_atomic_release_store(newStatus, &self->status);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003148 }
3149
3150 return oldStatus;
3151}
3152
3153/*
3154 * Get a statically defined thread group from a field in the ThreadGroup
3155 * Class object. Expected arguments are "mMain" and "mSystem".
3156 */
3157static Object* getStaticThreadGroup(const char* fieldName)
3158{
3159 StaticField* groupField;
3160 Object* groupObj;
3161
3162 groupField = dvmFindStaticField(gDvm.classJavaLangThreadGroup,
3163 fieldName, "Ljava/lang/ThreadGroup;");
3164 if (groupField == NULL) {
3165 LOGE("java.lang.ThreadGroup does not have an '%s' field\n", fieldName);
3166 dvmThrowException("Ljava/lang/IncompatibleClassChangeError;", NULL);
3167 return NULL;
3168 }
3169 groupObj = dvmGetStaticFieldObject(groupField);
3170 if (groupObj == NULL) {
3171 LOGE("java.lang.ThreadGroup.%s not initialized\n", fieldName);
3172 dvmThrowException("Ljava/lang/InternalError;", NULL);
3173 return NULL;
3174 }
3175
3176 return groupObj;
3177}
3178Object* dvmGetSystemThreadGroup(void)
3179{
3180 return getStaticThreadGroup("mSystem");
3181}
3182Object* dvmGetMainThreadGroup(void)
3183{
3184 return getStaticThreadGroup("mMain");
3185}
3186
3187/*
3188 * Given a VMThread object, return the associated Thread*.
3189 *
3190 * NOTE: if the thread detaches, the struct Thread will disappear, and
3191 * we will be touching invalid data. For safety, lock the thread list
3192 * before calling this.
3193 */
3194Thread* dvmGetThreadFromThreadObject(Object* vmThreadObj)
3195{
3196 int vmData;
3197
3198 vmData = dvmGetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData);
Andy McFadden44860362009-08-06 17:56:14 -07003199
3200 if (false) {
3201 Thread* thread = gDvm.threadList;
3202 while (thread != NULL) {
3203 if ((Thread*)vmData == thread)
3204 break;
3205
3206 thread = thread->next;
3207 }
3208
3209 if (thread == NULL) {
3210 LOGW("WARNING: vmThreadObj=%p has thread=%p, not in thread list\n",
3211 vmThreadObj, (Thread*)vmData);
3212 vmData = 0;
3213 }
3214 }
3215
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003216 return (Thread*) vmData;
3217}
3218
Andy McFadden2b94b302010-03-09 16:38:36 -08003219/*
3220 * Given a pthread handle, return the associated Thread*.
Andy McFadden0a24ef92010-03-12 13:39:59 -08003221 * Caller must hold the thread list lock.
Andy McFadden2b94b302010-03-09 16:38:36 -08003222 *
3223 * Returns NULL if the thread was not found.
3224 */
3225Thread* dvmGetThreadByHandle(pthread_t handle)
3226{
Andy McFadden0a24ef92010-03-12 13:39:59 -08003227 Thread* thread;
3228 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
Andy McFadden2b94b302010-03-09 16:38:36 -08003229 if (thread->handle == handle)
3230 break;
Andy McFadden2b94b302010-03-09 16:38:36 -08003231 }
Andy McFadden0a24ef92010-03-12 13:39:59 -08003232 return thread;
3233}
Andy McFadden2b94b302010-03-09 16:38:36 -08003234
Andy McFadden0a24ef92010-03-12 13:39:59 -08003235/*
3236 * Given a threadId, return the associated Thread*.
3237 * Caller must hold the thread list lock.
3238 *
3239 * Returns NULL if the thread was not found.
3240 */
3241Thread* dvmGetThreadByThreadId(u4 threadId)
3242{
3243 Thread* thread;
3244 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
3245 if (thread->threadId == threadId)
3246 break;
3247 }
Andy McFadden2b94b302010-03-09 16:38:36 -08003248 return thread;
3249}
3250
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003251
3252/*
3253 * Conversion map for "nice" values.
3254 *
3255 * We use Android thread priority constants to be consistent with the rest
3256 * of the system. In some cases adjacent entries may overlap.
3257 */
3258static const int kNiceValues[10] = {
3259 ANDROID_PRIORITY_LOWEST, /* 1 (MIN_PRIORITY) */
3260 ANDROID_PRIORITY_BACKGROUND + 6,
3261 ANDROID_PRIORITY_BACKGROUND + 3,
3262 ANDROID_PRIORITY_BACKGROUND,
3263 ANDROID_PRIORITY_NORMAL, /* 5 (NORM_PRIORITY) */
3264 ANDROID_PRIORITY_NORMAL - 2,
3265 ANDROID_PRIORITY_NORMAL - 4,
3266 ANDROID_PRIORITY_URGENT_DISPLAY + 3,
3267 ANDROID_PRIORITY_URGENT_DISPLAY + 2,
3268 ANDROID_PRIORITY_URGENT_DISPLAY /* 10 (MAX_PRIORITY) */
3269};
3270
3271/*
3272 * Change the priority of a system thread to match that of the Thread object.
3273 *
3274 * We map a priority value from 1-10 to Linux "nice" values, where lower
3275 * numbers indicate higher priority.
3276 */
3277void dvmChangeThreadPriority(Thread* thread, int newPriority)
3278{
3279 pid_t pid = thread->systemTid;
3280 int newNice;
3281
3282 if (newPriority < 1 || newPriority > 10) {
3283 LOGW("bad priority %d\n", newPriority);
3284 newPriority = 5;
3285 }
3286 newNice = kNiceValues[newPriority-1];
3287
Andy McFaddend62c0b52009-08-04 15:02:12 -07003288 if (newNice >= ANDROID_PRIORITY_BACKGROUND) {
San Mehat5a2056c2009-09-12 10:10:13 -07003289 set_sched_policy(dvmGetSysThreadId(), SP_BACKGROUND);
San Mehat3e371e22009-06-26 08:36:16 -07003290 } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
San Mehat5a2056c2009-09-12 10:10:13 -07003291 set_sched_policy(dvmGetSysThreadId(), SP_FOREGROUND);
San Mehat256fc152009-04-21 14:03:06 -07003292 }
3293
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003294 if (setpriority(PRIO_PROCESS, pid, newNice) != 0) {
3295 char* str = dvmGetThreadName(thread);
3296 LOGI("setPriority(%d) '%s' to prio=%d(n=%d) failed: %s\n",
3297 pid, str, newPriority, newNice, strerror(errno));
3298 free(str);
3299 } else {
3300 LOGV("setPriority(%d) to prio=%d(n=%d)\n",
3301 pid, newPriority, newNice);
3302 }
3303}
3304
3305/*
3306 * Get the thread priority for the current thread by querying the system.
3307 * This is useful when attaching a thread through JNI.
3308 *
3309 * Returns a value from 1 to 10 (compatible with java.lang.Thread values).
3310 */
3311static int getThreadPriorityFromSystem(void)
3312{
3313 int i, sysprio, jprio;
3314
3315 errno = 0;
3316 sysprio = getpriority(PRIO_PROCESS, 0);
3317 if (sysprio == -1 && errno != 0) {
3318 LOGW("getpriority() failed: %s\n", strerror(errno));
3319 return THREAD_NORM_PRIORITY;
3320 }
3321
3322 jprio = THREAD_MIN_PRIORITY;
3323 for (i = 0; i < NELEM(kNiceValues); i++) {
3324 if (sysprio >= kNiceValues[i])
3325 break;
3326 jprio++;
3327 }
3328 if (jprio > THREAD_MAX_PRIORITY)
3329 jprio = THREAD_MAX_PRIORITY;
3330
3331 return jprio;
3332}
3333
3334
3335/*
3336 * Return true if the thread is on gDvm.threadList.
3337 * Caller should not hold gDvm.threadListLock.
3338 */
3339bool dvmIsOnThreadList(const Thread* thread)
3340{
3341 bool ret = false;
3342
3343 dvmLockThreadList(NULL);
3344 if (thread == gDvm.threadList) {
3345 ret = true;
3346 } else {
3347 ret = thread->prev != NULL || thread->next != NULL;
3348 }
3349 dvmUnlockThreadList();
3350
3351 return ret;
3352}
3353
3354/*
3355 * Dump a thread to the log file -- just calls dvmDumpThreadEx() with an
3356 * output target.
3357 */
3358void dvmDumpThread(Thread* thread, bool isRunning)
3359{
3360 DebugOutputTarget target;
3361
3362 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
3363 dvmDumpThreadEx(&target, thread, isRunning);
3364}
3365
3366/*
Andy McFaddend62c0b52009-08-04 15:02:12 -07003367 * Try to get the scheduler group.
3368 *
Andy McFadden7f64ede2010-03-03 15:37:10 -08003369 * The data from /proc/<pid>/cgroup looks (something) like:
Andy McFaddend62c0b52009-08-04 15:02:12 -07003370 * 2:cpu:/bg_non_interactive
Andy McFadden7f64ede2010-03-03 15:37:10 -08003371 * 1:cpuacct:/
Andy McFaddend62c0b52009-08-04 15:02:12 -07003372 *
3373 * We return the part after the "/", which will be an empty string for
3374 * the default cgroup. If the string is longer than "bufLen", the string
3375 * will be truncated.
Andy McFadden7f64ede2010-03-03 15:37:10 -08003376 *
3377 * TODO: this is cloned from a static function in libcutils; expose that?
Andy McFaddend62c0b52009-08-04 15:02:12 -07003378 */
Andy McFadden7f64ede2010-03-03 15:37:10 -08003379static int getSchedulerGroup(int tid, char* buf, size_t bufLen)
Andy McFaddend62c0b52009-08-04 15:02:12 -07003380{
3381#ifdef HAVE_ANDROID_OS
3382 char pathBuf[32];
Andy McFadden7f64ede2010-03-03 15:37:10 -08003383 char lineBuf[256];
3384 FILE *fp;
Andy McFaddend62c0b52009-08-04 15:02:12 -07003385
Andy McFadden7f64ede2010-03-03 15:37:10 -08003386 snprintf(pathBuf, sizeof(pathBuf), "/proc/%d/cgroup", tid);
3387 if (!(fp = fopen(pathBuf, "r"))) {
3388 return -1;
Andy McFaddend62c0b52009-08-04 15:02:12 -07003389 }
3390
Andy McFadden7f64ede2010-03-03 15:37:10 -08003391 while(fgets(lineBuf, sizeof(lineBuf) -1, fp)) {
3392 char *next = lineBuf;
3393 char *subsys;
3394 char *grp;
3395 size_t len;
Andy McFaddend62c0b52009-08-04 15:02:12 -07003396
Andy McFadden7f64ede2010-03-03 15:37:10 -08003397 /* Junk the first field */
3398 if (!strsep(&next, ":")) {
3399 goto out_bad_data;
3400 }
Andy McFaddend62c0b52009-08-04 15:02:12 -07003401
Andy McFadden7f64ede2010-03-03 15:37:10 -08003402 if (!(subsys = strsep(&next, ":"))) {
3403 goto out_bad_data;
3404 }
3405
3406 if (strcmp(subsys, "cpu")) {
3407 /* Not the subsys we're looking for */
3408 continue;
3409 }
3410
3411 if (!(grp = strsep(&next, ":"))) {
3412 goto out_bad_data;
3413 }
3414 grp++; /* Drop the leading '/' */
3415 len = strlen(grp);
3416 grp[len-1] = '\0'; /* Drop the trailing '\n' */
3417
3418 if (bufLen <= len) {
3419 len = bufLen - 1;
3420 }
3421 strncpy(buf, grp, len);
3422 buf[len] = '\0';
3423 fclose(fp);
3424 return 0;
Andy McFaddend62c0b52009-08-04 15:02:12 -07003425 }
3426
Andy McFadden7f64ede2010-03-03 15:37:10 -08003427 LOGE("Failed to find cpu subsys");
3428 fclose(fp);
3429 return -1;
3430 out_bad_data:
3431 LOGE("Bad cgroup data {%s}", lineBuf);
3432 fclose(fp);
3433 return -1;
Andy McFaddend62c0b52009-08-04 15:02:12 -07003434#else
Andy McFadden7f64ede2010-03-03 15:37:10 -08003435 errno = ENOSYS;
3436 return -1;
Andy McFaddend62c0b52009-08-04 15:02:12 -07003437#endif
3438}
3439
3440/*
Ben Cheng7a0bcd02010-01-22 16:45:45 -08003441 * Convert ThreadStatus to a string.
3442 */
3443const char* dvmGetThreadStatusStr(ThreadStatus status)
3444{
3445 switch (status) {
3446 case THREAD_ZOMBIE: return "ZOMBIE";
3447 case THREAD_RUNNING: return "RUNNABLE";
3448 case THREAD_TIMED_WAIT: return "TIMED_WAIT";
3449 case THREAD_MONITOR: return "MONITOR";
3450 case THREAD_WAIT: return "WAIT";
3451 case THREAD_INITIALIZING: return "INITIALIZING";
3452 case THREAD_STARTING: return "STARTING";
3453 case THREAD_NATIVE: return "NATIVE";
3454 case THREAD_VMWAIT: return "VMWAIT";
3455 default: return "UNKNOWN";
3456 }
3457}
3458
3459/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003460 * Print information about the specified thread.
3461 *
3462 * Works best when the thread in question is "self" or has been suspended.
3463 * When dumping a separate thread that's still running, set "isRunning" to
3464 * use a more cautious thread dump function.
3465 */
3466void dvmDumpThreadEx(const DebugOutputTarget* target, Thread* thread,
3467 bool isRunning)
3468{
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003469 Object* threadObj;
3470 Object* groupObj;
3471 StringObject* nameStr;
3472 char* threadName = NULL;
3473 char* groupName = NULL;
Andy McFaddend62c0b52009-08-04 15:02:12 -07003474 char schedulerGroupBuf[32];
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003475 bool isDaemon;
3476 int priority; // java.lang.Thread priority
3477 int policy; // pthread policy
3478 struct sched_param sp; // pthread scheduling parameters
Christopher Tate962f8962010-06-02 16:17:46 -07003479 char schedstatBuf[64]; // contents of /proc/[pid]/task/[tid]/schedstat
3480 int schedstatFd;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003481
Andy McFaddene3346d82010-06-02 15:37:21 -07003482 /*
3483 * Get the java.lang.Thread object. This function gets called from
3484 * some weird debug contexts, so it's possible that there's a GC in
3485 * progress on some other thread. To decrease the chances of the
3486 * thread object being moved out from under us, we add the reference
3487 * to the tracked allocation list, which pins it in place.
3488 *
3489 * If threadObj is NULL, the thread is still in the process of being
3490 * attached to the VM, and there's really nothing interesting to
3491 * say about it yet.
3492 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003493 threadObj = thread->threadObj;
3494 if (threadObj == NULL) {
Andy McFaddene3346d82010-06-02 15:37:21 -07003495 LOGI("Can't dump thread %d: threadObj not set\n", thread->threadId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003496 return;
3497 }
Andy McFaddene3346d82010-06-02 15:37:21 -07003498 dvmAddTrackedAlloc(threadObj, NULL);
3499
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003500 nameStr = (StringObject*) dvmGetFieldObject(threadObj,
3501 gDvm.offJavaLangThread_name);
3502 threadName = dvmCreateCstrFromString(nameStr);
3503
3504 priority = dvmGetFieldInt(threadObj, gDvm.offJavaLangThread_priority);
3505 isDaemon = dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon);
3506
3507 if (pthread_getschedparam(pthread_self(), &policy, &sp) != 0) {
3508 LOGW("Warning: pthread_getschedparam failed\n");
3509 policy = -1;
3510 sp.sched_priority = -1;
3511 }
Andy McFadden7f64ede2010-03-03 15:37:10 -08003512 if (getSchedulerGroup(thread->systemTid, schedulerGroupBuf,
3513 sizeof(schedulerGroupBuf)) != 0)
Andy McFaddend62c0b52009-08-04 15:02:12 -07003514 {
3515 strcpy(schedulerGroupBuf, "unknown");
3516 } else if (schedulerGroupBuf[0] == '\0') {
3517 strcpy(schedulerGroupBuf, "default");
3518 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003519
3520 /* a null value for group is not expected, but deal with it anyway */
3521 groupObj = (Object*) dvmGetFieldObject(threadObj,
3522 gDvm.offJavaLangThread_group);
3523 if (groupObj != NULL) {
3524 int offset = dvmFindFieldOffset(gDvm.classJavaLangThreadGroup,
3525 "name", "Ljava/lang/String;");
3526 if (offset < 0) {
3527 LOGW("Unable to find 'name' field in ThreadGroup\n");
3528 } else {
3529 nameStr = (StringObject*) dvmGetFieldObject(groupObj, offset);
3530 groupName = dvmCreateCstrFromString(nameStr);
3531 }
3532 }
3533 if (groupName == NULL)
Andy McFadden40607dd2010-06-28 16:57:24 -07003534 groupName = strdup("(null; initializing?)");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003535
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003536 dvmPrintDebugMessage(target,
Ben Chengdc4a9282010-02-24 17:27:01 -08003537 "\"%s\"%s prio=%d tid=%d %s%s\n",
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003538 threadName, isDaemon ? " daemon" : "",
Ben Chengdc4a9282010-02-24 17:27:01 -08003539 priority, thread->threadId, dvmGetThreadStatusStr(thread->status),
3540#if defined(WITH_JIT)
3541 thread->inJitCodeCache ? " JIT" : ""
3542#else
3543 ""
3544#endif
3545 );
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003546 dvmPrintDebugMessage(target,
Andy McFadden2aa43612009-06-17 16:29:30 -07003547 " | group=\"%s\" sCount=%d dsCount=%d s=%c obj=%p self=%p\n",
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003548 groupName, thread->suspendCount, thread->dbgSuspendCount,
Andy McFadden2aa43612009-06-17 16:29:30 -07003549 thread->isSuspended ? 'Y' : 'N', thread->threadObj, thread);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003550 dvmPrintDebugMessage(target,
Andy McFaddend62c0b52009-08-04 15:02:12 -07003551 " | sysTid=%d nice=%d sched=%d/%d cgrp=%s handle=%d\n",
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003552 thread->systemTid, getpriority(PRIO_PROCESS, thread->systemTid),
Andy McFaddend62c0b52009-08-04 15:02:12 -07003553 policy, sp.sched_priority, schedulerGroupBuf, (int)thread->handle);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003554
Christopher Tate962f8962010-06-02 16:17:46 -07003555 snprintf(schedstatBuf, sizeof(schedstatBuf), "/proc/%d/task/%d/schedstat",
3556 getpid(), thread->systemTid);
3557 schedstatFd = open(schedstatBuf, O_RDONLY);
3558 if (schedstatFd >= 0) {
3559 int bytes;
3560 bytes = read(schedstatFd, schedstatBuf, sizeof(schedstatBuf) - 1);
3561 close(schedstatFd);
3562 if (bytes > 1) {
3563 schedstatBuf[bytes-1] = 0; // trailing newline
3564 dvmPrintDebugMessage(target, " | schedstat=( %s )\n", schedstatBuf);
3565 }
3566 }
3567
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003568#ifdef WITH_MONITOR_TRACKING
3569 if (!isRunning) {
3570 LockedObjectData* lod = thread->pLockedObjects;
3571 if (lod != NULL)
3572 dvmPrintDebugMessage(target, " | monitors held:\n");
3573 else
3574 dvmPrintDebugMessage(target, " | monitors held: <none>\n");
3575 while (lod != NULL) {
Elliott Hughesbeea0b72009-11-13 11:20:15 -08003576 Object* obj = lod->obj;
3577 if (obj->clazz == gDvm.classJavaLangClass) {
3578 ClassObject* clazz = (ClassObject*) obj;
3579 dvmPrintDebugMessage(target, " > %p[%d] (%s object for class %s)\n",
3580 obj, lod->recursionCount, obj->clazz->descriptor,
3581 clazz->descriptor);
3582 } else {
3583 dvmPrintDebugMessage(target, " > %p[%d] (%s)\n",
3584 obj, lod->recursionCount, obj->clazz->descriptor);
3585 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003586 lod = lod->next;
3587 }
3588 }
3589#endif
3590
3591 if (isRunning)
3592 dvmDumpRunningThreadStack(target, thread);
3593 else
3594 dvmDumpThreadStack(target, thread);
3595
Andy McFaddene3346d82010-06-02 15:37:21 -07003596 dvmReleaseTrackedAlloc(threadObj, NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003597 free(threadName);
3598 free(groupName);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003599}
3600
3601/*
3602 * Get the name of a thread.
3603 *
3604 * For correctness, the caller should hold the thread list lock to ensure
3605 * that the thread doesn't go away mid-call.
3606 *
3607 * Returns a newly-allocated string, or NULL if the Thread doesn't have a name.
3608 */
3609char* dvmGetThreadName(Thread* thread)
3610{
3611 StringObject* nameObj;
3612
3613 if (thread->threadObj == NULL) {
3614 LOGW("threadObj is NULL, name not available\n");
3615 return strdup("-unknown-");
3616 }
3617
3618 nameObj = (StringObject*)
3619 dvmGetFieldObject(thread->threadObj, gDvm.offJavaLangThread_name);
3620 return dvmCreateCstrFromString(nameObj);
3621}
3622
3623/*
3624 * Dump all threads to the log file -- just calls dvmDumpAllThreadsEx() with
3625 * an output target.
3626 */
3627void dvmDumpAllThreads(bool grabLock)
3628{
3629 DebugOutputTarget target;
3630
3631 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
3632 dvmDumpAllThreadsEx(&target, grabLock);
3633}
3634
3635/*
3636 * Print information about all known threads. Assumes they have been
3637 * suspended (or are in a non-interpreting state, e.g. WAIT or NATIVE).
3638 *
3639 * If "grabLock" is true, we grab the thread lock list. This is important
3640 * to do unless the caller already holds the lock.
3641 */
3642void dvmDumpAllThreadsEx(const DebugOutputTarget* target, bool grabLock)
3643{
3644 Thread* thread;
3645
3646 dvmPrintDebugMessage(target, "DALVIK THREADS:\n");
3647
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07003648#ifdef HAVE_ANDROID_OS
3649 dvmPrintDebugMessage(target,
3650 "(mutexes: tll=%x tsl=%x tscl=%x ghl=%x hwl=%x hwll=%x)\n",
3651 gDvm.threadListLock.value,
3652 gDvm._threadSuspendLock.value,
3653 gDvm.threadSuspendCountLock.value,
3654 gDvm.gcHeapLock.value,
3655 gDvm.heapWorkerLock.value,
3656 gDvm.heapWorkerListLock.value);
3657#endif
3658
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003659 if (grabLock)
3660 dvmLockThreadList(dvmThreadSelf());
3661
3662 thread = gDvm.threadList;
3663 while (thread != NULL) {
3664 dvmDumpThreadEx(target, thread, false);
3665
3666 /* verify link */
3667 assert(thread->next == NULL || thread->next->prev == thread);
3668
3669 thread = thread->next;
3670 }
3671
3672 if (grabLock)
3673 dvmUnlockThreadList();
3674}
3675
Andy McFadden384ef6b2010-03-15 17:24:55 -07003676/*
3677 * Nuke the target thread from orbit.
3678 *
3679 * The idea is to send a "crash" signal to the target thread so that
3680 * debuggerd will take notice and dump an appropriate stack trace.
3681 * Because of the way debuggerd works, we have to throw the same signal
3682 * at it twice.
3683 *
3684 * This does not necessarily cause the entire process to stop, but once a
3685 * thread has been nuked the rest of the system is likely to be unstable.
3686 * This returns so that some limited set of additional operations may be
Andy McFaddend4e09522010-03-23 12:34:43 -07003687 * performed, but it's advisable (and expected) to call dvmAbort soon.
3688 * (This is NOT a way to simply cancel a thread.)
Andy McFadden384ef6b2010-03-15 17:24:55 -07003689 */
3690void dvmNukeThread(Thread* thread)
3691{
Andy McFaddena388a162010-03-18 16:27:14 -07003692 /* suppress the heapworker watchdog to assist anyone using a debugger */
3693 gDvm.nativeDebuggerActive = true;
3694
Andy McFadden384ef6b2010-03-15 17:24:55 -07003695 /*
Andy McFaddend4e09522010-03-23 12:34:43 -07003696 * Send the signals, separated by a brief interval to allow debuggerd
3697 * to work its magic. An uncommon signal like SIGFPE or SIGSTKFLT
3698 * can be used instead of SIGSEGV to avoid making it look like the
3699 * code actually crashed at the current point of execution.
3700 *
3701 * (Observed behavior: with SIGFPE, debuggerd will dump the target
3702 * thread and then the thread that calls dvmAbort. With SIGSEGV,
3703 * you don't get the second stack trace; possibly something in the
3704 * kernel decides that a signal has already been sent and it's time
3705 * to just kill the process. The position in the current thread is
3706 * generally known, so the second dump is not useful.)
Andy McFadden384ef6b2010-03-15 17:24:55 -07003707 *
Andy McFaddena388a162010-03-18 16:27:14 -07003708 * The target thread can continue to execute between the two signals.
3709 * (The first just causes debuggerd to attach to it.)
Andy McFadden384ef6b2010-03-15 17:24:55 -07003710 */
Andy McFaddend4e09522010-03-23 12:34:43 -07003711 LOGD("threadid=%d: sending two SIGSTKFLTs to threadid=%d (tid=%d) to"
3712 " cause debuggerd dump\n",
3713 dvmThreadSelf()->threadId, thread->threadId, thread->systemTid);
3714 pthread_kill(thread->handle, SIGSTKFLT);
Andy McFaddena388a162010-03-18 16:27:14 -07003715 usleep(2 * 1000 * 1000); // TODO: timed-wait until debuggerd attaches
Andy McFaddend4e09522010-03-23 12:34:43 -07003716 pthread_kill(thread->handle, SIGSTKFLT);
Andy McFadden7122d862010-03-19 15:18:57 -07003717 LOGD("Sent, pausing to let debuggerd run\n");
Andy McFaddena388a162010-03-18 16:27:14 -07003718 usleep(8 * 1000 * 1000); // TODO: timed-wait until debuggerd finishes
Andy McFaddend4e09522010-03-23 12:34:43 -07003719
3720 /* ignore SIGSEGV so the eventual dmvAbort() doesn't notify debuggerd */
3721 signal(SIGSEGV, SIG_IGN);
Andy McFadden384ef6b2010-03-15 17:24:55 -07003722 LOGD("Continuing\n");
3723}
3724
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003725#ifdef WITH_MONITOR_TRACKING
3726/*
3727 * Count up the #of locked objects in the current thread.
3728 */
3729static int getThreadObjectCount(const Thread* self)
3730{
3731 LockedObjectData* lod;
3732 int count = 0;
3733
3734 lod = self->pLockedObjects;
3735 while (lod != NULL) {
3736 count++;
3737 lod = lod->next;
3738 }
3739 return count;
3740}
3741
3742/*
3743 * Add the object to the thread's locked object list if it doesn't already
3744 * exist. The most recently added object is the most likely to be released
3745 * next, so we insert at the head of the list.
3746 *
3747 * If it already exists, we increase the recursive lock count.
3748 *
3749 * The object's lock may be thin or fat.
3750 */
3751void dvmAddToMonitorList(Thread* self, Object* obj, bool withTrace)
3752{
3753 LockedObjectData* newLod;
3754 LockedObjectData* lod;
3755 int* trace;
3756 int depth;
3757
3758 lod = self->pLockedObjects;
3759 while (lod != NULL) {
3760 if (lod->obj == obj) {
3761 lod->recursionCount++;
3762 LOGV("+++ +recursive lock %p -> %d\n", obj, lod->recursionCount);
3763 return;
3764 }
3765 lod = lod->next;
3766 }
3767
3768 newLod = (LockedObjectData*) calloc(1, sizeof(LockedObjectData));
3769 if (newLod == NULL) {
3770 LOGE("malloc failed on %d bytes\n", sizeof(LockedObjectData));
3771 return;
3772 }
3773 newLod->obj = obj;
3774 newLod->recursionCount = 0;
3775
3776 if (withTrace) {
3777 trace = dvmFillInStackTraceRaw(self, &depth);
3778 newLod->rawStackTrace = trace;
3779 newLod->stackDepth = depth;
3780 }
3781
3782 newLod->next = self->pLockedObjects;
3783 self->pLockedObjects = newLod;
3784
3785 LOGV("+++ threadid=%d: added %p, now %d\n",
3786 self->threadId, newLod, getThreadObjectCount(self));
3787}
3788
3789/*
3790 * Remove the object from the thread's locked object list. If the entry
3791 * has a nonzero recursion count, we just decrement the count instead.
3792 */
3793void dvmRemoveFromMonitorList(Thread* self, Object* obj)
3794{
3795 LockedObjectData* lod;
3796 LockedObjectData* prevLod;
3797
3798 lod = self->pLockedObjects;
3799 prevLod = NULL;
3800 while (lod != NULL) {
3801 if (lod->obj == obj) {
3802 if (lod->recursionCount > 0) {
3803 lod->recursionCount--;
3804 LOGV("+++ -recursive lock %p -> %d\n",
3805 obj, lod->recursionCount);
3806 return;
3807 } else {
3808 break;
3809 }
3810 }
3811 prevLod = lod;
3812 lod = lod->next;
3813 }
3814
3815 if (lod == NULL) {
3816 LOGW("BUG: object %p not found in thread's lock list\n", obj);
3817 return;
3818 }
3819 if (prevLod == NULL) {
3820 /* first item in list */
3821 assert(self->pLockedObjects == lod);
3822 self->pLockedObjects = lod->next;
3823 } else {
3824 /* middle/end of list */
3825 prevLod->next = lod->next;
3826 }
3827
3828 LOGV("+++ threadid=%d: removed %p, now %d\n",
3829 self->threadId, lod, getThreadObjectCount(self));
3830 free(lod->rawStackTrace);
3831 free(lod);
3832}
3833
3834/*
3835 * If the specified object is already in the thread's locked object list,
3836 * return the LockedObjectData struct. Otherwise return NULL.
3837 */
3838LockedObjectData* dvmFindInMonitorList(const Thread* self, const Object* obj)
3839{
3840 LockedObjectData* lod;
3841
3842 lod = self->pLockedObjects;
3843 while (lod != NULL) {
3844 if (lod->obj == obj)
3845 return lod;
3846 lod = lod->next;
3847 }
3848 return NULL;
3849}
3850#endif /*WITH_MONITOR_TRACKING*/
3851
3852
3853/*
3854 * GC helper functions
3855 */
3856
The Android Open Source Project99409882009-03-18 22:20:24 -07003857/*
3858 * Add the contents of the registers from the interpreted call stack.
3859 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003860static void gcScanInterpStackReferences(Thread *thread)
3861{
3862 const u4 *framePtr;
The Android Open Source Project99409882009-03-18 22:20:24 -07003863#if WITH_EXTRA_GC_CHECKS > 1
3864 bool first = true;
3865#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003866
3867 framePtr = (const u4 *)thread->curFrame;
3868 while (framePtr != NULL) {
3869 const StackSaveArea *saveArea;
3870 const Method *method;
3871
3872 saveArea = SAVEAREA_FROM_FP(framePtr);
3873 method = saveArea->method;
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07003874 if (method != NULL) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003875#ifdef COUNT_PRECISE_METHODS
3876 /* the GC is running, so no lock required */
The Android Open Source Project99409882009-03-18 22:20:24 -07003877 if (dvmPointerSetAddEntry(gDvm.preciseMethods, method))
3878 LOGI("PGC: added %s.%s %p\n",
3879 method->clazz->descriptor, method->name, method);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003880#endif
The Android Open Source Project99409882009-03-18 22:20:24 -07003881#if WITH_EXTRA_GC_CHECKS > 1
3882 /*
3883 * May also want to enable the memset() in the "invokeMethod"
3884 * goto target in the portable interpreter. That sets the stack
3885 * to a pattern that makes referring to uninitialized data
3886 * very obvious.
3887 */
3888
3889 if (first) {
3890 /*
3891 * First frame, isn't native, check the "alternate" saved PC
3892 * as a sanity check.
3893 *
3894 * It seems like we could check the second frame if the first
3895 * is native, since the PCs should be the same. It turns out
3896 * this doesn't always work. The problem is that we could
3897 * have calls in the sequence:
3898 * interp method #2
3899 * native method
3900 * interp method #1
3901 *
3902 * and then GC while in the native method after returning
3903 * from interp method #2. The currentPc on the stack is
3904 * for interp method #1, but thread->currentPc2 is still
3905 * set for the last thing interp method #2 did.
3906 *
3907 * This can also happen in normal execution:
3908 * - sget-object on not-yet-loaded class
3909 * - class init updates currentPc2
3910 * - static field init is handled by parsing annotations;
3911 * static String init requires creation of a String object,
3912 * which can cause a GC
3913 *
3914 * Essentially, any pattern that involves executing
3915 * interpreted code and then causes an allocation without
3916 * executing instructions in the original method will hit
3917 * this. These are rare enough that the test still has
3918 * some value.
3919 */
3920 if (saveArea->xtra.currentPc != thread->currentPc2) {
3921 LOGW("PGC: savedPC(%p) != current PC(%p), %s.%s ins=%p\n",
3922 saveArea->xtra.currentPc, thread->currentPc2,
3923 method->clazz->descriptor, method->name, method->insns);
3924 if (saveArea->xtra.currentPc != NULL)
3925 LOGE(" pc inst = 0x%04x\n", *saveArea->xtra.currentPc);
3926 if (thread->currentPc2 != NULL)
3927 LOGE(" pc2 inst = 0x%04x\n", *thread->currentPc2);
3928 dvmDumpThread(thread, false);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003929 }
The Android Open Source Project99409882009-03-18 22:20:24 -07003930 } else {
3931 /*
3932 * It's unusual, but not impossible, for a non-first frame
3933 * to be at something other than a method invocation. For
3934 * example, if we do a new-instance on a nonexistent class,
3935 * we'll have a lot of class loader activity on the stack
3936 * above the frame with the "new" operation. Could also
3937 * happen while we initialize a Throwable when an instruction
3938 * fails.
3939 *
3940 * So there's not much we can do here to verify the PC,
3941 * except to verify that it's a GC point.
3942 */
3943 }
3944 assert(saveArea->xtra.currentPc != NULL);
3945#endif
3946
3947 const RegisterMap* pMap;
3948 const u1* regVector;
3949 int i;
3950
Andy McFaddencf8b55c2009-04-13 15:26:03 -07003951 Method* nonConstMethod = (Method*) method; // quiet gcc
3952 pMap = dvmGetExpandedRegisterMap(nonConstMethod);
The Android Open Source Project99409882009-03-18 22:20:24 -07003953 if (pMap != NULL) {
3954 /* found map, get registers for this address */
3955 int addr = saveArea->xtra.currentPc - method->insns;
Andy McFaddend45a8872009-03-24 20:41:52 -07003956 regVector = dvmRegisterMapGetLine(pMap, addr);
The Android Open Source Project99409882009-03-18 22:20:24 -07003957 if (regVector == NULL) {
3958 LOGW("PGC: map but no entry for %s.%s addr=0x%04x\n",
3959 method->clazz->descriptor, method->name, addr);
3960 } else {
3961 LOGV("PGC: found map for %s.%s 0x%04x (t=%d)\n",
3962 method->clazz->descriptor, method->name, addr,
3963 thread->threadId);
3964 }
3965 } else {
3966 /*
3967 * No map found. If precise GC is disabled this is
3968 * expected -- we don't create pointers to the map data even
3969 * if it's present -- but if it's enabled it means we're
3970 * unexpectedly falling back on a conservative scan, so it's
3971 * worth yelling a little.
The Android Open Source Project99409882009-03-18 22:20:24 -07003972 */
3973 if (gDvm.preciseGc) {
Andy McFaddena66a01a2009-08-18 15:11:35 -07003974 LOGVV("PGC: no map for %s.%s\n",
The Android Open Source Project99409882009-03-18 22:20:24 -07003975 method->clazz->descriptor, method->name);
3976 }
3977 regVector = NULL;
3978 }
3979
3980 if (regVector == NULL) {
3981 /* conservative scan */
3982 for (i = method->registersSize - 1; i >= 0; i--) {
3983 u4 rval = *framePtr++;
3984 if (rval != 0 && (rval & 0x3) == 0) {
3985 dvmMarkIfObject((Object *)rval);
3986 }
3987 }
3988 } else {
3989 /*
3990 * Precise scan. v0 is at the lowest address on the
3991 * interpreted stack, and is the first bit in the register
3992 * vector, so we can walk through the register map and
3993 * memory in the same direction.
3994 *
3995 * A '1' bit indicates a live reference.
3996 */
3997 u2 bits = 1 << 1;
3998 for (i = method->registersSize - 1; i >= 0; i--) {
3999 u4 rval = *framePtr++;
4000
4001 bits >>= 1;
4002 if (bits == 1) {
4003 /* set bit 9 so we can tell when we're empty */
4004 bits = *regVector++ | 0x0100;
4005 LOGVV("loaded bits: 0x%02x\n", bits & 0xff);
4006 }
4007
4008 if (rval != 0 && (bits & 0x01) != 0) {
4009 /*
4010 * Non-null, register marked as live reference. This
4011 * should always be a valid object.
4012 */
4013#if WITH_EXTRA_GC_CHECKS > 0
4014 if ((rval & 0x3) != 0 ||
4015 !dvmIsValidObject((Object*) rval))
4016 {
4017 /* this is very bad */
4018 LOGE("PGC: invalid ref in reg %d: 0x%08x\n",
4019 method->registersSize-1 - i, rval);
4020 } else
4021#endif
4022 {
4023 dvmMarkObjectNonNull((Object *)rval);
4024 }
4025 } else {
4026 /*
4027 * Null or non-reference, do nothing at all.
4028 */
4029#if WITH_EXTRA_GC_CHECKS > 1
4030 if (dvmIsValidObject((Object*) rval)) {
4031 /* this is normal, but we feel chatty */
4032 LOGD("PGC: ignoring valid ref in reg %d: 0x%08x\n",
4033 method->registersSize-1 - i, rval);
4034 }
4035#endif
4036 }
4037 }
4038 dvmReleaseRegisterMapLine(pMap, regVector);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08004039 }
4040 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08004041
The Android Open Source Project99409882009-03-18 22:20:24 -07004042#if WITH_EXTRA_GC_CHECKS > 1
4043 first = false;
4044#endif
4045
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08004046 /* Don't fall into an infinite loop if things get corrupted.
4047 */
4048 assert((uintptr_t)saveArea->prevFrame > (uintptr_t)framePtr ||
4049 saveArea->prevFrame == NULL);
4050 framePtr = saveArea->prevFrame;
4051 }
4052}
4053
4054static void gcScanReferenceTable(ReferenceTable *refTable)
4055{
4056 Object **op;
4057
4058 //TODO: these asserts are overkill; turn them off when things stablize.
4059 assert(refTable != NULL);
4060 assert(refTable->table != NULL);
4061 assert(refTable->nextEntry != NULL);
4062 assert((uintptr_t)refTable->nextEntry >= (uintptr_t)refTable->table);
4063 assert(refTable->nextEntry - refTable->table <= refTable->maxEntries);
4064
4065 op = refTable->table;
4066 while ((uintptr_t)op < (uintptr_t)refTable->nextEntry) {
4067 dvmMarkObjectNonNull(*(op++));
4068 }
4069}
4070
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07004071#ifdef USE_INDIRECT_REF
Andy McFaddend5ab7262009-08-25 07:19:34 -07004072static void gcScanIndirectRefTable(IndirectRefTable* pRefTable)
4073{
4074 Object** op = pRefTable->table;
4075 int numEntries = dvmIndirectRefTableEntries(pRefTable);
4076 int i;
4077
4078 for (i = 0; i < numEntries; i++) {
4079 Object* obj = *op;
4080 if (obj != NULL)
4081 dvmMarkObjectNonNull(obj);
4082 op++;
4083 }
4084}
Brian Carlstromfbdcfb92010-05-28 15:42:12 -07004085#endif
Andy McFaddend5ab7262009-08-25 07:19:34 -07004086
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08004087/*
4088 * Scan a Thread and mark any objects it references.
4089 */
4090static void gcScanThread(Thread *thread)
4091{
4092 assert(thread != NULL);
4093
4094 /*
4095 * The target thread must be suspended or in a state where it can't do
4096 * any harm (e.g. in Object.wait()). The only exception is the current
4097 * thread, which will still be active and in the "running" state.
4098 *
4099 * (Newly-created threads shouldn't be able to shift themselves to
4100 * RUNNING without a suspend-pending check, so this shouldn't cause
4101 * a false-positive.)
Andy McFadden3469a7e2010-08-04 16:09:10 -07004102 *
4103 * Since the thread is supposed to be suspended, we should have already
4104 * observed all changes to thread state, and don't need to use a memory
4105 * barrier here. It's possible we might miss a wayward unsuspended
4106 * thread on SMP, but as this is primarily a sanity check it's not
4107 * worth slowing the common case.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08004108 */
Andy McFaddend40223e2009-12-07 15:35:51 -08004109 if (thread->status == THREAD_RUNNING && !thread->isSuspended &&
4110 thread != dvmThreadSelf())
4111 {
4112 Thread* self = dvmThreadSelf();
4113 LOGW("threadid=%d: BUG: GC scanning a running thread (%d)\n",
4114 self->threadId, thread->threadId);
4115 dvmDumpThread(thread, true);
4116 LOGW("Found by:\n");
4117 dvmDumpThread(self, false);
4118
4119 /* continue anyway? */
4120 dvmAbort();
4121 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08004122
4123 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_THREAD_OBJECT, thread->threadId);
4124
4125 dvmMarkObject(thread->threadObj); // could be NULL, when constructing
4126
4127 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_NATIVE_STACK, thread->threadId);
4128
4129 dvmMarkObject(thread->exception); // usually NULL
4130 gcScanReferenceTable(&thread->internalLocalRefTable);
4131
4132 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_LOCAL, thread->threadId);
4133
Andy McFaddend5ab7262009-08-25 07:19:34 -07004134#ifdef USE_INDIRECT_REF
4135 gcScanIndirectRefTable(&thread->jniLocalRefTable);
4136#else
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08004137 gcScanReferenceTable(&thread->jniLocalRefTable);
Andy McFaddend5ab7262009-08-25 07:19:34 -07004138#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08004139
4140 if (thread->jniMonitorRefTable.table != NULL) {
4141 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_MONITOR, thread->threadId);
4142
4143 gcScanReferenceTable(&thread->jniMonitorRefTable);
4144 }
4145
4146 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JAVA_FRAME, thread->threadId);
4147
4148 gcScanInterpStackReferences(thread);
4149
4150 HPROF_CLEAR_GC_SCAN_STATE();
4151}
4152
4153static void gcScanAllThreads()
4154{
4155 Thread *thread;
4156
4157 /* Lock the thread list so we can safely use the
4158 * next/prev pointers.
4159 */
4160 dvmLockThreadList(dvmThreadSelf());
4161
4162 for (thread = gDvm.threadList; thread != NULL;
4163 thread = thread->next)
4164 {
4165 /* We need to scan our own stack, so don't special-case
4166 * the current thread.
4167 */
4168 gcScanThread(thread);
4169 }
4170
4171 dvmUnlockThreadList();
4172}
4173
4174void dvmGcScanRootThreadGroups()
4175{
4176 /* We scan the VM's list of threads instead of going
4177 * through the actual ThreadGroups, but it should be
4178 * equivalent.
4179 *
Jeff Hao97319a82009-08-12 16:57:15 -07004180 * This assumes that the ThreadGroup class object is in
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08004181 * the root set, which should always be true; it's
4182 * loaded by the built-in class loader, which is part
4183 * of the root set.
4184 */
4185 gcScanAllThreads();
4186}