blob: e4ee8e3ee4b43388d1c396ea2100ed0ca8648597 [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>
28#include <sys/resource.h>
29#include <sys/mman.h>
30#include <errno.h>
Andy McFaddend62c0b52009-08-04 15:02:12 -070031#include <fcntl.h>
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080032
San Mehat5a2056c2009-09-12 10:10:13 -070033#include <cutils/sched_policy.h>
34
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080035#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
227#define kMaxThreadId ((1<<15) - 1)
228#define kMainThreadId ((1<<1) | 1)
229
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 */
452 int cc = pthread_mutex_lock(&gDvm.threadSuspendCountLock);
453 assert(cc == 0);
454}
455
456/*
457 * Release the suspend count global lock.
458 */
459static inline void unlockThreadSuspendCount(void)
460{
461 dvmUnlockMutex(&gDvm.threadSuspendCountLock);
462}
463
464/*
465 * Grab the thread list global lock.
466 *
467 * This is held while "suspend all" is trying to make everybody stop. If
468 * the shutdown is in progress, and somebody tries to grab the lock, they'll
469 * have to wait for the GC to finish. Therefore it's important that the
470 * thread not be in RUNNING mode.
471 *
472 * We don't have to check to see if we should be suspended once we have
473 * the lock. Nobody can suspend all threads without holding the thread list
474 * lock while they do it, so by definition there isn't a GC in progress.
Andy McFadden44860362009-08-06 17:56:14 -0700475 *
476 * TODO: consider checking for suspend after acquiring the lock, and
477 * backing off if set. As stated above, it can't happen during normal
478 * execution, but it *can* happen during shutdown when daemon threads
479 * are being suspended.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800480 */
481void dvmLockThreadList(Thread* self)
482{
483 ThreadStatus oldStatus;
484
485 if (self == NULL) /* try to get it from TLS */
486 self = dvmThreadSelf();
487
488 if (self != NULL) {
489 oldStatus = self->status;
490 self->status = THREAD_VMWAIT;
491 } else {
Andy McFadden44860362009-08-06 17:56:14 -0700492 /* happens during VM shutdown */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800493 //LOGW("NULL self in dvmLockThreadList\n");
494 oldStatus = -1; // shut up gcc
495 }
496
497 int cc = pthread_mutex_lock(&gDvm.threadListLock);
498 assert(cc == 0);
499
500 if (self != NULL)
501 self->status = oldStatus;
502}
503
504/*
505 * Release the thread list global lock.
506 */
507void dvmUnlockThreadList(void)
508{
509 int cc = pthread_mutex_unlock(&gDvm.threadListLock);
510 assert(cc == 0);
511}
512
The Android Open Source Project99409882009-03-18 22:20:24 -0700513/*
514 * Convert SuspendCause to a string.
515 */
516static const char* getSuspendCauseStr(SuspendCause why)
517{
518 switch (why) {
519 case SUSPEND_NOT: return "NOT?";
520 case SUSPEND_FOR_GC: return "gc";
521 case SUSPEND_FOR_DEBUG: return "debug";
522 case SUSPEND_FOR_DEBUG_EVENT: return "debug-event";
523 case SUSPEND_FOR_STACK_DUMP: return "stack-dump";
Ben Chenga8e64a72009-10-20 13:01:36 -0700524#if defined(WITH_JIT)
525 case SUSPEND_FOR_TBL_RESIZE: return "table-resize";
526 case SUSPEND_FOR_IC_PATCH: return "inline-cache-patch";
Ben Cheng60c24f42010-01-04 12:29:56 -0800527 case SUSPEND_FOR_CC_RESET: return "reset-code-cache";
Ben Chenga8e64a72009-10-20 13:01:36 -0700528#endif
The Android Open Source Project99409882009-03-18 22:20:24 -0700529 default: return "UNKNOWN";
530 }
531}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800532
533/*
534 * Grab the "thread suspend" lock. This is required to prevent the
535 * GC and the debugger from simultaneously suspending all threads.
536 *
537 * If we fail to get the lock, somebody else is trying to suspend all
538 * threads -- including us. If we go to sleep on the lock we'll deadlock
539 * the VM. Loop until we get it or somebody puts us to sleep.
540 */
541static void lockThreadSuspend(const char* who, SuspendCause why)
542{
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800543 const int kSpinSleepTime = 3*1000*1000; /* 3s */
544 u8 startWhen = 0; // init req'd to placate gcc
545 int sleepIter = 0;
546 int cc;
Jeff Hao97319a82009-08-12 16:57:15 -0700547
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800548 do {
549 cc = pthread_mutex_trylock(&gDvm._threadSuspendLock);
550 if (cc != 0) {
551 if (!dvmCheckSuspendPending(NULL)) {
552 /*
Andy McFadden2aa43612009-06-17 16:29:30 -0700553 * Could be that a resume-all is in progress, and something
554 * grabbed the CPU when the wakeup was broadcast. The thread
555 * performing the resume hasn't had a chance to release the
Andy McFaddene8059be2009-06-04 14:34:14 -0700556 * thread suspend lock. (We release before the broadcast,
557 * so this should be a narrow window.)
Andy McFadden2aa43612009-06-17 16:29:30 -0700558 *
559 * Could be we hit the window as a suspend was started,
560 * and the lock has been grabbed but the suspend counts
561 * haven't been incremented yet.
The Android Open Source Project99409882009-03-18 22:20:24 -0700562 *
563 * Could be an unusual JNI thread-attach thing.
564 *
565 * Could be the debugger telling us to resume at roughly
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800566 * the same time we're posting an event.
Ben Chenga8e64a72009-10-20 13:01:36 -0700567 *
568 * Could be two app threads both want to patch predicted
569 * chaining cells around the same time.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800570 */
The Android Open Source Project99409882009-03-18 22:20:24 -0700571 LOGI("threadid=%d ODD: want thread-suspend lock (%s:%s),"
572 " it's held, no suspend pending\n",
573 dvmThreadSelf()->threadId, who, getSuspendCauseStr(why));
574 } else {
575 /* we suspended; reset timeout */
576 sleepIter = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800577 }
578
579 /* give the lock-holder a chance to do some work */
580 if (sleepIter == 0)
581 startWhen = dvmGetRelativeTimeUsec();
582 if (!dvmIterativeSleep(sleepIter++, kSpinSleepTime, startWhen)) {
The Android Open Source Project99409882009-03-18 22:20:24 -0700583 LOGE("threadid=%d: couldn't get thread-suspend lock (%s:%s),"
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800584 " bailing\n",
The Android Open Source Project99409882009-03-18 22:20:24 -0700585 dvmThreadSelf()->threadId, who, getSuspendCauseStr(why));
Andy McFadden2aa43612009-06-17 16:29:30 -0700586 /* threads are not suspended, thread dump could crash */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800587 dvmDumpAllThreads(false);
588 dvmAbort();
589 }
590 }
591 } while (cc != 0);
592 assert(cc == 0);
593}
594
595/*
596 * Release the "thread suspend" lock.
597 */
598static inline void unlockThreadSuspend(void)
599{
600 int cc = pthread_mutex_unlock(&gDvm._threadSuspendLock);
601 assert(cc == 0);
602}
603
604
605/*
606 * Kill any daemon threads that still exist. All of ours should be
607 * stopped, so these should be Thread objects or JNI-attached threads
608 * started by the application. Actively-running threads are likely
609 * to crash the process if they continue to execute while the VM
610 * shuts down, so we really need to kill or suspend them. (If we want
611 * the VM to restart within this process, we need to kill them, but that
612 * leaves open the possibility of orphaned resources.)
613 *
614 * Waiting for the thread to suspend may be unwise at this point, but
615 * if one of these is wedged in a critical section then we probably
616 * would've locked up on the last GC attempt.
617 *
618 * It's possible for this function to get called after a failed
619 * initialization, so be careful with assumptions about the environment.
Andy McFadden44860362009-08-06 17:56:14 -0700620 *
621 * This will be called from whatever thread calls DestroyJavaVM, usually
622 * but not necessarily the main thread. It's likely, but not guaranteed,
623 * that the current thread has already been cleaned up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800624 */
625void dvmSlayDaemons(void)
626{
Andy McFadden44860362009-08-06 17:56:14 -0700627 Thread* self = dvmThreadSelf(); // may be null
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800628 Thread* target;
Andy McFadden44860362009-08-06 17:56:14 -0700629 int threadId = 0;
630 bool doWait = false;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800631
632 //dvmEnterCritical(self);
633 dvmLockThreadList(self);
634
Andy McFadden44860362009-08-06 17:56:14 -0700635 if (self != NULL)
636 threadId = self->threadId;
637
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800638 target = gDvm.threadList;
639 while (target != NULL) {
640 if (target == self) {
641 target = target->next;
642 continue;
643 }
644
645 if (!dvmGetFieldBoolean(target->threadObj,
646 gDvm.offJavaLangThread_daemon))
647 {
Andy McFadden44860362009-08-06 17:56:14 -0700648 /* should never happen; suspend it with the rest */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800649 LOGW("threadid=%d: non-daemon id=%d still running at shutdown?!\n",
Andy McFadden44860362009-08-06 17:56:14 -0700650 threadId, target->threadId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800651 }
652
Andy McFadden44860362009-08-06 17:56:14 -0700653 char* threadName = dvmGetThreadName(target);
654 LOGD("threadid=%d: suspending daemon id=%d name='%s'\n",
655 threadId, target->threadId, threadName);
656 free(threadName);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800657
Andy McFadden44860362009-08-06 17:56:14 -0700658 /* mark as suspended */
659 lockThreadSuspendCount();
660 dvmAddToThreadSuspendCount(&target->suspendCount, 1);
661 unlockThreadSuspendCount();
662 doWait = true;
663
664 target = target->next;
665 }
666
667 //dvmDumpAllThreads(false);
668
669 /*
670 * Unlock the thread list, relocking it later if necessary. It's
671 * possible a thread is in VMWAIT after calling dvmLockThreadList,
672 * and that function *doesn't* check for pending suspend after
673 * acquiring the lock. We want to let them finish their business
674 * and see the pending suspend before we continue here.
675 *
676 * There's no guarantee of mutex fairness, so this might not work.
677 * (The alternative is to have dvmLockThreadList check for suspend
678 * after acquiring the lock and back off, something we should consider.)
679 */
680 dvmUnlockThreadList();
681
682 if (doWait) {
683 usleep(200 * 1000);
684
685 dvmLockThreadList(self);
686
687 /*
688 * Sleep for a bit until the threads have suspended. We're trying
689 * to exit, so don't wait for too long.
690 */
691 int i;
692 for (i = 0; i < 10; i++) {
693 bool allSuspended = true;
694
695 target = gDvm.threadList;
696 while (target != NULL) {
697 if (target == self) {
698 target = target->next;
699 continue;
700 }
701
702 if (target->status == THREAD_RUNNING && !target->isSuspended) {
703 LOGD("threadid=%d not ready yet\n", target->threadId);
704 allSuspended = false;
705 break;
706 }
707
708 target = target->next;
709 }
710
711 if (allSuspended) {
712 LOGD("threadid=%d: all daemons have suspended\n", threadId);
713 break;
714 } else {
715 LOGD("threadid=%d: waiting for daemons to suspend\n", threadId);
716 }
717
718 usleep(200 * 1000);
719 }
720 dvmUnlockThreadList();
721 }
722
723#if 0 /* bad things happen if they come out of JNI or "spuriously" wake up */
724 /*
725 * Abandon the threads and recover their resources.
726 */
727 target = gDvm.threadList;
728 while (target != NULL) {
729 Thread* nextTarget = target->next;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800730 unlinkThread(target);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800731 freeThread(target);
732 target = nextTarget;
733 }
Andy McFadden44860362009-08-06 17:56:14 -0700734#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800735
Andy McFadden44860362009-08-06 17:56:14 -0700736 //dvmDumpAllThreads(true);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800737}
738
739
740/*
741 * Finish preparing the parts of the Thread struct required to support
742 * JNI registration.
743 */
744bool dvmPrepMainForJni(JNIEnv* pEnv)
745{
746 Thread* self;
747
748 /* main thread is always first in list at this point */
749 self = gDvm.threadList;
750 assert(self->threadId == kMainThreadId);
751
752 /* create a "fake" JNI frame at the top of the main thread interp stack */
753 if (!createFakeEntryFrame(self))
754 return false;
755
756 /* fill these in, since they weren't ready at dvmCreateJNIEnv time */
757 dvmSetJniEnvThreadId(pEnv, self);
758 dvmSetThreadJNIEnv(self, (JNIEnv*) pEnv);
759
760 return true;
761}
762
763
764/*
765 * Finish preparing the main thread, allocating some objects to represent
766 * it. As part of doing so, we finish initializing Thread and ThreadGroup.
Andy McFaddena1a7a342009-05-04 13:29:30 -0700767 * This will execute some interpreted code (e.g. class initializers).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800768 */
769bool dvmPrepMainThread(void)
770{
771 Thread* thread;
772 Object* groupObj;
773 Object* threadObj;
774 Object* vmThreadObj;
775 StringObject* threadNameStr;
776 Method* init;
777 JValue unused;
778
779 LOGV("+++ finishing prep on main VM thread\n");
780
781 /* main thread is always first in list at this point */
782 thread = gDvm.threadList;
783 assert(thread->threadId == kMainThreadId);
784
785 /*
786 * Make sure the classes are initialized. We have to do this before
787 * we create an instance of them.
788 */
789 if (!dvmInitClass(gDvm.classJavaLangClass)) {
790 LOGE("'Class' class failed to initialize\n");
791 return false;
792 }
793 if (!dvmInitClass(gDvm.classJavaLangThreadGroup) ||
794 !dvmInitClass(gDvm.classJavaLangThread) ||
795 !dvmInitClass(gDvm.classJavaLangVMThread))
796 {
797 LOGE("thread classes failed to initialize\n");
798 return false;
799 }
800
801 groupObj = dvmGetMainThreadGroup();
802 if (groupObj == NULL)
803 return false;
804
805 /*
806 * Allocate and construct a Thread with the internal-creation
807 * constructor.
808 */
809 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_DEFAULT);
810 if (threadObj == NULL) {
811 LOGE("unable to allocate main thread object\n");
812 return false;
813 }
814 dvmReleaseTrackedAlloc(threadObj, NULL);
815
816 threadNameStr = dvmCreateStringFromCstr("main", ALLOC_DEFAULT);
817 if (threadNameStr == NULL)
818 return false;
819 dvmReleaseTrackedAlloc((Object*)threadNameStr, NULL);
820
821 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
822 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
823 assert(init != NULL);
824 dvmCallMethod(thread, init, threadObj, &unused, groupObj, threadNameStr,
825 THREAD_NORM_PRIORITY, false);
826 if (dvmCheckException(thread)) {
827 LOGE("exception thrown while constructing main thread object\n");
828 return false;
829 }
830
831 /*
832 * Allocate and construct a VMThread.
833 */
834 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
835 if (vmThreadObj == NULL) {
836 LOGE("unable to allocate main vmthread object\n");
837 return false;
838 }
839 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
840
841 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangVMThread, "<init>",
842 "(Ljava/lang/Thread;)V");
843 dvmCallMethod(thread, init, vmThreadObj, &unused, threadObj);
844 if (dvmCheckException(thread)) {
845 LOGE("exception thrown while constructing main vmthread object\n");
846 return false;
847 }
848
849 /* set the VMThread.vmData field to our Thread struct */
850 assert(gDvm.offJavaLangVMThread_vmData != 0);
851 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)thread);
852
853 /*
854 * Stuff the VMThread back into the Thread. From this point on, other
Andy McFaddena1a7a342009-05-04 13:29:30 -0700855 * Threads will see that this Thread is running (at least, they would,
856 * if there were any).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800857 */
858 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread,
859 vmThreadObj);
860
861 thread->threadObj = threadObj;
862
863 /*
Andy McFaddena1a7a342009-05-04 13:29:30 -0700864 * Set the context class loader. This invokes a ClassLoader method,
865 * which could conceivably call Thread.currentThread(), so we want the
866 * Thread to be fully configured before we do this.
867 */
868 Object* systemLoader = dvmGetSystemClassLoader();
869 if (systemLoader == NULL) {
870 LOGW("WARNING: system class loader is NULL (setting main ctxt)\n");
871 /* keep going */
872 }
873 int ctxtClassLoaderOffset = dvmFindFieldOffset(gDvm.classJavaLangThread,
874 "contextClassLoader", "Ljava/lang/ClassLoader;");
875 if (ctxtClassLoaderOffset < 0) {
876 LOGE("Unable to find contextClassLoader field in Thread\n");
877 return false;
878 }
879 dvmSetFieldObject(threadObj, ctxtClassLoaderOffset, systemLoader);
880
881 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800882 * Finish our thread prep.
883 */
884
885 /* include self in non-daemon threads (mainly for AttachCurrentThread) */
886 gDvm.nonDaemonThreadCount++;
887
888 return true;
889}
890
891
892/*
893 * Alloc and initialize a Thread struct.
894 *
895 * "threadObj" is the java.lang.Thread object. It will be NULL for the
896 * main VM thread, but non-NULL for everything else.
897 *
898 * Does not create any objects, just stuff on the system (malloc) heap. (If
899 * this changes, we need to use ALLOC_NO_GC. And also verify that we're
900 * ready to load classes at the time this is called.)
901 */
902static Thread* allocThread(int interpStackSize)
903{
904 Thread* thread;
905 u1* stackBottom;
906
907 thread = (Thread*) calloc(1, sizeof(Thread));
908 if (thread == NULL)
909 return NULL;
910
Jeff Hao97319a82009-08-12 16:57:15 -0700911#if defined(WITH_SELF_VERIFICATION)
912 if (dvmSelfVerificationShadowSpaceAlloc(thread) == NULL)
913 return NULL;
914#endif
915
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800916 assert(interpStackSize >= kMinStackSize && interpStackSize <=kMaxStackSize);
917
918 thread->status = THREAD_INITIALIZING;
919 thread->suspendCount = 0;
920
921#ifdef WITH_ALLOC_LIMITS
922 thread->allocLimit = -1;
923#endif
924
925 /*
926 * Allocate and initialize the interpreted code stack. We essentially
927 * "lose" the alloc pointer, which points at the bottom of the stack,
928 * but we can get it back later because we know how big the stack is.
929 *
930 * The stack must be aligned on a 4-byte boundary.
931 */
932#ifdef MALLOC_INTERP_STACK
933 stackBottom = (u1*) malloc(interpStackSize);
934 if (stackBottom == NULL) {
Jeff Hao97319a82009-08-12 16:57:15 -0700935#if defined(WITH_SELF_VERIFICATION)
936 dvmSelfVerificationShadowSpaceFree(thread);
937#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800938 free(thread);
939 return NULL;
940 }
941 memset(stackBottom, 0xc5, interpStackSize); // stop valgrind complaints
942#else
943 stackBottom = mmap(NULL, interpStackSize, PROT_READ | PROT_WRITE,
944 MAP_PRIVATE | MAP_ANON, -1, 0);
945 if (stackBottom == MAP_FAILED) {
Jeff Hao97319a82009-08-12 16:57:15 -0700946#if defined(WITH_SELF_VERIFICATION)
947 dvmSelfVerificationShadowSpaceFree(thread);
948#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800949 free(thread);
950 return NULL;
951 }
952#endif
953
954 assert(((u4)stackBottom & 0x03) == 0); // looks like our malloc ensures this
955 thread->interpStackSize = interpStackSize;
956 thread->interpStackStart = stackBottom + interpStackSize;
957 thread->interpStackEnd = stackBottom + STACK_OVERFLOW_RESERVE;
958
959 /* give the thread code a chance to set things up */
960 dvmInitInterpStack(thread, interpStackSize);
961
962 return thread;
963}
964
965/*
966 * Get a meaningful thread ID. At present this only has meaning under Linux,
967 * where getpid() and gettid() sometimes agree and sometimes don't depending
968 * on your thread model (try "export LD_ASSUME_KERNEL=2.4.19").
969 */
970pid_t dvmGetSysThreadId(void)
971{
972#ifdef HAVE_GETTID
973 return gettid();
974#else
975 return getpid();
976#endif
977}
978
979/*
980 * Finish initialization of a Thread struct.
981 *
982 * This must be called while executing in the new thread, but before the
983 * thread is added to the thread list.
984 *
985 * *** NOTE: The threadListLock must be held by the caller (needed for
986 * assignThreadId()).
987 */
988static bool prepareThread(Thread* thread)
989{
990 assignThreadId(thread);
991 thread->handle = pthread_self();
992 thread->systemTid = dvmGetSysThreadId();
993
994 //LOGI("SYSTEM TID IS %d (pid is %d)\n", (int) thread->systemTid,
995 // (int) getpid());
996 setThreadSelf(thread);
997
998 LOGV("threadid=%d: interp stack at %p\n",
999 thread->threadId, thread->interpStackStart - thread->interpStackSize);
1000
1001 /*
1002 * Initialize invokeReq.
1003 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001004 dvmInitMutex(&thread->invokeReq.lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001005 pthread_cond_init(&thread->invokeReq.cv, NULL);
1006
1007 /*
1008 * Initialize our reference tracking tables.
1009 *
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001010 * Most threads won't use jniMonitorRefTable, so we clear out the
1011 * structure but don't call the init function (which allocs storage).
1012 */
Andy McFaddend5ab7262009-08-25 07:19:34 -07001013#ifdef USE_INDIRECT_REF
1014 if (!dvmInitIndirectRefTable(&thread->jniLocalRefTable,
1015 kJniLocalRefMin, kJniLocalRefMax, kIndirectKindLocal))
1016 return false;
1017#else
1018 /*
1019 * The JNI local ref table *must* be fixed-size because we keep pointers
1020 * into the table in our stack frames.
1021 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001022 if (!dvmInitReferenceTable(&thread->jniLocalRefTable,
1023 kJniLocalRefMax, kJniLocalRefMax))
1024 return false;
Andy McFaddend5ab7262009-08-25 07:19:34 -07001025#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001026 if (!dvmInitReferenceTable(&thread->internalLocalRefTable,
1027 kInternalRefDefault, kInternalRefMax))
1028 return false;
1029
1030 memset(&thread->jniMonitorRefTable, 0, sizeof(thread->jniMonitorRefTable));
1031
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001032 pthread_cond_init(&thread->waitCond, NULL);
1033 dvmInitMutex(&thread->waitMutex);
1034
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001035 return true;
1036}
1037
1038/*
1039 * Remove a thread from the internal list.
1040 * Clear out the links to make it obvious that the thread is
1041 * no longer on the list. Caller must hold gDvm.threadListLock.
1042 */
1043static void unlinkThread(Thread* thread)
1044{
1045 LOG_THREAD("threadid=%d: removing from list\n", thread->threadId);
1046 if (thread == gDvm.threadList) {
1047 assert(thread->prev == NULL);
1048 gDvm.threadList = thread->next;
1049 } else {
1050 assert(thread->prev != NULL);
1051 thread->prev->next = thread->next;
1052 }
1053 if (thread->next != NULL)
1054 thread->next->prev = thread->prev;
1055 thread->prev = thread->next = NULL;
1056}
1057
1058/*
1059 * Free a Thread struct, and all the stuff allocated within.
1060 */
1061static void freeThread(Thread* thread)
1062{
1063 if (thread == NULL)
1064 return;
1065
1066 /* thread->threadId is zero at this point */
1067 LOGVV("threadid=%d: freeing\n", thread->threadId);
1068
1069 if (thread->interpStackStart != NULL) {
1070 u1* interpStackBottom;
1071
1072 interpStackBottom = thread->interpStackStart;
1073 interpStackBottom -= thread->interpStackSize;
1074#ifdef MALLOC_INTERP_STACK
1075 free(interpStackBottom);
1076#else
1077 if (munmap(interpStackBottom, thread->interpStackSize) != 0)
1078 LOGW("munmap(thread stack) failed\n");
1079#endif
1080 }
1081
Andy McFaddend5ab7262009-08-25 07:19:34 -07001082#ifdef USE_INDIRECT_REF
1083 dvmClearIndirectRefTable(&thread->jniLocalRefTable);
1084#else
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001085 dvmClearReferenceTable(&thread->jniLocalRefTable);
Andy McFaddend5ab7262009-08-25 07:19:34 -07001086#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001087 dvmClearReferenceTable(&thread->internalLocalRefTable);
1088 if (&thread->jniMonitorRefTable.table != NULL)
1089 dvmClearReferenceTable(&thread->jniMonitorRefTable);
1090
Jeff Hao97319a82009-08-12 16:57:15 -07001091#if defined(WITH_SELF_VERIFICATION)
1092 dvmSelfVerificationShadowSpaceFree(thread);
1093#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001094 free(thread);
1095}
1096
1097/*
1098 * Like pthread_self(), but on a Thread*.
1099 */
1100Thread* dvmThreadSelf(void)
1101{
1102 return (Thread*) pthread_getspecific(gDvm.pthreadKeySelf);
1103}
1104
1105/*
1106 * Explore our sense of self. Stuffs the thread pointer into TLS.
1107 */
1108static void setThreadSelf(Thread* thread)
1109{
1110 int cc;
1111
1112 cc = pthread_setspecific(gDvm.pthreadKeySelf, thread);
1113 if (cc != 0) {
1114 /*
1115 * Sometimes this fails under Bionic with EINVAL during shutdown.
1116 * This can happen if the timing is just right, e.g. a thread
1117 * fails to attach during shutdown, but the "fail" path calls
1118 * here to ensure we clean up after ourselves.
1119 */
1120 if (thread != NULL) {
1121 LOGE("pthread_setspecific(%p) failed, err=%d\n", thread, cc);
1122 dvmAbort(); /* the world is fundamentally hosed */
1123 }
1124 }
1125}
1126
1127/*
1128 * This is associated with the pthreadKeySelf key. It's called by the
1129 * pthread library when a thread is exiting and the "self" pointer in TLS
1130 * is non-NULL, meaning the VM hasn't had a chance to clean up. In normal
Andy McFadden909ce242009-12-10 16:38:30 -08001131 * operation this will not be called.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001132 *
1133 * This is mainly of use to ensure that we don't leak resources if, for
1134 * example, a thread attaches itself to us with AttachCurrentThread and
1135 * then exits without notifying the VM.
Andy McFadden34e25bb2009-04-15 13:27:12 -07001136 *
1137 * We could do the detach here instead of aborting, but this will lead to
1138 * portability problems. Other implementations do not do this check and
1139 * will simply be unaware that the thread has exited, leading to resource
1140 * leaks (and, if this is a non-daemon thread, an infinite hang when the
1141 * VM tries to shut down).
Andy McFadden909ce242009-12-10 16:38:30 -08001142 *
1143 * Because some implementations may want to use the pthread destructor
1144 * to initiate the detach, and the ordering of destructors is not defined,
1145 * we want to iterate a couple of times to give those a chance to run.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001146 */
1147static void threadExitCheck(void* arg)
1148{
Andy McFadden909ce242009-12-10 16:38:30 -08001149 const int kMaxCount = 2;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001150
Andy McFadden909ce242009-12-10 16:38:30 -08001151 Thread* self = (Thread*) arg;
1152 assert(self != NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001153
Andy McFadden909ce242009-12-10 16:38:30 -08001154 LOGV("threadid=%d: threadExitCheck(%p) count=%d\n",
1155 self->threadId, arg, self->threadExitCheckCount);
1156
1157 if (self->status == THREAD_ZOMBIE) {
1158 LOGW("threadid=%d: Weird -- shouldn't be in threadExitCheck\n",
1159 self->threadId);
1160 return;
1161 }
1162
1163 if (self->threadExitCheckCount < kMaxCount) {
1164 /*
1165 * Spin a couple of times to let other destructors fire.
1166 */
1167 LOGD("threadid=%d: thread exiting, not yet detached (count=%d)\n",
1168 self->threadId, self->threadExitCheckCount);
1169 self->threadExitCheckCount++;
1170 int cc = pthread_setspecific(gDvm.pthreadKeySelf, self);
1171 if (cc != 0) {
1172 LOGE("threadid=%d: unable to re-add thread to TLS\n",
1173 self->threadId);
1174 dvmAbort();
1175 }
1176 } else {
1177 LOGE("threadid=%d: native thread exited without detaching\n",
1178 self->threadId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001179 dvmAbort();
1180 }
1181}
1182
1183
1184/*
1185 * Assign the threadId. This needs to be a small integer so that our
1186 * "thin" locks fit in a small number of bits.
1187 *
1188 * We reserve zero for use as an invalid ID.
1189 *
1190 * This must be called with threadListLock held (unless we're still
1191 * initializing the system).
1192 */
1193static void assignThreadId(Thread* thread)
1194{
1195 /* Find a small unique integer. threadIdMap is a vector of
1196 * kMaxThreadId bits; dvmAllocBit() returns the index of a
1197 * bit, meaning that it will always be < kMaxThreadId.
1198 *
1199 * The thin locking magic requires that the low bit is always
1200 * set, so we do it once, here.
1201 */
1202 int num = dvmAllocBit(gDvm.threadIdMap);
1203 if (num < 0) {
1204 LOGE("Ran out of thread IDs\n");
1205 dvmAbort(); // TODO: make this a non-fatal error result
1206 }
1207
1208 thread->threadId = ((num + 1) << 1) | 1;
1209
1210 assert(thread->threadId != 0);
1211 assert(thread->threadId != DVM_LOCK_INITIAL_THIN_VALUE);
1212}
1213
1214/*
1215 * Give back the thread ID.
1216 */
1217static void releaseThreadId(Thread* thread)
1218{
1219 assert(thread->threadId > 0);
1220 dvmClearBit(gDvm.threadIdMap, (thread->threadId >> 1) - 1);
1221 thread->threadId = 0;
1222}
1223
1224
1225/*
1226 * Add a stack frame that makes it look like the native code in the main
1227 * thread was originally invoked from interpreted code. This gives us a
1228 * place to hang JNI local references. The VM spec says (v2 5.2) that the
1229 * VM begins by executing "main" in a class, so in a way this brings us
1230 * closer to the spec.
1231 */
1232static bool createFakeEntryFrame(Thread* thread)
1233{
1234 assert(thread->threadId == kMainThreadId); // main thread only
1235
1236 /* find the method on first use */
1237 if (gDvm.methFakeNativeEntry == NULL) {
1238 ClassObject* nativeStart;
1239 Method* mainMeth;
1240
1241 nativeStart = dvmFindSystemClassNoInit(
1242 "Ldalvik/system/NativeStart;");
1243 if (nativeStart == NULL) {
1244 LOGE("Unable to find dalvik.system.NativeStart class\n");
1245 return false;
1246 }
1247
1248 /*
1249 * Because we are creating a frame that represents application code, we
1250 * want to stuff the application class loader into the method's class
1251 * loader field, even though we're using the system class loader to
1252 * load it. This makes life easier over in JNI FindClass (though it
1253 * could bite us in other ways).
1254 *
1255 * Unfortunately this is occurring too early in the initialization,
1256 * of necessity coming before JNI is initialized, and we're not quite
1257 * ready to set up the application class loader.
1258 *
1259 * So we save a pointer to the method in gDvm.methFakeNativeEntry
1260 * and check it in FindClass. The method is private so nobody else
1261 * can call it.
1262 */
1263 //nativeStart->classLoader = dvmGetSystemClassLoader();
1264
1265 mainMeth = dvmFindDirectMethodByDescriptor(nativeStart,
1266 "main", "([Ljava/lang/String;)V");
1267 if (mainMeth == NULL) {
1268 LOGE("Unable to find 'main' in dalvik.system.NativeStart\n");
1269 return false;
1270 }
1271
1272 gDvm.methFakeNativeEntry = mainMeth;
1273 }
1274
1275 return dvmPushJNIFrame(thread, gDvm.methFakeNativeEntry);
1276}
1277
1278
1279/*
1280 * Add a stack frame that makes it look like the native thread has been
1281 * executing interpreted code. This gives us a place to hang JNI local
1282 * references.
1283 */
1284static bool createFakeRunFrame(Thread* thread)
1285{
1286 ClassObject* nativeStart;
1287 Method* runMeth;
1288
1289 assert(thread->threadId != 1); // not for main thread
1290
1291 nativeStart =
1292 dvmFindSystemClassNoInit("Ldalvik/system/NativeStart;");
1293 if (nativeStart == NULL) {
1294 LOGE("Unable to find dalvik.system.NativeStart class\n");
1295 return false;
1296 }
1297
1298 runMeth = dvmFindVirtualMethodByDescriptor(nativeStart, "run", "()V");
1299 if (runMeth == NULL) {
1300 LOGE("Unable to find 'run' in dalvik.system.NativeStart\n");
1301 return false;
1302 }
1303
1304 return dvmPushJNIFrame(thread, runMeth);
1305}
1306
1307/*
1308 * Helper function to set the name of the current thread
1309 */
1310static void setThreadName(const char *threadName)
1311{
1312#if defined(HAVE_PRCTL)
1313 int hasAt = 0;
1314 int hasDot = 0;
1315 const char *s = threadName;
1316 while (*s) {
1317 if (*s == '.') hasDot = 1;
1318 else if (*s == '@') hasAt = 1;
1319 s++;
1320 }
1321 int len = s - threadName;
1322 if (len < 15 || hasAt || !hasDot) {
1323 s = threadName;
1324 } else {
1325 s = threadName + len - 15;
1326 }
1327 prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
1328#endif
1329}
1330
1331/*
1332 * Create a thread as a result of java.lang.Thread.start().
1333 *
1334 * We do have to worry about some concurrency problems, e.g. programs
1335 * that try to call Thread.start() on the same object from multiple threads.
1336 * (This will fail for all but one, but we have to make sure that it succeeds
1337 * for exactly one.)
1338 *
1339 * Some of the complexity here arises from our desire to mimic the
1340 * Thread vs. VMThread class decomposition we inherited. We've been given
1341 * a Thread, and now we need to create a VMThread and then populate both
1342 * objects. We also need to create one of our internal Thread objects.
1343 *
1344 * Pass in a stack size of 0 to get the default.
1345 */
1346bool dvmCreateInterpThread(Object* threadObj, int reqStackSize)
1347{
1348 pthread_attr_t threadAttr;
1349 pthread_t threadHandle;
1350 Thread* self;
1351 Thread* newThread = NULL;
1352 Object* vmThreadObj = NULL;
1353 int stackSize;
1354
1355 assert(threadObj != NULL);
1356
1357 if(gDvm.zygote) {
Bob Lee9dc72a32009-09-04 18:28:16 -07001358 // Allow the sampling profiler thread. We shut it down before forking.
1359 StringObject* nameStr = (StringObject*) dvmGetFieldObject(threadObj,
1360 gDvm.offJavaLangThread_name);
1361 char* threadName = dvmCreateCstrFromString(nameStr);
1362 bool profilerThread = strcmp(threadName, "SamplingProfiler") == 0;
1363 free(threadName);
1364 if (!profilerThread) {
1365 dvmThrowException("Ljava/lang/IllegalStateException;",
1366 "No new threads in -Xzygote mode");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001367
Bob Lee9dc72a32009-09-04 18:28:16 -07001368 goto fail;
1369 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001370 }
1371
1372 self = dvmThreadSelf();
1373 if (reqStackSize == 0)
1374 stackSize = gDvm.stackSize;
1375 else if (reqStackSize < kMinStackSize)
1376 stackSize = kMinStackSize;
1377 else if (reqStackSize > kMaxStackSize)
1378 stackSize = kMaxStackSize;
1379 else
1380 stackSize = reqStackSize;
1381
1382 pthread_attr_init(&threadAttr);
1383 pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1384
1385 /*
1386 * To minimize the time spent in the critical section, we allocate the
1387 * vmThread object here.
1388 */
1389 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
1390 if (vmThreadObj == NULL)
1391 goto fail;
1392
1393 newThread = allocThread(stackSize);
1394 if (newThread == NULL)
1395 goto fail;
1396 newThread->threadObj = threadObj;
1397
1398 assert(newThread->status == THREAD_INITIALIZING);
1399
1400 /*
1401 * We need to lock out other threads while we test and set the
1402 * "vmThread" field in java.lang.Thread, because we use that to determine
1403 * if this thread has been started before. We use the thread list lock
1404 * because it's handy and we're going to need to grab it again soon
1405 * anyway.
1406 */
1407 dvmLockThreadList(self);
1408
1409 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
1410 dvmUnlockThreadList();
1411 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
1412 "thread has already been started");
1413 goto fail;
1414 }
1415
1416 /*
1417 * There are actually three data structures: Thread (object), VMThread
1418 * (object), and Thread (C struct). All of them point to at least one
1419 * other.
1420 *
1421 * As soon as "VMThread.vmData" is assigned, other threads can start
1422 * making calls into us (e.g. setPriority).
1423 */
1424 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)newThread);
1425 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
1426
1427 /*
1428 * Thread creation might take a while, so release the lock.
1429 */
1430 dvmUnlockThreadList();
1431
Andy McFadden2aa43612009-06-17 16:29:30 -07001432 int cc, oldStatus;
1433 oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
1434 cc = pthread_create(&threadHandle, &threadAttr, interpThreadStart,
1435 newThread);
1436 oldStatus = dvmChangeStatus(self, oldStatus);
1437
1438 if (cc != 0) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001439 /*
1440 * Failure generally indicates that we have exceeded system
1441 * resource limits. VirtualMachineError is probably too severe,
1442 * so use OutOfMemoryError.
1443 */
1444 LOGE("Thread creation failed (err=%s)\n", strerror(errno));
1445
1446 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, NULL);
1447
1448 dvmThrowException("Ljava/lang/OutOfMemoryError;",
1449 "thread creation failed");
1450 goto fail;
1451 }
1452
1453 /*
1454 * We need to wait for the thread to start. Otherwise, depending on
1455 * the whims of the OS scheduler, we could return and the code in our
1456 * thread could try to do operations on the new thread before it had
1457 * finished starting.
1458 *
1459 * The new thread will lock the thread list, change its state to
1460 * THREAD_STARTING, broadcast to gDvm.threadStartCond, and then sleep
1461 * on gDvm.threadStartCond (which uses the thread list lock). This
1462 * thread (the parent) will either see that the thread is already ready
1463 * after we grab the thread list lock, or will be awakened from the
1464 * condition variable on the broadcast.
1465 *
1466 * We don't want to stall the rest of the VM while the new thread
1467 * starts, which can happen if the GC wakes up at the wrong moment.
1468 * So, we change our own status to VMWAIT, and self-suspend if
1469 * necessary after we finish adding the new thread.
1470 *
1471 *
1472 * We have to deal with an odd race with the GC/debugger suspension
1473 * mechanism when creating a new thread. The information about whether
1474 * or not a thread should be suspended is contained entirely within
1475 * the Thread struct; this is usually cleaner to deal with than having
1476 * one or more globally-visible suspension flags. The trouble is that
1477 * we could create the thread while the VM is trying to suspend all
1478 * threads. The suspend-count won't be nonzero for the new thread,
1479 * so dvmChangeStatus(THREAD_RUNNING) won't cause a suspension.
1480 *
1481 * The easiest way to deal with this is to prevent the new thread from
1482 * running until the parent says it's okay. This results in the
Andy McFadden2aa43612009-06-17 16:29:30 -07001483 * following (correct) sequence of events for a "badly timed" GC
1484 * (where '-' is us, 'o' is the child, and '+' is some other thread):
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001485 *
1486 * - call pthread_create()
1487 * - lock thread list
1488 * - put self into THREAD_VMWAIT so GC doesn't wait for us
1489 * - sleep on condition var (mutex = thread list lock) until child starts
1490 * + GC triggered by another thread
1491 * + thread list locked; suspend counts updated; thread list unlocked
1492 * + loop waiting for all runnable threads to suspend
1493 * + success, start GC
1494 * o child thread wakes, signals condition var to wake parent
1495 * o child waits for parent ack on condition variable
1496 * - we wake up, locking thread list
1497 * - add child to thread list
1498 * - unlock thread list
1499 * - change our state back to THREAD_RUNNING; GC causes us to suspend
1500 * + GC finishes; all threads in thread list are resumed
1501 * - lock thread list
1502 * - set child to THREAD_VMWAIT, and signal it to start
1503 * - unlock thread list
1504 * o child resumes
1505 * o child changes state to THREAD_RUNNING
1506 *
1507 * The above shows the GC starting up during thread creation, but if
1508 * it starts anywhere after VMThread.create() is called it will
1509 * produce the same series of events.
1510 *
1511 * Once the child is in the thread list, it will be suspended and
1512 * resumed like any other thread. In the above scenario the resume-all
1513 * code will try to resume the new thread, which was never actually
1514 * suspended, and try to decrement the child's thread suspend count to -1.
1515 * We can catch this in the resume-all code.
1516 *
1517 * Bouncing back and forth between threads like this adds a small amount
1518 * of scheduler overhead to thread startup.
1519 *
1520 * One alternative to having the child wait for the parent would be
1521 * to have the child inherit the parents' suspension count. This
1522 * would work for a GC, since we can safely assume that the parent
1523 * thread didn't cause it, but we must only do so if the parent suspension
1524 * was caused by a suspend-all. If the parent was being asked to
1525 * suspend singly by the debugger, the child should not inherit the value.
1526 *
1527 * We could also have a global "new thread suspend count" that gets
1528 * picked up by new threads before changing state to THREAD_RUNNING.
1529 * This would be protected by the thread list lock and set by a
1530 * suspend-all.
1531 */
1532 dvmLockThreadList(self);
1533 assert(self->status == THREAD_RUNNING);
1534 self->status = THREAD_VMWAIT;
1535 while (newThread->status != THREAD_STARTING)
1536 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1537
1538 LOG_THREAD("threadid=%d: adding to list\n", newThread->threadId);
1539 newThread->next = gDvm.threadList->next;
1540 if (newThread->next != NULL)
1541 newThread->next->prev = newThread;
1542 newThread->prev = gDvm.threadList;
1543 gDvm.threadList->next = newThread;
1544
1545 if (!dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon))
1546 gDvm.nonDaemonThreadCount++; // guarded by thread list lock
1547
1548 dvmUnlockThreadList();
1549
1550 /* change status back to RUNNING, self-suspending if necessary */
1551 dvmChangeStatus(self, THREAD_RUNNING);
1552
1553 /*
1554 * Tell the new thread to start.
1555 *
1556 * We must hold the thread list lock before messing with another thread.
1557 * In the general case we would also need to verify that newThread was
1558 * still in the thread list, but in our case the thread has not started
1559 * executing user code and therefore has not had a chance to exit.
1560 *
1561 * We move it to VMWAIT, and it then shifts itself to RUNNING, which
1562 * comes with a suspend-pending check.
1563 */
1564 dvmLockThreadList(self);
1565
1566 assert(newThread->status == THREAD_STARTING);
1567 newThread->status = THREAD_VMWAIT;
1568 pthread_cond_broadcast(&gDvm.threadStartCond);
1569
1570 dvmUnlockThreadList();
1571
1572 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1573 return true;
1574
1575fail:
1576 freeThread(newThread);
1577 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1578 return false;
1579}
1580
1581/*
1582 * pthread entry function for threads started from interpreted code.
1583 */
1584static void* interpThreadStart(void* arg)
1585{
1586 Thread* self = (Thread*) arg;
1587
1588 char *threadName = dvmGetThreadName(self);
1589 setThreadName(threadName);
1590 free(threadName);
1591
1592 /*
1593 * Finish initializing the Thread struct.
1594 */
1595 prepareThread(self);
1596
1597 LOG_THREAD("threadid=%d: created from interp\n", self->threadId);
1598
1599 /*
1600 * Change our status and wake our parent, who will add us to the
1601 * thread list and advance our state to VMWAIT.
1602 */
1603 dvmLockThreadList(self);
1604 self->status = THREAD_STARTING;
1605 pthread_cond_broadcast(&gDvm.threadStartCond);
1606
1607 /*
1608 * Wait until the parent says we can go. Assuming there wasn't a
1609 * suspend pending, this will happen immediately. When it completes,
1610 * we're full-fledged citizens of the VM.
1611 *
1612 * We have to use THREAD_VMWAIT here rather than THREAD_RUNNING
1613 * because the pthread_cond_wait below needs to reacquire a lock that
1614 * suspend-all is also interested in. If we get unlucky, the parent could
1615 * change us to THREAD_RUNNING, then a GC could start before we get
1616 * signaled, and suspend-all will grab the thread list lock and then
1617 * wait for us to suspend. We'll be in the tail end of pthread_cond_wait
1618 * trying to get the lock.
1619 */
1620 while (self->status != THREAD_VMWAIT)
1621 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1622
1623 dvmUnlockThreadList();
1624
1625 /*
1626 * Add a JNI context.
1627 */
1628 self->jniEnv = dvmCreateJNIEnv(self);
1629
1630 /*
1631 * Change our state so the GC will wait for us from now on. If a GC is
1632 * in progress this call will suspend us.
1633 */
1634 dvmChangeStatus(self, THREAD_RUNNING);
1635
1636 /*
1637 * Notify the debugger & DDM. The debugger notification may cause
1638 * us to suspend ourselves (and others).
1639 */
1640 if (gDvm.debuggerConnected)
1641 dvmDbgPostThreadStart(self);
1642
1643 /*
1644 * Set the system thread priority according to the Thread object's
1645 * priority level. We don't usually need to do this, because both the
1646 * Thread object and system thread priorities inherit from parents. The
1647 * tricky case is when somebody creates a Thread object, calls
1648 * setPriority(), and then starts the thread. We could manage this with
1649 * a "needs priority update" flag to avoid the redundant call.
1650 */
Andy McFadden4879df92009-08-07 14:49:40 -07001651 int priority = dvmGetFieldInt(self->threadObj,
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001652 gDvm.offJavaLangThread_priority);
1653 dvmChangeThreadPriority(self, priority);
1654
1655 /*
1656 * Execute the "run" method.
1657 *
1658 * At this point our stack is empty, so somebody who comes looking for
1659 * stack traces right now won't have much to look at. This is normal.
1660 */
1661 Method* run = self->threadObj->clazz->vtable[gDvm.voffJavaLangThread_run];
1662 JValue unused;
1663
1664 LOGV("threadid=%d: calling run()\n", self->threadId);
1665 assert(strcmp(run->name, "run") == 0);
1666 dvmCallMethod(self, run, self->threadObj, &unused);
1667 LOGV("threadid=%d: exiting\n", self->threadId);
1668
1669 /*
1670 * Remove the thread from various lists, report its death, and free
1671 * its resources.
1672 */
1673 dvmDetachCurrentThread();
1674
1675 return NULL;
1676}
1677
1678/*
1679 * The current thread is exiting with an uncaught exception. The
1680 * Java programming language allows the application to provide a
1681 * thread-exit-uncaught-exception handler for the VM, for a specific
1682 * Thread, and for all threads in a ThreadGroup.
1683 *
1684 * Version 1.5 added the per-thread handler. We need to call
1685 * "uncaughtException" in the handler object, which is either the
1686 * ThreadGroup object or the Thread-specific handler.
1687 */
1688static void threadExitUncaughtException(Thread* self, Object* group)
1689{
1690 Object* exception;
1691 Object* handlerObj;
1692 ClassObject* throwable;
1693 Method* uncaughtHandler = NULL;
1694 InstField* threadHandler;
1695
1696 LOGW("threadid=%d: thread exiting with uncaught exception (group=%p)\n",
1697 self->threadId, group);
1698 assert(group != NULL);
1699
1700 /*
1701 * Get a pointer to the exception, then clear out the one in the
1702 * thread. We don't want to have it set when executing interpreted code.
1703 */
1704 exception = dvmGetException(self);
1705 dvmAddTrackedAlloc(exception, self);
1706 dvmClearException(self);
1707
1708 /*
1709 * Get the Thread's "uncaughtHandler" object. Use it if non-NULL;
1710 * else use "group" (which is an instance of UncaughtExceptionHandler).
1711 */
1712 threadHandler = dvmFindInstanceField(gDvm.classJavaLangThread,
1713 "uncaughtHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;");
1714 if (threadHandler == NULL) {
1715 LOGW("WARNING: no 'uncaughtHandler' field in java/lang/Thread\n");
1716 goto bail;
1717 }
1718 handlerObj = dvmGetFieldObject(self->threadObj, threadHandler->byteOffset);
1719 if (handlerObj == NULL)
1720 handlerObj = group;
1721
1722 /*
1723 * Find the "uncaughtHandler" field in this object.
1724 */
1725 uncaughtHandler = dvmFindVirtualMethodHierByDescriptor(handlerObj->clazz,
1726 "uncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
1727
1728 if (uncaughtHandler != NULL) {
1729 //LOGI("+++ calling %s.uncaughtException\n",
1730 // handlerObj->clazz->descriptor);
1731 JValue unused;
1732 dvmCallMethod(self, uncaughtHandler, handlerObj, &unused,
1733 self->threadObj, exception);
1734 } else {
1735 /* restore it and dump a stack trace */
1736 LOGW("WARNING: no 'uncaughtException' method in class %s\n",
1737 handlerObj->clazz->descriptor);
1738 dvmSetException(self, exception);
1739 dvmLogExceptionStackTrace();
1740 }
1741
1742bail:
Bill Buzbee46cd5b62009-06-05 15:36:06 -07001743#if defined(WITH_JIT)
1744 /* Remove this thread's suspendCount from global suspendCount sum */
1745 lockThreadSuspendCount();
1746 dvmAddToThreadSuspendCount(&self->suspendCount, -self->suspendCount);
1747 unlockThreadSuspendCount();
1748#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001749 dvmReleaseTrackedAlloc(exception, self);
1750}
1751
1752
1753/*
1754 * Create an internal VM thread, for things like JDWP and finalizers.
1755 *
1756 * The easiest way to do this is create a new thread and then use the
1757 * JNI AttachCurrentThread implementation.
1758 *
1759 * This does not return until after the new thread has begun executing.
1760 */
1761bool dvmCreateInternalThread(pthread_t* pHandle, const char* name,
1762 InternalThreadStart func, void* funcArg)
1763{
1764 InternalStartArgs* pArgs;
1765 Object* systemGroup;
1766 pthread_attr_t threadAttr;
1767 volatile Thread* newThread = NULL;
1768 volatile int createStatus = 0;
1769
1770 systemGroup = dvmGetSystemThreadGroup();
1771 if (systemGroup == NULL)
1772 return false;
1773
1774 pArgs = (InternalStartArgs*) malloc(sizeof(*pArgs));
1775 pArgs->func = func;
1776 pArgs->funcArg = funcArg;
1777 pArgs->name = strdup(name); // storage will be owned by new thread
1778 pArgs->group = systemGroup;
1779 pArgs->isDaemon = true;
1780 pArgs->pThread = &newThread;
1781 pArgs->pCreateStatus = &createStatus;
1782
1783 pthread_attr_init(&threadAttr);
1784 //pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1785
1786 if (pthread_create(pHandle, &threadAttr, internalThreadStart,
1787 pArgs) != 0)
1788 {
1789 LOGE("internal thread creation failed\n");
1790 free(pArgs->name);
1791 free(pArgs);
1792 return false;
1793 }
1794
1795 /*
1796 * Wait for the child to start. This gives us an opportunity to make
1797 * sure that the thread started correctly, and allows our caller to
1798 * assume that the thread has started running.
1799 *
1800 * Because we aren't holding a lock across the thread creation, it's
1801 * possible that the child will already have completed its
1802 * initialization. Because the child only adjusts "createStatus" while
1803 * holding the thread list lock, the initial condition on the "while"
1804 * loop will correctly avoid the wait if this occurs.
1805 *
1806 * It's also possible that we'll have to wait for the thread to finish
1807 * being created, and as part of allocating a Thread object it might
1808 * need to initiate a GC. We switch to VMWAIT while we pause.
1809 */
1810 Thread* self = dvmThreadSelf();
1811 int oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
1812 dvmLockThreadList(self);
1813 while (createStatus == 0)
1814 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1815
1816 if (newThread == NULL) {
1817 LOGW("internal thread create failed (createStatus=%d)\n", createStatus);
1818 assert(createStatus < 0);
1819 /* don't free pArgs -- if pthread_create succeeded, child owns it */
1820 dvmUnlockThreadList();
1821 dvmChangeStatus(self, oldStatus);
1822 return false;
1823 }
1824
1825 /* thread could be in any state now (except early init states) */
1826 //assert(newThread->status == THREAD_RUNNING);
1827
1828 dvmUnlockThreadList();
1829 dvmChangeStatus(self, oldStatus);
1830
1831 return true;
1832}
1833
1834/*
1835 * pthread entry function for internally-created threads.
1836 *
1837 * We are expected to free "arg" and its contents. If we're a daemon
1838 * thread, and we get cancelled abruptly when the VM shuts down, the
1839 * storage won't be freed. If this becomes a concern we can make a copy
1840 * on the stack.
1841 */
1842static void* internalThreadStart(void* arg)
1843{
1844 InternalStartArgs* pArgs = (InternalStartArgs*) arg;
1845 JavaVMAttachArgs jniArgs;
1846
1847 jniArgs.version = JNI_VERSION_1_2;
1848 jniArgs.name = pArgs->name;
1849 jniArgs.group = pArgs->group;
1850
1851 setThreadName(pArgs->name);
1852
1853 /* use local jniArgs as stack top */
1854 if (dvmAttachCurrentThread(&jniArgs, pArgs->isDaemon)) {
1855 /*
1856 * Tell the parent of our success.
1857 *
1858 * threadListLock is the mutex for threadStartCond.
1859 */
1860 dvmLockThreadList(dvmThreadSelf());
1861 *pArgs->pCreateStatus = 1;
1862 *pArgs->pThread = dvmThreadSelf();
1863 pthread_cond_broadcast(&gDvm.threadStartCond);
1864 dvmUnlockThreadList();
1865
1866 LOG_THREAD("threadid=%d: internal '%s'\n",
1867 dvmThreadSelf()->threadId, pArgs->name);
1868
1869 /* execute */
1870 (*pArgs->func)(pArgs->funcArg);
1871
1872 /* detach ourselves */
1873 dvmDetachCurrentThread();
1874 } else {
1875 /*
1876 * Tell the parent of our failure. We don't have a Thread struct,
1877 * so we can't be suspended, so we don't need to enter a critical
1878 * section.
1879 */
1880 dvmLockThreadList(dvmThreadSelf());
1881 *pArgs->pCreateStatus = -1;
1882 assert(*pArgs->pThread == NULL);
1883 pthread_cond_broadcast(&gDvm.threadStartCond);
1884 dvmUnlockThreadList();
1885
1886 assert(*pArgs->pThread == NULL);
1887 }
1888
1889 free(pArgs->name);
1890 free(pArgs);
1891 return NULL;
1892}
1893
1894/*
1895 * Attach the current thread to the VM.
1896 *
1897 * Used for internally-created threads and JNI's AttachCurrentThread.
1898 */
1899bool dvmAttachCurrentThread(const JavaVMAttachArgs* pArgs, bool isDaemon)
1900{
1901 Thread* self = NULL;
1902 Object* threadObj = NULL;
1903 Object* vmThreadObj = NULL;
1904 StringObject* threadNameStr = NULL;
1905 Method* init;
1906 bool ok, ret;
1907
1908 /* establish a basic sense of self */
1909 self = allocThread(gDvm.stackSize);
1910 if (self == NULL)
1911 goto fail;
1912 setThreadSelf(self);
1913
1914 /*
1915 * Create Thread and VMThread objects. We have to use ALLOC_NO_GC
1916 * because this thread is not yet visible to the VM. We could also
1917 * just grab the GC lock earlier, but that leaves us executing
1918 * interpreted code with the lock held, which is not prudent.
1919 *
1920 * The alloc calls will block if a GC is in progress, so we don't need
1921 * to check for global suspension here.
1922 *
1923 * It's also possible for the allocation calls to *cause* a GC.
1924 */
1925 //BUG: deadlock if a GC happens here during HeapWorker creation
1926 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_NO_GC);
1927 if (threadObj == NULL)
1928 goto fail;
1929 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_NO_GC);
1930 if (vmThreadObj == NULL)
1931 goto fail;
1932
1933 self->threadObj = threadObj;
1934 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)self);
1935
1936 /*
1937 * Do some java.lang.Thread constructor prep before we lock stuff down.
1938 */
1939 if (pArgs->name != NULL) {
1940 threadNameStr = dvmCreateStringFromCstr(pArgs->name, ALLOC_NO_GC);
1941 if (threadNameStr == NULL) {
1942 assert(dvmCheckException(dvmThreadSelf()));
1943 goto fail;
1944 }
1945 }
1946
1947 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
1948 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
1949 if (init == NULL) {
1950 assert(dvmCheckException(dvmThreadSelf()));
1951 goto fail;
1952 }
1953
1954 /*
1955 * Finish our thread prep. We need to do this before invoking any
1956 * interpreted code. prepareThread() requires that we hold the thread
1957 * list lock.
1958 */
1959 dvmLockThreadList(self);
1960 ok = prepareThread(self);
1961 dvmUnlockThreadList();
1962 if (!ok)
1963 goto fail;
1964
1965 self->jniEnv = dvmCreateJNIEnv(self);
1966 if (self->jniEnv == NULL)
1967 goto fail;
1968
1969 /*
1970 * Create a "fake" JNI frame at the top of the main thread interp stack.
1971 * It isn't really necessary for the internal threads, but it gives
1972 * the debugger something to show. It is essential for the JNI-attached
1973 * threads.
1974 */
1975 if (!createFakeRunFrame(self))
1976 goto fail;
1977
1978 /*
1979 * The native side of the thread is ready; add it to the list.
1980 */
1981 LOG_THREAD("threadid=%d: adding to list (attached)\n", self->threadId);
1982
1983 /* Start off in VMWAIT, because we may be about to block
1984 * on the heap lock, and we don't want any suspensions
1985 * to wait for us.
1986 */
1987 self->status = THREAD_VMWAIT;
1988
1989 /*
1990 * Add ourselves to the thread list. Once we finish here we are
1991 * visible to the debugger and the GC.
1992 */
1993 dvmLockThreadList(self);
1994
1995 self->next = gDvm.threadList->next;
1996 if (self->next != NULL)
1997 self->next->prev = self;
1998 self->prev = gDvm.threadList;
1999 gDvm.threadList->next = self;
2000 if (!isDaemon)
2001 gDvm.nonDaemonThreadCount++;
2002
2003 dvmUnlockThreadList();
2004
2005 /*
2006 * It's possible that a GC is currently running. Our thread
2007 * wasn't in the list when the GC started, so it's not properly
2008 * suspended in that case. Synchronize on the heap lock (held
2009 * when a GC is happening) to guarantee that any GCs from here
2010 * on will see this thread in the list.
2011 */
2012 dvmLockMutex(&gDvm.gcHeapLock);
2013 dvmUnlockMutex(&gDvm.gcHeapLock);
2014
2015 /*
2016 * Switch to the running state now that we're ready for
2017 * suspensions. This call may suspend.
2018 */
2019 dvmChangeStatus(self, THREAD_RUNNING);
2020
2021 /*
2022 * Now we're ready to run some interpreted code.
2023 *
2024 * We need to construct the Thread object and set the VMThread field.
2025 * Setting VMThread tells interpreted code that we're alive.
2026 *
2027 * Call the (group, name, priority, daemon) constructor on the Thread.
2028 * This sets the thread's name and adds it to the specified group, and
2029 * provides values for priority and daemon (which are normally inherited
2030 * from the current thread).
2031 */
2032 JValue unused;
2033 dvmCallMethod(self, init, threadObj, &unused, (Object*)pArgs->group,
2034 threadNameStr, getThreadPriorityFromSystem(), isDaemon);
2035 if (dvmCheckException(self)) {
2036 LOGE("exception thrown while constructing attached thread object\n");
2037 goto fail_unlink;
2038 }
2039 //if (isDaemon)
2040 // dvmSetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon, true);
2041
2042 /*
2043 * Set the VMThread field, which tells interpreted code that we're alive.
2044 *
2045 * The risk of a thread start collision here is very low; somebody
2046 * would have to be deliberately polling the ThreadGroup list and
2047 * trying to start threads against anything it sees, which would
2048 * generally cause problems for all thread creation. However, for
2049 * correctness we test "vmThread" before setting it.
2050 */
2051 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
2052 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
2053 "thread has already been started");
2054 /* We don't want to free anything associated with the thread
2055 * because someone is obviously interested in it. Just let
2056 * it go and hope it will clean itself up when its finished.
2057 * This case should never happen anyway.
2058 *
2059 * Since we're letting it live, we need to finish setting it up.
2060 * We just have to let the caller know that the intended operation
2061 * has failed.
2062 *
2063 * [ This seems strange -- stepping on the vmThread object that's
2064 * already present seems like a bad idea. TODO: figure this out. ]
2065 */
2066 ret = false;
2067 } else
2068 ret = true;
2069 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
2070
2071 /* These are now reachable from the thread groups. */
2072 dvmClearAllocFlags(threadObj, ALLOC_NO_GC);
2073 dvmClearAllocFlags(vmThreadObj, ALLOC_NO_GC);
2074
2075 /*
2076 * The thread is ready to go; let the debugger see it.
2077 */
2078 self->threadObj = threadObj;
2079
2080 LOG_THREAD("threadid=%d: attached from native, name=%s\n",
2081 self->threadId, pArgs->name);
2082
2083 /* tell the debugger & DDM */
2084 if (gDvm.debuggerConnected)
2085 dvmDbgPostThreadStart(self);
2086
2087 return ret;
2088
2089fail_unlink:
2090 dvmLockThreadList(self);
2091 unlinkThread(self);
2092 if (!isDaemon)
2093 gDvm.nonDaemonThreadCount--;
2094 dvmUnlockThreadList();
2095 /* fall through to "fail" */
2096fail:
2097 dvmClearAllocFlags(threadObj, ALLOC_NO_GC);
2098 dvmClearAllocFlags(vmThreadObj, ALLOC_NO_GC);
2099 if (self != NULL) {
2100 if (self->jniEnv != NULL) {
2101 dvmDestroyJNIEnv(self->jniEnv);
2102 self->jniEnv = NULL;
2103 }
2104 freeThread(self);
2105 }
2106 setThreadSelf(NULL);
2107 return false;
2108}
2109
2110/*
2111 * Detach the thread from the various data structures, notify other threads
2112 * that are waiting to "join" it, and free up all heap-allocated storage.
2113 *
2114 * Used for all threads.
2115 *
2116 * When we get here the interpreted stack should be empty. The JNI 1.6 spec
2117 * requires us to enforce this for the DetachCurrentThread call, probably
2118 * because it also says that DetachCurrentThread causes all monitors
2119 * associated with the thread to be released. (Because the stack is empty,
2120 * we only have to worry about explicit JNI calls to MonitorEnter.)
2121 *
2122 * THOUGHT:
2123 * We might want to avoid freeing our internal Thread structure until the
2124 * associated Thread/VMThread objects get GCed. Our Thread is impossible to
2125 * get to once the thread shuts down, but there is a small possibility of
2126 * an operation starting in another thread before this thread halts, and
2127 * finishing much later (perhaps the thread got stalled by a weird OS bug).
2128 * We don't want something like Thread.isInterrupted() crawling through
2129 * freed storage. Can do with a Thread finalizer, or by creating a
2130 * dedicated ThreadObject class for java/lang/Thread and moving all of our
2131 * state into that.
2132 */
2133void dvmDetachCurrentThread(void)
2134{
2135 Thread* self = dvmThreadSelf();
2136 Object* vmThread;
2137 Object* group;
2138
2139 /*
2140 * Make sure we're not detaching a thread that's still running. (This
2141 * could happen with an explicit JNI detach call.)
2142 *
2143 * A thread created by interpreted code will finish with a depth of
2144 * zero, while a JNI-attached thread will have the synthetic "stack
2145 * starter" native method at the top.
2146 */
2147 int curDepth = dvmComputeExactFrameDepth(self->curFrame);
2148 if (curDepth != 0) {
2149 bool topIsNative = false;
2150
2151 if (curDepth == 1) {
2152 /* not expecting a lingering break frame; just look at curFrame */
2153 assert(!dvmIsBreakFrame(self->curFrame));
2154 StackSaveArea* ssa = SAVEAREA_FROM_FP(self->curFrame);
2155 if (dvmIsNativeMethod(ssa->method))
2156 topIsNative = true;
2157 }
2158
2159 if (!topIsNative) {
2160 LOGE("ERROR: detaching thread with interp frames (count=%d)\n",
2161 curDepth);
2162 dvmDumpThread(self, false);
2163 dvmAbort();
2164 }
2165 }
2166
2167 group = dvmGetFieldObject(self->threadObj, gDvm.offJavaLangThread_group);
2168 LOG_THREAD("threadid=%d: detach (group=%p)\n", self->threadId, group);
2169
2170 /*
2171 * Release any held monitors. Since there are no interpreted stack
2172 * frames, the only thing left are the monitors held by JNI MonitorEnter
2173 * calls.
2174 */
2175 dvmReleaseJniMonitors(self);
2176
2177 /*
2178 * Do some thread-exit uncaught exception processing if necessary.
2179 */
2180 if (dvmCheckException(self))
2181 threadExitUncaughtException(self, group);
2182
2183 /*
2184 * Remove the thread from the thread group.
2185 */
2186 if (group != NULL) {
2187 Method* removeThread =
2188 group->clazz->vtable[gDvm.voffJavaLangThreadGroup_removeThread];
2189 JValue unused;
2190 dvmCallMethod(self, removeThread, group, &unused, self->threadObj);
2191 }
2192
2193 /*
2194 * Clear the vmThread reference in the Thread object. Interpreted code
2195 * will now see that this Thread is not running. As this may be the
2196 * only reference to the VMThread object that the VM knows about, we
2197 * have to create an internal reference to it first.
2198 */
2199 vmThread = dvmGetFieldObject(self->threadObj,
2200 gDvm.offJavaLangThread_vmThread);
2201 dvmAddTrackedAlloc(vmThread, self);
2202 dvmSetFieldObject(self->threadObj, gDvm.offJavaLangThread_vmThread, NULL);
2203
2204 /* clear out our struct Thread pointer, since it's going away */
2205 dvmSetFieldObject(vmThread, gDvm.offJavaLangVMThread_vmData, NULL);
2206
2207 /*
2208 * Tell the debugger & DDM. This may cause the current thread or all
2209 * threads to suspend.
2210 *
2211 * The JDWP spec is somewhat vague about when this happens, other than
2212 * that it's issued by the dying thread, which may still appear in
2213 * an "all threads" listing.
2214 */
2215 if (gDvm.debuggerConnected)
2216 dvmDbgPostThreadDeath(self);
2217
2218 /*
2219 * Thread.join() is implemented as an Object.wait() on the VMThread
2220 * object. Signal anyone who is waiting.
2221 */
2222 dvmLockObject(self, vmThread);
2223 dvmObjectNotifyAll(self, vmThread);
2224 dvmUnlockObject(self, vmThread);
2225
2226 dvmReleaseTrackedAlloc(vmThread, self);
2227 vmThread = NULL;
2228
2229 /*
2230 * We're done manipulating objects, so it's okay if the GC runs in
2231 * parallel with us from here out. It's important to do this if
2232 * profiling is enabled, since we can wait indefinitely.
2233 */
2234 self->status = THREAD_VMWAIT;
2235
2236#ifdef WITH_PROFILER
2237 /*
2238 * If we're doing method trace profiling, we don't want threads to exit,
2239 * because if they do we'll end up reusing thread IDs. This complicates
2240 * analysis and makes it impossible to have reasonable output in the
2241 * "threads" section of the "key" file.
2242 *
2243 * We need to do this after Thread.join() completes, or other threads
2244 * could get wedged. Since self->threadObj is still valid, the Thread
2245 * object will not get GCed even though we're no longer in the ThreadGroup
2246 * list (which is important since the profiling thread needs to get
2247 * the thread's name).
2248 */
2249 MethodTraceState* traceState = &gDvm.methodTrace;
2250
2251 dvmLockMutex(&traceState->startStopLock);
2252 if (traceState->traceEnabled) {
2253 LOGI("threadid=%d: waiting for method trace to finish\n",
2254 self->threadId);
2255 while (traceState->traceEnabled) {
2256 int cc;
2257 cc = pthread_cond_wait(&traceState->threadExitCond,
2258 &traceState->startStopLock);
2259 assert(cc == 0);
2260 }
2261 }
2262 dvmUnlockMutex(&traceState->startStopLock);
2263#endif
2264
2265 dvmLockThreadList(self);
2266
2267 /*
2268 * Lose the JNI context.
2269 */
2270 dvmDestroyJNIEnv(self->jniEnv);
2271 self->jniEnv = NULL;
2272
2273 self->status = THREAD_ZOMBIE;
2274
2275 /*
2276 * Remove ourselves from the internal thread list.
2277 */
2278 unlinkThread(self);
2279
2280 /*
2281 * If we're the last one standing, signal anybody waiting in
2282 * DestroyJavaVM that it's okay to exit.
2283 */
2284 if (!dvmGetFieldBoolean(self->threadObj, gDvm.offJavaLangThread_daemon)) {
2285 gDvm.nonDaemonThreadCount--; // guarded by thread list lock
2286
2287 if (gDvm.nonDaemonThreadCount == 0) {
2288 int cc;
2289
2290 LOGV("threadid=%d: last non-daemon thread\n", self->threadId);
2291 //dvmDumpAllThreads(false);
2292 // cond var guarded by threadListLock, which we already hold
2293 cc = pthread_cond_signal(&gDvm.vmExitCond);
2294 assert(cc == 0);
2295 }
2296 }
2297
2298 LOGV("threadid=%d: bye!\n", self->threadId);
2299 releaseThreadId(self);
2300 dvmUnlockThreadList();
2301
2302 setThreadSelf(NULL);
Bob Lee9dc72a32009-09-04 18:28:16 -07002303
Bob Lee2fe146a2009-09-10 00:36:29 +02002304 dvmDetachSystemThread(self);
Bob Lee9dc72a32009-09-04 18:28:16 -07002305
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002306 freeThread(self);
2307}
2308
2309
2310/*
2311 * Suspend a single thread. Do not use to suspend yourself.
2312 *
2313 * This is used primarily for debugger/DDMS activity. Does not return
2314 * until the thread has suspended or is in a "safe" state (e.g. executing
2315 * native code outside the VM).
2316 *
2317 * The thread list lock should be held before calling here -- it's not
2318 * entirely safe to hang on to a Thread* from another thread otherwise.
2319 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2320 */
2321void dvmSuspendThread(Thread* thread)
2322{
2323 assert(thread != NULL);
2324 assert(thread != dvmThreadSelf());
2325 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2326
2327 lockThreadSuspendCount();
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002328 dvmAddToThreadSuspendCount(&thread->suspendCount, 1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002329 thread->dbgSuspendCount++;
2330
2331 LOG_THREAD("threadid=%d: suspend++, now=%d\n",
2332 thread->threadId, thread->suspendCount);
2333 unlockThreadSuspendCount();
2334
2335 waitForThreadSuspend(dvmThreadSelf(), thread);
2336}
2337
2338/*
2339 * Reduce the suspend count of a thread. If it hits zero, tell it to
2340 * resume.
2341 *
2342 * Used primarily for debugger/DDMS activity. The thread in question
2343 * might have been suspended singly or as part of a suspend-all operation.
2344 *
2345 * The thread list lock should be held before calling here -- it's not
2346 * entirely safe to hang on to a Thread* from another thread otherwise.
2347 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2348 */
2349void dvmResumeThread(Thread* thread)
2350{
2351 assert(thread != NULL);
2352 assert(thread != dvmThreadSelf());
2353 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2354
2355 lockThreadSuspendCount();
2356 if (thread->suspendCount > 0) {
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002357 dvmAddToThreadSuspendCount(&thread->suspendCount, -1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002358 thread->dbgSuspendCount--;
2359 } else {
2360 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2361 thread->threadId);
2362 }
2363
2364 LOG_THREAD("threadid=%d: suspend--, now=%d\n",
2365 thread->threadId, thread->suspendCount);
2366
2367 if (thread->suspendCount == 0) {
2368 int cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2369 assert(cc == 0);
2370 }
2371
2372 unlockThreadSuspendCount();
2373}
2374
2375/*
2376 * Suspend yourself, as a result of debugger activity.
2377 */
2378void dvmSuspendSelf(bool jdwpActivity)
2379{
2380 Thread* self = dvmThreadSelf();
2381
2382 /* debugger thread may not suspend itself due to debugger activity! */
2383 assert(gDvm.jdwpState != NULL);
2384 if (self->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2385 assert(false);
2386 return;
2387 }
2388
2389 /*
2390 * Collisions with other suspends aren't really interesting. We want
2391 * to ensure that we're the only one fiddling with the suspend count
2392 * though.
2393 */
2394 lockThreadSuspendCount();
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002395 dvmAddToThreadSuspendCount(&self->suspendCount, 1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002396 self->dbgSuspendCount++;
2397
2398 /*
2399 * Suspend ourselves.
2400 */
2401 assert(self->suspendCount > 0);
2402 self->isSuspended = true;
2403 LOG_THREAD("threadid=%d: self-suspending (dbg)\n", self->threadId);
2404
2405 /*
2406 * Tell JDWP that we've completed suspension. The JDWP thread can't
2407 * tell us to resume before we're fully asleep because we hold the
2408 * suspend count lock.
2409 *
2410 * If we got here via waitForDebugger(), don't do this part.
2411 */
2412 if (jdwpActivity) {
2413 //LOGI("threadid=%d: clearing wait-for-event (my handle=%08x)\n",
2414 // self->threadId, (int) self->handle);
2415 dvmJdwpClearWaitForEventThread(gDvm.jdwpState);
2416 }
2417
2418 while (self->suspendCount != 0) {
2419 int cc;
2420 cc = pthread_cond_wait(&gDvm.threadSuspendCountCond,
2421 &gDvm.threadSuspendCountLock);
2422 assert(cc == 0);
2423 if (self->suspendCount != 0) {
The Android Open Source Project99409882009-03-18 22:20:24 -07002424 /*
2425 * The condition was signaled but we're still suspended. This
2426 * can happen if the debugger lets go while a SIGQUIT thread
2427 * dump event is pending (assuming SignalCatcher was resumed for
2428 * just long enough to try to grab the thread-suspend lock).
2429 */
2430 LOGD("threadid=%d: still suspended after undo (sc=%d dc=%d s=%c)\n",
2431 self->threadId, self->suspendCount, self->dbgSuspendCount,
2432 self->isSuspended ? 'Y' : 'N');
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002433 }
2434 }
2435 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
2436 self->isSuspended = false;
2437 LOG_THREAD("threadid=%d: self-reviving (dbg), status=%d\n",
2438 self->threadId, self->status);
2439
2440 unlockThreadSuspendCount();
2441}
2442
2443
2444#ifdef HAVE_GLIBC
2445# define NUM_FRAMES 20
2446# include <execinfo.h>
2447/*
2448 * glibc-only stack dump function. Requires link with "--export-dynamic".
2449 *
2450 * TODO: move this into libs/cutils and make it work for all platforms.
2451 */
2452static void printBackTrace(void)
2453{
2454 void* array[NUM_FRAMES];
2455 size_t size;
2456 char** strings;
2457 size_t i;
2458
2459 size = backtrace(array, NUM_FRAMES);
2460 strings = backtrace_symbols(array, size);
2461
2462 LOGW("Obtained %zd stack frames.\n", size);
2463
2464 for (i = 0; i < size; i++)
2465 LOGW("%s\n", strings[i]);
2466
2467 free(strings);
2468}
2469#else
2470static void printBackTrace(void) {}
2471#endif
2472
2473/*
2474 * Dump the state of the current thread and that of another thread that
2475 * we think is wedged.
2476 */
2477static void dumpWedgedThread(Thread* thread)
2478{
2479 char exePath[1024];
2480
2481 /*
2482 * The "executablepath" function in libutils is host-side only.
2483 */
2484 strcpy(exePath, "-");
2485#ifdef HAVE_GLIBC
2486 {
2487 char proc[100];
2488 sprintf(proc, "/proc/%d/exe", getpid());
2489 int len;
Jeff Hao97319a82009-08-12 16:57:15 -07002490
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002491 len = readlink(proc, exePath, sizeof(exePath)-1);
2492 exePath[len] = '\0';
2493 }
2494#endif
2495
2496 LOGW("dumping state: process %s %d\n", exePath, getpid());
2497 dvmDumpThread(dvmThreadSelf(), false);
2498 printBackTrace();
2499
2500 // dumping a running thread is risky, but could be useful
2501 dvmDumpThread(thread, true);
2502
2503
2504 // stop now and get a core dump
2505 //abort();
2506}
2507
2508
2509/*
2510 * Wait for another thread to see the pending suspension and stop running.
2511 * It can either suspend itself or go into a non-running state such as
2512 * VMWAIT or NATIVE in which it cannot interact with the GC.
2513 *
2514 * If we're running at a higher priority, sched_yield() may not do anything,
2515 * so we need to sleep for "long enough" to guarantee that the other
2516 * thread has a chance to finish what it's doing. Sleeping for too short
2517 * a period (e.g. less than the resolution of the sleep clock) might cause
2518 * the scheduler to return immediately, so we want to start with a
2519 * "reasonable" value and expand.
2520 *
2521 * This does not return until the other thread has stopped running.
2522 * Eventually we time out and the VM aborts.
2523 *
2524 * This does not try to detect the situation where two threads are
2525 * waiting for each other to suspend. In normal use this is part of a
2526 * suspend-all, which implies that the suspend-all lock is held, or as
2527 * part of a debugger action in which the JDWP thread is always the one
2528 * doing the suspending. (We may need to re-evaluate this now that
2529 * getThreadStackTrace is implemented as suspend-snapshot-resume.)
2530 *
2531 * TODO: track basic stats about time required to suspend VM.
2532 */
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002533#define FIRST_SLEEP (250*1000) /* 0.25s */
2534#define MORE_SLEEP (750*1000) /* 0.75s */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002535static void waitForThreadSuspend(Thread* self, Thread* thread)
2536{
2537 const int kMaxRetries = 10;
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002538 int spinSleepTime = FIRST_SLEEP;
Andy McFadden2aa43612009-06-17 16:29:30 -07002539 bool complained = false;
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002540 bool needPriorityReset = false;
2541 int savedThreadPrio = -500;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002542
2543 int sleepIter = 0;
2544 int retryCount = 0;
2545 u8 startWhen = 0; // init req'd to placate gcc
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002546 u8 firstStartWhen = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002547
2548 while (thread->status == THREAD_RUNNING && !thread->isSuspended) {
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002549 if (sleepIter == 0) { // get current time on first iteration
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002550 startWhen = dvmGetRelativeTimeUsec();
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002551 if (firstStartWhen == 0) // first iteration of first attempt
2552 firstStartWhen = startWhen;
2553
2554 /*
2555 * After waiting for a bit, check to see if the target thread is
2556 * running at a reduced priority. If so, bump it up temporarily
2557 * to give it more CPU time.
2558 *
2559 * getpriority() returns the "nice" value, so larger numbers
2560 * indicate lower priority.
2561 *
2562 * (Not currently changing the cgroup. Wasn't necessary in some
2563 * simple experiments.)
2564 */
2565 if (retryCount == 2) {
2566 assert(thread->systemTid != 0);
2567 errno = 0;
2568 int threadPrio = getpriority(PRIO_PROCESS, thread->systemTid);
2569 if (errno == 0 && threadPrio > 0) {
2570 const int kHigher = 0;
2571 if (setpriority(PRIO_PROCESS, thread->systemTid, kHigher) < 0)
2572 {
2573 LOGW("Couldn't raise priority on tid %d to %d\n",
2574 thread->systemTid, kHigher);
2575 } else {
2576 savedThreadPrio = threadPrio;
2577 needPriorityReset = true;
2578 LOGD("Temporarily raising priority on tid %d (%d -> %d)\n",
2579 thread->systemTid, threadPrio, kHigher);
2580 }
2581 }
2582 }
2583 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002584
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002585#if defined (WITH_JIT)
2586 /*
2587 * If we're still waiting after the first timeout,
2588 * unchain all translations.
2589 */
2590 if (gDvmJit.pJitEntryTable && retryCount > 0) {
2591 LOGD("JIT unchain all attempt #%d",retryCount);
2592 dvmJitUnchainAll();
2593 }
2594#endif
2595
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002596 /*
Andy McFadden1ede83b2009-12-02 17:03:41 -08002597 * Sleep briefly. The iterative sleep call returns false if we've
2598 * exceeded the total time limit for this round of sleeping.
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002599 */
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002600 if (!dvmIterativeSleep(sleepIter++, spinSleepTime, startWhen)) {
Andy McFadden1ede83b2009-12-02 17:03:41 -08002601 if (spinSleepTime != FIRST_SLEEP) {
2602 LOGW("threadid=%d: spin on suspend #%d threadid=%d (h=%d)\n",
2603 self->threadId, retryCount,
2604 thread->threadId, (int)thread->handle);
2605 dumpWedgedThread(thread);
2606 complained = true;
2607 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002608
2609 // keep going; could be slow due to valgrind
2610 sleepIter = 0;
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002611 spinSleepTime = MORE_SLEEP;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002612
2613 if (retryCount++ == kMaxRetries) {
2614 LOGE("threadid=%d: stuck on threadid=%d, giving up\n",
2615 self->threadId, thread->threadId);
2616 dvmDumpAllThreads(false);
2617 dvmAbort();
2618 }
2619 }
2620 }
Andy McFadden2aa43612009-06-17 16:29:30 -07002621
2622 if (complained) {
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002623 LOGW("threadid=%d: spin on suspend resolved in %lld msec\n",
2624 self->threadId,
2625 (dvmGetRelativeTimeUsec() - firstStartWhen) / 1000);
Andy McFadden2aa43612009-06-17 16:29:30 -07002626 //dvmDumpThread(thread, false); /* suspended, so dump is safe */
2627 }
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002628 if (needPriorityReset) {
2629 if (setpriority(PRIO_PROCESS, thread->systemTid, savedThreadPrio) < 0) {
2630 LOGW("NOTE: couldn't reset priority on thread %d to %d\n",
2631 thread->systemTid, savedThreadPrio);
2632 } else {
2633 LOGV("Restored priority on %d to %d\n",
2634 thread->systemTid, savedThreadPrio);
2635 }
2636 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002637}
2638
2639/*
2640 * Suspend all threads except the current one. This is used by the GC,
2641 * the debugger, and by any thread that hits a "suspend all threads"
2642 * debugger event (e.g. breakpoint or exception).
2643 *
2644 * If thread N hits a "suspend all threads" breakpoint, we don't want it
2645 * to suspend the JDWP thread. For the GC, we do, because the debugger can
2646 * create objects and even execute arbitrary code. The "why" argument
2647 * allows the caller to say why the suspension is taking place.
2648 *
2649 * This can be called when a global suspend has already happened, due to
2650 * various debugger gymnastics, so keeping an "everybody is suspended" flag
2651 * doesn't work.
2652 *
2653 * DO NOT grab any locks before calling here. We grab & release the thread
2654 * lock and suspend lock here (and we're not using recursive threads), and
2655 * we might have to self-suspend if somebody else beats us here.
2656 *
2657 * The current thread may not be attached to the VM. This can happen if
2658 * we happen to GC as the result of an allocation of a Thread object.
2659 */
2660void dvmSuspendAllThreads(SuspendCause why)
2661{
2662 Thread* self = dvmThreadSelf();
2663 Thread* thread;
2664
2665 assert(why != 0);
2666
2667 /*
2668 * Start by grabbing the thread suspend lock. If we can't get it, most
2669 * likely somebody else is in the process of performing a suspend or
2670 * resume, so lockThreadSuspend() will cause us to self-suspend.
2671 *
2672 * We keep the lock until all other threads are suspended.
2673 */
2674 lockThreadSuspend("susp-all", why);
2675
2676 LOG_THREAD("threadid=%d: SuspendAll starting\n", self->threadId);
2677
2678 /*
2679 * This is possible if the current thread was in VMWAIT mode when a
2680 * suspend-all happened, and then decided to do its own suspend-all.
2681 * This can happen when a couple of threads have simultaneous events
2682 * of interest to the debugger.
2683 */
2684 //assert(self->suspendCount == 0);
2685
2686 /*
2687 * Increment everybody's suspend count (except our own).
2688 */
2689 dvmLockThreadList(self);
2690
2691 lockThreadSuspendCount();
2692 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2693 if (thread == self)
2694 continue;
2695
2696 /* debugger events don't suspend JDWP thread */
2697 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2698 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2699 continue;
2700
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002701 dvmAddToThreadSuspendCount(&thread->suspendCount, 1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002702 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2703 thread->dbgSuspendCount++;
2704 }
2705 unlockThreadSuspendCount();
2706
2707 /*
2708 * Wait for everybody in THREAD_RUNNING state to stop. Other states
2709 * indicate the code is either running natively or sleeping quietly.
2710 * Any attempt to transition back to THREAD_RUNNING will cause a check
2711 * for suspension, so it should be impossible for anything to execute
2712 * interpreted code or modify objects (assuming native code plays nicely).
2713 *
2714 * It's also okay if the thread transitions to a non-RUNNING state.
2715 *
2716 * Note we released the threadSuspendCountLock before getting here,
2717 * so if another thread is fiddling with its suspend count (perhaps
2718 * self-suspending for the debugger) it won't block while we're waiting
2719 * in here.
2720 */
2721 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2722 if (thread == self)
2723 continue;
2724
2725 /* debugger events don't suspend JDWP thread */
2726 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2727 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2728 continue;
2729
2730 /* wait for the other thread to see the pending suspend */
2731 waitForThreadSuspend(self, thread);
2732
Jeff Hao97319a82009-08-12 16:57:15 -07002733 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 -08002734 self->threadId,
2735 thread->threadId, thread->status, thread->suspendCount,
2736 thread->dbgSuspendCount, thread->isSuspended);
2737 }
2738
2739 dvmUnlockThreadList();
2740 unlockThreadSuspend();
2741
2742 LOG_THREAD("threadid=%d: SuspendAll complete\n", self->threadId);
2743}
2744
2745/*
2746 * Resume all threads that are currently suspended.
2747 *
2748 * The "why" must match with the previous suspend.
2749 */
2750void dvmResumeAllThreads(SuspendCause why)
2751{
2752 Thread* self = dvmThreadSelf();
2753 Thread* thread;
2754 int cc;
2755
2756 lockThreadSuspend("res-all", why); /* one suspend/resume at a time */
2757 LOG_THREAD("threadid=%d: ResumeAll starting\n", self->threadId);
2758
2759 /*
2760 * Decrement the suspend counts for all threads. No need for atomic
2761 * writes, since nobody should be moving until we decrement the count.
2762 * We do need to hold the thread list because of JNI attaches.
2763 */
2764 dvmLockThreadList(self);
2765 lockThreadSuspendCount();
2766 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2767 if (thread == self)
2768 continue;
2769
2770 /* debugger events don't suspend JDWP thread */
2771 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2772 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
Andy McFadden2aa43612009-06-17 16:29:30 -07002773 {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002774 continue;
Andy McFadden2aa43612009-06-17 16:29:30 -07002775 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002776
2777 if (thread->suspendCount > 0) {
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002778 dvmAddToThreadSuspendCount(&thread->suspendCount, -1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002779 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2780 thread->dbgSuspendCount--;
2781 } else {
2782 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2783 thread->threadId);
2784 }
2785 }
2786 unlockThreadSuspendCount();
2787 dvmUnlockThreadList();
2788
2789 /*
Andy McFadden2aa43612009-06-17 16:29:30 -07002790 * In some ways it makes sense to continue to hold the thread-suspend
2791 * lock while we issue the wakeup broadcast. It allows us to complete
2792 * one operation before moving on to the next, which simplifies the
2793 * thread activity debug traces.
2794 *
2795 * This approach caused us some difficulty under Linux, because the
2796 * condition variable broadcast not only made the threads runnable,
2797 * but actually caused them to execute, and it was a while before
2798 * the thread performing the wakeup had an opportunity to release the
2799 * thread-suspend lock.
2800 *
2801 * This is a problem because, when a thread tries to acquire that
2802 * lock, it times out after 3 seconds. If at some point the thread
2803 * is told to suspend, the clock resets; but since the VM is still
2804 * theoretically mid-resume, there's no suspend pending. If, for
2805 * example, the GC was waking threads up while the SIGQUIT handler
2806 * was trying to acquire the lock, we would occasionally time out on
2807 * a busy system and SignalCatcher would abort.
2808 *
2809 * We now perform the unlock before the wakeup broadcast. The next
2810 * suspend can't actually start until the broadcast completes and
2811 * returns, because we're holding the thread-suspend-count lock, but the
2812 * suspending thread is now able to make progress and we avoid the abort.
2813 *
2814 * (Technically there is a narrow window between when we release
2815 * the thread-suspend lock and grab the thread-suspend-count lock.
2816 * This could cause us to send a broadcast to threads with nonzero
2817 * suspend counts, but this is expected and they'll all just fall
2818 * right back to sleep. It's probably safe to grab the suspend-count
2819 * lock before releasing thread-suspend, since we're still following
2820 * the correct order of acquisition, but it feels weird.)
2821 */
2822
2823 LOG_THREAD("threadid=%d: ResumeAll waking others\n", self->threadId);
2824 unlockThreadSuspend();
2825
2826 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002827 * Broadcast a notification to all suspended threads, some or all of
2828 * which may choose to wake up. No need to wait for them.
2829 */
2830 lockThreadSuspendCount();
2831 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2832 assert(cc == 0);
2833 unlockThreadSuspendCount();
2834
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002835 LOG_THREAD("threadid=%d: ResumeAll complete\n", self->threadId);
2836}
2837
2838/*
2839 * Undo any debugger suspensions. This is called when the debugger
2840 * disconnects.
2841 */
2842void dvmUndoDebuggerSuspensions(void)
2843{
2844 Thread* self = dvmThreadSelf();
2845 Thread* thread;
2846 int cc;
2847
2848 lockThreadSuspend("undo", SUSPEND_FOR_DEBUG);
2849 LOG_THREAD("threadid=%d: UndoDebuggerSusp starting\n", self->threadId);
2850
2851 /*
2852 * Decrement the suspend counts for all threads. No need for atomic
2853 * writes, since nobody should be moving until we decrement the count.
2854 * We do need to hold the thread list because of JNI attaches.
2855 */
2856 dvmLockThreadList(self);
2857 lockThreadSuspendCount();
2858 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2859 if (thread == self)
2860 continue;
2861
2862 /* debugger events don't suspend JDWP thread */
2863 if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2864 assert(thread->dbgSuspendCount == 0);
2865 continue;
2866 }
2867
2868 assert(thread->suspendCount >= thread->dbgSuspendCount);
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002869 dvmAddToThreadSuspendCount(&thread->suspendCount,
2870 -thread->dbgSuspendCount);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002871 thread->dbgSuspendCount = 0;
2872 }
2873 unlockThreadSuspendCount();
2874 dvmUnlockThreadList();
2875
2876 /*
2877 * Broadcast a notification to all suspended threads, some or all of
2878 * which may choose to wake up. No need to wait for them.
2879 */
2880 lockThreadSuspendCount();
2881 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2882 assert(cc == 0);
2883 unlockThreadSuspendCount();
2884
2885 unlockThreadSuspend();
2886
2887 LOG_THREAD("threadid=%d: UndoDebuggerSusp complete\n", self->threadId);
2888}
2889
2890/*
2891 * Determine if a thread is suspended.
2892 *
2893 * As with all operations on foreign threads, the caller should hold
2894 * the thread list lock before calling.
2895 */
2896bool dvmIsSuspended(Thread* thread)
2897{
2898 /*
2899 * The thread could be:
2900 * (1) Running happily. status is RUNNING, isSuspended is false,
2901 * suspendCount is zero. Return "false".
2902 * (2) Pending suspend. status is RUNNING, isSuspended is false,
2903 * suspendCount is nonzero. Return "false".
2904 * (3) Suspended. suspendCount is nonzero, and either (status is
2905 * RUNNING and isSuspended is true) OR (status is !RUNNING).
2906 * Return "true".
2907 * (4) Waking up. suspendCount is zero, status is RUNNING and
2908 * isSuspended is true. Return "false" (since it could change
2909 * out from under us, unless we hold suspendCountLock).
2910 */
2911
2912 return (thread->suspendCount != 0 &&
2913 ((thread->status == THREAD_RUNNING && thread->isSuspended) ||
2914 (thread->status != THREAD_RUNNING)));
2915}
2916
2917/*
2918 * Wait until another thread self-suspends. This is specifically for
2919 * synchronization between the JDWP thread and a thread that has decided
2920 * to suspend itself after sending an event to the debugger.
2921 *
2922 * Threads that encounter "suspend all" events work as well -- the thread
2923 * in question suspends everybody else and then itself.
2924 *
2925 * We can't hold a thread lock here or in the caller, because we could
2926 * get here just before the to-be-waited-for-thread issues a "suspend all".
2927 * There's an opportunity for badness if the thread we're waiting for exits
2928 * and gets cleaned up, but since the thread in question is processing a
2929 * debugger event, that's not really a possibility. (To avoid deadlock,
2930 * it's important that we not be in THREAD_RUNNING while we wait.)
2931 */
2932void dvmWaitForSuspend(Thread* thread)
2933{
2934 Thread* self = dvmThreadSelf();
2935
2936 LOG_THREAD("threadid=%d: waiting for threadid=%d to sleep\n",
2937 self->threadId, thread->threadId);
2938
2939 assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2940 assert(thread != self);
2941 assert(self->status != THREAD_RUNNING);
2942
2943 waitForThreadSuspend(self, thread);
2944
2945 LOG_THREAD("threadid=%d: threadid=%d is now asleep\n",
2946 self->threadId, thread->threadId);
2947}
2948
2949/*
2950 * Check to see if we need to suspend ourselves. If so, go to sleep on
2951 * a condition variable.
2952 *
2953 * Takes "self" as an argument as an optimization. Pass in NULL to have
2954 * it do the lookup.
2955 *
2956 * Returns "true" if we suspended ourselves.
2957 */
2958bool dvmCheckSuspendPending(Thread* self)
2959{
2960 bool didSuspend;
2961
2962 if (self == NULL)
2963 self = dvmThreadSelf();
2964
2965 /* fast path: if count is zero, bail immediately */
2966 if (self->suspendCount == 0)
2967 return false;
2968
2969 lockThreadSuspendCount(); /* grab gDvm.threadSuspendCountLock */
2970
2971 assert(self->suspendCount >= 0); /* XXX: valid? useful? */
2972
2973 didSuspend = (self->suspendCount != 0);
2974 self->isSuspended = true;
2975 LOG_THREAD("threadid=%d: self-suspending\n", self->threadId);
2976 while (self->suspendCount != 0) {
2977 /* wait for wakeup signal; releases lock */
2978 int cc;
2979 cc = pthread_cond_wait(&gDvm.threadSuspendCountCond,
2980 &gDvm.threadSuspendCountLock);
2981 assert(cc == 0);
2982 }
2983 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
2984 self->isSuspended = false;
2985 LOG_THREAD("threadid=%d: self-reviving, status=%d\n",
2986 self->threadId, self->status);
2987
2988 unlockThreadSuspendCount();
2989
2990 return didSuspend;
2991}
2992
2993/*
2994 * Update our status.
2995 *
2996 * The "self" argument, which may be NULL, is accepted as an optimization.
2997 *
2998 * Returns the old status.
2999 */
3000ThreadStatus dvmChangeStatus(Thread* self, ThreadStatus newStatus)
3001{
3002 ThreadStatus oldStatus;
3003
3004 if (self == NULL)
3005 self = dvmThreadSelf();
3006
3007 LOGVV("threadid=%d: (status %d -> %d)\n",
3008 self->threadId, self->status, newStatus);
3009
3010 oldStatus = self->status;
3011
3012 if (newStatus == THREAD_RUNNING) {
3013 /*
3014 * Change our status to THREAD_RUNNING. The transition requires
3015 * that we check for pending suspension, because the VM considers
3016 * us to be "asleep" in all other states.
3017 *
3018 * We need to do the "suspend pending" check FIRST, because it grabs
3019 * a lock that could be held by something that wants us to suspend.
3020 * If we're in RUNNING it will wait for us, and we'll be waiting
3021 * for the lock it holds.
3022 */
3023 assert(self->status != THREAD_RUNNING);
3024
3025 dvmCheckSuspendPending(self);
3026 self->status = THREAD_RUNNING;
3027 } else {
3028 /*
3029 * Change from one state to another, neither of which is
3030 * THREAD_RUNNING. This is most common during system or thread
3031 * initialization.
3032 */
3033 self->status = newStatus;
3034 }
3035
3036 return oldStatus;
3037}
3038
3039/*
3040 * Get a statically defined thread group from a field in the ThreadGroup
3041 * Class object. Expected arguments are "mMain" and "mSystem".
3042 */
3043static Object* getStaticThreadGroup(const char* fieldName)
3044{
3045 StaticField* groupField;
3046 Object* groupObj;
3047
3048 groupField = dvmFindStaticField(gDvm.classJavaLangThreadGroup,
3049 fieldName, "Ljava/lang/ThreadGroup;");
3050 if (groupField == NULL) {
3051 LOGE("java.lang.ThreadGroup does not have an '%s' field\n", fieldName);
3052 dvmThrowException("Ljava/lang/IncompatibleClassChangeError;", NULL);
3053 return NULL;
3054 }
3055 groupObj = dvmGetStaticFieldObject(groupField);
3056 if (groupObj == NULL) {
3057 LOGE("java.lang.ThreadGroup.%s not initialized\n", fieldName);
3058 dvmThrowException("Ljava/lang/InternalError;", NULL);
3059 return NULL;
3060 }
3061
3062 return groupObj;
3063}
3064Object* dvmGetSystemThreadGroup(void)
3065{
3066 return getStaticThreadGroup("mSystem");
3067}
3068Object* dvmGetMainThreadGroup(void)
3069{
3070 return getStaticThreadGroup("mMain");
3071}
3072
3073/*
3074 * Given a VMThread object, return the associated Thread*.
3075 *
3076 * NOTE: if the thread detaches, the struct Thread will disappear, and
3077 * we will be touching invalid data. For safety, lock the thread list
3078 * before calling this.
3079 */
3080Thread* dvmGetThreadFromThreadObject(Object* vmThreadObj)
3081{
3082 int vmData;
3083
3084 vmData = dvmGetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData);
Andy McFadden44860362009-08-06 17:56:14 -07003085
3086 if (false) {
3087 Thread* thread = gDvm.threadList;
3088 while (thread != NULL) {
3089 if ((Thread*)vmData == thread)
3090 break;
3091
3092 thread = thread->next;
3093 }
3094
3095 if (thread == NULL) {
3096 LOGW("WARNING: vmThreadObj=%p has thread=%p, not in thread list\n",
3097 vmThreadObj, (Thread*)vmData);
3098 vmData = 0;
3099 }
3100 }
3101
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003102 return (Thread*) vmData;
3103}
3104
3105
3106/*
3107 * Conversion map for "nice" values.
3108 *
3109 * We use Android thread priority constants to be consistent with the rest
3110 * of the system. In some cases adjacent entries may overlap.
3111 */
3112static const int kNiceValues[10] = {
3113 ANDROID_PRIORITY_LOWEST, /* 1 (MIN_PRIORITY) */
3114 ANDROID_PRIORITY_BACKGROUND + 6,
3115 ANDROID_PRIORITY_BACKGROUND + 3,
3116 ANDROID_PRIORITY_BACKGROUND,
3117 ANDROID_PRIORITY_NORMAL, /* 5 (NORM_PRIORITY) */
3118 ANDROID_PRIORITY_NORMAL - 2,
3119 ANDROID_PRIORITY_NORMAL - 4,
3120 ANDROID_PRIORITY_URGENT_DISPLAY + 3,
3121 ANDROID_PRIORITY_URGENT_DISPLAY + 2,
3122 ANDROID_PRIORITY_URGENT_DISPLAY /* 10 (MAX_PRIORITY) */
3123};
3124
3125/*
3126 * Change the priority of a system thread to match that of the Thread object.
3127 *
3128 * We map a priority value from 1-10 to Linux "nice" values, where lower
3129 * numbers indicate higher priority.
3130 */
3131void dvmChangeThreadPriority(Thread* thread, int newPriority)
3132{
3133 pid_t pid = thread->systemTid;
3134 int newNice;
3135
3136 if (newPriority < 1 || newPriority > 10) {
3137 LOGW("bad priority %d\n", newPriority);
3138 newPriority = 5;
3139 }
3140 newNice = kNiceValues[newPriority-1];
3141
Andy McFaddend62c0b52009-08-04 15:02:12 -07003142 if (newNice >= ANDROID_PRIORITY_BACKGROUND) {
San Mehat5a2056c2009-09-12 10:10:13 -07003143 set_sched_policy(dvmGetSysThreadId(), SP_BACKGROUND);
San Mehat3e371e22009-06-26 08:36:16 -07003144 } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
San Mehat5a2056c2009-09-12 10:10:13 -07003145 set_sched_policy(dvmGetSysThreadId(), SP_FOREGROUND);
San Mehat256fc152009-04-21 14:03:06 -07003146 }
3147
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003148 if (setpriority(PRIO_PROCESS, pid, newNice) != 0) {
3149 char* str = dvmGetThreadName(thread);
3150 LOGI("setPriority(%d) '%s' to prio=%d(n=%d) failed: %s\n",
3151 pid, str, newPriority, newNice, strerror(errno));
3152 free(str);
3153 } else {
3154 LOGV("setPriority(%d) to prio=%d(n=%d)\n",
3155 pid, newPriority, newNice);
3156 }
3157}
3158
3159/*
3160 * Get the thread priority for the current thread by querying the system.
3161 * This is useful when attaching a thread through JNI.
3162 *
3163 * Returns a value from 1 to 10 (compatible with java.lang.Thread values).
3164 */
3165static int getThreadPriorityFromSystem(void)
3166{
3167 int i, sysprio, jprio;
3168
3169 errno = 0;
3170 sysprio = getpriority(PRIO_PROCESS, 0);
3171 if (sysprio == -1 && errno != 0) {
3172 LOGW("getpriority() failed: %s\n", strerror(errno));
3173 return THREAD_NORM_PRIORITY;
3174 }
3175
3176 jprio = THREAD_MIN_PRIORITY;
3177 for (i = 0; i < NELEM(kNiceValues); i++) {
3178 if (sysprio >= kNiceValues[i])
3179 break;
3180 jprio++;
3181 }
3182 if (jprio > THREAD_MAX_PRIORITY)
3183 jprio = THREAD_MAX_PRIORITY;
3184
3185 return jprio;
3186}
3187
3188
3189/*
3190 * Return true if the thread is on gDvm.threadList.
3191 * Caller should not hold gDvm.threadListLock.
3192 */
3193bool dvmIsOnThreadList(const Thread* thread)
3194{
3195 bool ret = false;
3196
3197 dvmLockThreadList(NULL);
3198 if (thread == gDvm.threadList) {
3199 ret = true;
3200 } else {
3201 ret = thread->prev != NULL || thread->next != NULL;
3202 }
3203 dvmUnlockThreadList();
3204
3205 return ret;
3206}
3207
3208/*
3209 * Dump a thread to the log file -- just calls dvmDumpThreadEx() with an
3210 * output target.
3211 */
3212void dvmDumpThread(Thread* thread, bool isRunning)
3213{
3214 DebugOutputTarget target;
3215
3216 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
3217 dvmDumpThreadEx(&target, thread, isRunning);
3218}
3219
3220/*
Andy McFaddend62c0b52009-08-04 15:02:12 -07003221 * Try to get the scheduler group.
3222 *
3223 * The data from /proc/<pid>/cgroup looks like:
3224 * 2:cpu:/bg_non_interactive
3225 *
3226 * We return the part after the "/", which will be an empty string for
3227 * the default cgroup. If the string is longer than "bufLen", the string
3228 * will be truncated.
3229 */
3230static bool getSchedulerGroup(Thread* thread, char* buf, size_t bufLen)
3231{
3232#ifdef HAVE_ANDROID_OS
3233 char pathBuf[32];
3234 char readBuf[256];
3235 ssize_t count;
3236 int fd;
3237
3238 snprintf(pathBuf, sizeof(pathBuf), "/proc/%d/cgroup", thread->systemTid);
3239 if ((fd = open(pathBuf, O_RDONLY)) < 0) {
3240 LOGV("open(%s) failed: %s\n", pathBuf, strerror(errno));
3241 return false;
3242 }
3243
3244 count = read(fd, readBuf, sizeof(readBuf));
3245 if (count <= 0) {
3246 LOGV("read(%s) failed (%d): %s\n",
3247 pathBuf, (int) count, strerror(errno));
3248 close(fd);
3249 return false;
3250 }
3251 close(fd);
3252
3253 readBuf[--count] = '\0'; /* remove the '\n', now count==strlen */
3254
3255 char* cp = strchr(readBuf, '/');
3256 if (cp == NULL) {
3257 readBuf[sizeof(readBuf)-1] = '\0';
3258 LOGV("no '/' in '%s' (file=%s count=%d)\n",
3259 readBuf, pathBuf, (int) count);
3260 return false;
3261 }
3262
3263 memcpy(buf, cp+1, count); /* count-1 for cp+1, count+1 for NUL */
3264 return true;
3265#else
3266 return false;
3267#endif
3268}
3269
3270/*
Ben Cheng7a0bcd02010-01-22 16:45:45 -08003271 * Convert ThreadStatus to a string.
3272 */
3273const char* dvmGetThreadStatusStr(ThreadStatus status)
3274{
3275 switch (status) {
3276 case THREAD_ZOMBIE: return "ZOMBIE";
3277 case THREAD_RUNNING: return "RUNNABLE";
3278 case THREAD_TIMED_WAIT: return "TIMED_WAIT";
3279 case THREAD_MONITOR: return "MONITOR";
3280 case THREAD_WAIT: return "WAIT";
3281 case THREAD_INITIALIZING: return "INITIALIZING";
3282 case THREAD_STARTING: return "STARTING";
3283 case THREAD_NATIVE: return "NATIVE";
3284 case THREAD_VMWAIT: return "VMWAIT";
3285 default: return "UNKNOWN";
3286 }
3287}
3288
3289/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003290 * Print information about the specified thread.
3291 *
3292 * Works best when the thread in question is "self" or has been suspended.
3293 * When dumping a separate thread that's still running, set "isRunning" to
3294 * use a more cautious thread dump function.
3295 */
3296void dvmDumpThreadEx(const DebugOutputTarget* target, Thread* thread,
3297 bool isRunning)
3298{
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003299 Object* threadObj;
3300 Object* groupObj;
3301 StringObject* nameStr;
3302 char* threadName = NULL;
3303 char* groupName = NULL;
Andy McFaddend62c0b52009-08-04 15:02:12 -07003304 char schedulerGroupBuf[32];
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003305 bool isDaemon;
3306 int priority; // java.lang.Thread priority
3307 int policy; // pthread policy
3308 struct sched_param sp; // pthread scheduling parameters
3309
3310 threadObj = thread->threadObj;
3311 if (threadObj == NULL) {
3312 LOGW("Can't dump thread %d: threadObj not set\n", thread->threadId);
3313 return;
3314 }
3315 nameStr = (StringObject*) dvmGetFieldObject(threadObj,
3316 gDvm.offJavaLangThread_name);
3317 threadName = dvmCreateCstrFromString(nameStr);
3318
3319 priority = dvmGetFieldInt(threadObj, gDvm.offJavaLangThread_priority);
3320 isDaemon = dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon);
3321
3322 if (pthread_getschedparam(pthread_self(), &policy, &sp) != 0) {
3323 LOGW("Warning: pthread_getschedparam failed\n");
3324 policy = -1;
3325 sp.sched_priority = -1;
3326 }
Andy McFaddend62c0b52009-08-04 15:02:12 -07003327 if (!getSchedulerGroup(thread, schedulerGroupBuf,sizeof(schedulerGroupBuf)))
3328 {
3329 strcpy(schedulerGroupBuf, "unknown");
3330 } else if (schedulerGroupBuf[0] == '\0') {
3331 strcpy(schedulerGroupBuf, "default");
3332 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003333
3334 /* a null value for group is not expected, but deal with it anyway */
3335 groupObj = (Object*) dvmGetFieldObject(threadObj,
3336 gDvm.offJavaLangThread_group);
3337 if (groupObj != NULL) {
3338 int offset = dvmFindFieldOffset(gDvm.classJavaLangThreadGroup,
3339 "name", "Ljava/lang/String;");
3340 if (offset < 0) {
3341 LOGW("Unable to find 'name' field in ThreadGroup\n");
3342 } else {
3343 nameStr = (StringObject*) dvmGetFieldObject(groupObj, offset);
3344 groupName = dvmCreateCstrFromString(nameStr);
3345 }
3346 }
3347 if (groupName == NULL)
3348 groupName = strdup("(BOGUS GROUP)");
3349
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003350 dvmPrintDebugMessage(target,
3351 "\"%s\"%s prio=%d tid=%d %s\n",
3352 threadName, isDaemon ? " daemon" : "",
Ben Cheng7a0bcd02010-01-22 16:45:45 -08003353 priority, thread->threadId, dvmGetThreadStatusStr(thread->status));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003354 dvmPrintDebugMessage(target,
Andy McFadden2aa43612009-06-17 16:29:30 -07003355 " | group=\"%s\" sCount=%d dsCount=%d s=%c obj=%p self=%p\n",
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003356 groupName, thread->suspendCount, thread->dbgSuspendCount,
Andy McFadden2aa43612009-06-17 16:29:30 -07003357 thread->isSuspended ? 'Y' : 'N', thread->threadObj, thread);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003358 dvmPrintDebugMessage(target,
Andy McFaddend62c0b52009-08-04 15:02:12 -07003359 " | sysTid=%d nice=%d sched=%d/%d cgrp=%s handle=%d\n",
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003360 thread->systemTid, getpriority(PRIO_PROCESS, thread->systemTid),
Andy McFaddend62c0b52009-08-04 15:02:12 -07003361 policy, sp.sched_priority, schedulerGroupBuf, (int)thread->handle);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003362
3363#ifdef WITH_MONITOR_TRACKING
3364 if (!isRunning) {
3365 LockedObjectData* lod = thread->pLockedObjects;
3366 if (lod != NULL)
3367 dvmPrintDebugMessage(target, " | monitors held:\n");
3368 else
3369 dvmPrintDebugMessage(target, " | monitors held: <none>\n");
3370 while (lod != NULL) {
Elliott Hughesbeea0b72009-11-13 11:20:15 -08003371 Object* obj = lod->obj;
3372 if (obj->clazz == gDvm.classJavaLangClass) {
3373 ClassObject* clazz = (ClassObject*) obj;
3374 dvmPrintDebugMessage(target, " > %p[%d] (%s object for class %s)\n",
3375 obj, lod->recursionCount, obj->clazz->descriptor,
3376 clazz->descriptor);
3377 } else {
3378 dvmPrintDebugMessage(target, " > %p[%d] (%s)\n",
3379 obj, lod->recursionCount, obj->clazz->descriptor);
3380 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003381 lod = lod->next;
3382 }
3383 }
3384#endif
3385
3386 if (isRunning)
3387 dvmDumpRunningThreadStack(target, thread);
3388 else
3389 dvmDumpThreadStack(target, thread);
3390
3391 free(threadName);
3392 free(groupName);
3393
3394}
3395
3396/*
3397 * Get the name of a thread.
3398 *
3399 * For correctness, the caller should hold the thread list lock to ensure
3400 * that the thread doesn't go away mid-call.
3401 *
3402 * Returns a newly-allocated string, or NULL if the Thread doesn't have a name.
3403 */
3404char* dvmGetThreadName(Thread* thread)
3405{
3406 StringObject* nameObj;
3407
3408 if (thread->threadObj == NULL) {
3409 LOGW("threadObj is NULL, name not available\n");
3410 return strdup("-unknown-");
3411 }
3412
3413 nameObj = (StringObject*)
3414 dvmGetFieldObject(thread->threadObj, gDvm.offJavaLangThread_name);
3415 return dvmCreateCstrFromString(nameObj);
3416}
3417
3418/*
3419 * Dump all threads to the log file -- just calls dvmDumpAllThreadsEx() with
3420 * an output target.
3421 */
3422void dvmDumpAllThreads(bool grabLock)
3423{
3424 DebugOutputTarget target;
3425
3426 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
3427 dvmDumpAllThreadsEx(&target, grabLock);
3428}
3429
3430/*
3431 * Print information about all known threads. Assumes they have been
3432 * suspended (or are in a non-interpreting state, e.g. WAIT or NATIVE).
3433 *
3434 * If "grabLock" is true, we grab the thread lock list. This is important
3435 * to do unless the caller already holds the lock.
3436 */
3437void dvmDumpAllThreadsEx(const DebugOutputTarget* target, bool grabLock)
3438{
3439 Thread* thread;
3440
3441 dvmPrintDebugMessage(target, "DALVIK THREADS:\n");
3442
3443 if (grabLock)
3444 dvmLockThreadList(dvmThreadSelf());
3445
3446 thread = gDvm.threadList;
3447 while (thread != NULL) {
3448 dvmDumpThreadEx(target, thread, false);
3449
3450 /* verify link */
3451 assert(thread->next == NULL || thread->next->prev == thread);
3452
3453 thread = thread->next;
3454 }
3455
3456 if (grabLock)
3457 dvmUnlockThreadList();
3458}
3459
3460#ifdef WITH_MONITOR_TRACKING
3461/*
3462 * Count up the #of locked objects in the current thread.
3463 */
3464static int getThreadObjectCount(const Thread* self)
3465{
3466 LockedObjectData* lod;
3467 int count = 0;
3468
3469 lod = self->pLockedObjects;
3470 while (lod != NULL) {
3471 count++;
3472 lod = lod->next;
3473 }
3474 return count;
3475}
3476
3477/*
3478 * Add the object to the thread's locked object list if it doesn't already
3479 * exist. The most recently added object is the most likely to be released
3480 * next, so we insert at the head of the list.
3481 *
3482 * If it already exists, we increase the recursive lock count.
3483 *
3484 * The object's lock may be thin or fat.
3485 */
3486void dvmAddToMonitorList(Thread* self, Object* obj, bool withTrace)
3487{
3488 LockedObjectData* newLod;
3489 LockedObjectData* lod;
3490 int* trace;
3491 int depth;
3492
3493 lod = self->pLockedObjects;
3494 while (lod != NULL) {
3495 if (lod->obj == obj) {
3496 lod->recursionCount++;
3497 LOGV("+++ +recursive lock %p -> %d\n", obj, lod->recursionCount);
3498 return;
3499 }
3500 lod = lod->next;
3501 }
3502
3503 newLod = (LockedObjectData*) calloc(1, sizeof(LockedObjectData));
3504 if (newLod == NULL) {
3505 LOGE("malloc failed on %d bytes\n", sizeof(LockedObjectData));
3506 return;
3507 }
3508 newLod->obj = obj;
3509 newLod->recursionCount = 0;
3510
3511 if (withTrace) {
3512 trace = dvmFillInStackTraceRaw(self, &depth);
3513 newLod->rawStackTrace = trace;
3514 newLod->stackDepth = depth;
3515 }
3516
3517 newLod->next = self->pLockedObjects;
3518 self->pLockedObjects = newLod;
3519
3520 LOGV("+++ threadid=%d: added %p, now %d\n",
3521 self->threadId, newLod, getThreadObjectCount(self));
3522}
3523
3524/*
3525 * Remove the object from the thread's locked object list. If the entry
3526 * has a nonzero recursion count, we just decrement the count instead.
3527 */
3528void dvmRemoveFromMonitorList(Thread* self, Object* obj)
3529{
3530 LockedObjectData* lod;
3531 LockedObjectData* prevLod;
3532
3533 lod = self->pLockedObjects;
3534 prevLod = NULL;
3535 while (lod != NULL) {
3536 if (lod->obj == obj) {
3537 if (lod->recursionCount > 0) {
3538 lod->recursionCount--;
3539 LOGV("+++ -recursive lock %p -> %d\n",
3540 obj, lod->recursionCount);
3541 return;
3542 } else {
3543 break;
3544 }
3545 }
3546 prevLod = lod;
3547 lod = lod->next;
3548 }
3549
3550 if (lod == NULL) {
3551 LOGW("BUG: object %p not found in thread's lock list\n", obj);
3552 return;
3553 }
3554 if (prevLod == NULL) {
3555 /* first item in list */
3556 assert(self->pLockedObjects == lod);
3557 self->pLockedObjects = lod->next;
3558 } else {
3559 /* middle/end of list */
3560 prevLod->next = lod->next;
3561 }
3562
3563 LOGV("+++ threadid=%d: removed %p, now %d\n",
3564 self->threadId, lod, getThreadObjectCount(self));
3565 free(lod->rawStackTrace);
3566 free(lod);
3567}
3568
3569/*
3570 * If the specified object is already in the thread's locked object list,
3571 * return the LockedObjectData struct. Otherwise return NULL.
3572 */
3573LockedObjectData* dvmFindInMonitorList(const Thread* self, const Object* obj)
3574{
3575 LockedObjectData* lod;
3576
3577 lod = self->pLockedObjects;
3578 while (lod != NULL) {
3579 if (lod->obj == obj)
3580 return lod;
3581 lod = lod->next;
3582 }
3583 return NULL;
3584}
3585#endif /*WITH_MONITOR_TRACKING*/
3586
3587
3588/*
3589 * GC helper functions
3590 */
3591
The Android Open Source Project99409882009-03-18 22:20:24 -07003592/*
3593 * Add the contents of the registers from the interpreted call stack.
3594 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003595static void gcScanInterpStackReferences(Thread *thread)
3596{
3597 const u4 *framePtr;
The Android Open Source Project99409882009-03-18 22:20:24 -07003598#if WITH_EXTRA_GC_CHECKS > 1
3599 bool first = true;
3600#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003601
3602 framePtr = (const u4 *)thread->curFrame;
3603 while (framePtr != NULL) {
3604 const StackSaveArea *saveArea;
3605 const Method *method;
3606
3607 saveArea = SAVEAREA_FROM_FP(framePtr);
3608 method = saveArea->method;
The Android Open Source Project99409882009-03-18 22:20:24 -07003609 if (method != NULL && !dvmIsNativeMethod(method)) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003610#ifdef COUNT_PRECISE_METHODS
3611 /* the GC is running, so no lock required */
The Android Open Source Project99409882009-03-18 22:20:24 -07003612 if (dvmPointerSetAddEntry(gDvm.preciseMethods, method))
3613 LOGI("PGC: added %s.%s %p\n",
3614 method->clazz->descriptor, method->name, method);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003615#endif
The Android Open Source Project99409882009-03-18 22:20:24 -07003616#if WITH_EXTRA_GC_CHECKS > 1
3617 /*
3618 * May also want to enable the memset() in the "invokeMethod"
3619 * goto target in the portable interpreter. That sets the stack
3620 * to a pattern that makes referring to uninitialized data
3621 * very obvious.
3622 */
3623
3624 if (first) {
3625 /*
3626 * First frame, isn't native, check the "alternate" saved PC
3627 * as a sanity check.
3628 *
3629 * It seems like we could check the second frame if the first
3630 * is native, since the PCs should be the same. It turns out
3631 * this doesn't always work. The problem is that we could
3632 * have calls in the sequence:
3633 * interp method #2
3634 * native method
3635 * interp method #1
3636 *
3637 * and then GC while in the native method after returning
3638 * from interp method #2. The currentPc on the stack is
3639 * for interp method #1, but thread->currentPc2 is still
3640 * set for the last thing interp method #2 did.
3641 *
3642 * This can also happen in normal execution:
3643 * - sget-object on not-yet-loaded class
3644 * - class init updates currentPc2
3645 * - static field init is handled by parsing annotations;
3646 * static String init requires creation of a String object,
3647 * which can cause a GC
3648 *
3649 * Essentially, any pattern that involves executing
3650 * interpreted code and then causes an allocation without
3651 * executing instructions in the original method will hit
3652 * this. These are rare enough that the test still has
3653 * some value.
3654 */
3655 if (saveArea->xtra.currentPc != thread->currentPc2) {
3656 LOGW("PGC: savedPC(%p) != current PC(%p), %s.%s ins=%p\n",
3657 saveArea->xtra.currentPc, thread->currentPc2,
3658 method->clazz->descriptor, method->name, method->insns);
3659 if (saveArea->xtra.currentPc != NULL)
3660 LOGE(" pc inst = 0x%04x\n", *saveArea->xtra.currentPc);
3661 if (thread->currentPc2 != NULL)
3662 LOGE(" pc2 inst = 0x%04x\n", *thread->currentPc2);
3663 dvmDumpThread(thread, false);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003664 }
The Android Open Source Project99409882009-03-18 22:20:24 -07003665 } else {
3666 /*
3667 * It's unusual, but not impossible, for a non-first frame
3668 * to be at something other than a method invocation. For
3669 * example, if we do a new-instance on a nonexistent class,
3670 * we'll have a lot of class loader activity on the stack
3671 * above the frame with the "new" operation. Could also
3672 * happen while we initialize a Throwable when an instruction
3673 * fails.
3674 *
3675 * So there's not much we can do here to verify the PC,
3676 * except to verify that it's a GC point.
3677 */
3678 }
3679 assert(saveArea->xtra.currentPc != NULL);
3680#endif
3681
3682 const RegisterMap* pMap;
3683 const u1* regVector;
3684 int i;
3685
Andy McFaddencf8b55c2009-04-13 15:26:03 -07003686 Method* nonConstMethod = (Method*) method; // quiet gcc
3687 pMap = dvmGetExpandedRegisterMap(nonConstMethod);
The Android Open Source Project99409882009-03-18 22:20:24 -07003688 if (pMap != NULL) {
3689 /* found map, get registers for this address */
3690 int addr = saveArea->xtra.currentPc - method->insns;
Andy McFaddend45a8872009-03-24 20:41:52 -07003691 regVector = dvmRegisterMapGetLine(pMap, addr);
The Android Open Source Project99409882009-03-18 22:20:24 -07003692 if (regVector == NULL) {
3693 LOGW("PGC: map but no entry for %s.%s addr=0x%04x\n",
3694 method->clazz->descriptor, method->name, addr);
3695 } else {
3696 LOGV("PGC: found map for %s.%s 0x%04x (t=%d)\n",
3697 method->clazz->descriptor, method->name, addr,
3698 thread->threadId);
3699 }
3700 } else {
3701 /*
3702 * No map found. If precise GC is disabled this is
3703 * expected -- we don't create pointers to the map data even
3704 * if it's present -- but if it's enabled it means we're
3705 * unexpectedly falling back on a conservative scan, so it's
3706 * worth yelling a little.
The Android Open Source Project99409882009-03-18 22:20:24 -07003707 */
3708 if (gDvm.preciseGc) {
Andy McFaddena66a01a2009-08-18 15:11:35 -07003709 LOGVV("PGC: no map for %s.%s\n",
The Android Open Source Project99409882009-03-18 22:20:24 -07003710 method->clazz->descriptor, method->name);
3711 }
3712 regVector = NULL;
3713 }
3714
3715 if (regVector == NULL) {
3716 /* conservative scan */
3717 for (i = method->registersSize - 1; i >= 0; i--) {
3718 u4 rval = *framePtr++;
3719 if (rval != 0 && (rval & 0x3) == 0) {
3720 dvmMarkIfObject((Object *)rval);
3721 }
3722 }
3723 } else {
3724 /*
3725 * Precise scan. v0 is at the lowest address on the
3726 * interpreted stack, and is the first bit in the register
3727 * vector, so we can walk through the register map and
3728 * memory in the same direction.
3729 *
3730 * A '1' bit indicates a live reference.
3731 */
3732 u2 bits = 1 << 1;
3733 for (i = method->registersSize - 1; i >= 0; i--) {
3734 u4 rval = *framePtr++;
3735
3736 bits >>= 1;
3737 if (bits == 1) {
3738 /* set bit 9 so we can tell when we're empty */
3739 bits = *regVector++ | 0x0100;
3740 LOGVV("loaded bits: 0x%02x\n", bits & 0xff);
3741 }
3742
3743 if (rval != 0 && (bits & 0x01) != 0) {
3744 /*
3745 * Non-null, register marked as live reference. This
3746 * should always be a valid object.
3747 */
3748#if WITH_EXTRA_GC_CHECKS > 0
3749 if ((rval & 0x3) != 0 ||
3750 !dvmIsValidObject((Object*) rval))
3751 {
3752 /* this is very bad */
3753 LOGE("PGC: invalid ref in reg %d: 0x%08x\n",
3754 method->registersSize-1 - i, rval);
3755 } else
3756#endif
3757 {
3758 dvmMarkObjectNonNull((Object *)rval);
3759 }
3760 } else {
3761 /*
3762 * Null or non-reference, do nothing at all.
3763 */
3764#if WITH_EXTRA_GC_CHECKS > 1
3765 if (dvmIsValidObject((Object*) rval)) {
3766 /* this is normal, but we feel chatty */
3767 LOGD("PGC: ignoring valid ref in reg %d: 0x%08x\n",
3768 method->registersSize-1 - i, rval);
3769 }
3770#endif
3771 }
3772 }
3773 dvmReleaseRegisterMapLine(pMap, regVector);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003774 }
3775 }
The Android Open Source Project99409882009-03-18 22:20:24 -07003776 /* else this is a break frame and there is nothing to mark, or
3777 * this is a native method and the registers are just the "ins",
3778 * copied from various registers in the caller's set.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003779 */
3780
The Android Open Source Project99409882009-03-18 22:20:24 -07003781#if WITH_EXTRA_GC_CHECKS > 1
3782 first = false;
3783#endif
3784
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003785 /* Don't fall into an infinite loop if things get corrupted.
3786 */
3787 assert((uintptr_t)saveArea->prevFrame > (uintptr_t)framePtr ||
3788 saveArea->prevFrame == NULL);
3789 framePtr = saveArea->prevFrame;
3790 }
3791}
3792
3793static void gcScanReferenceTable(ReferenceTable *refTable)
3794{
3795 Object **op;
3796
3797 //TODO: these asserts are overkill; turn them off when things stablize.
3798 assert(refTable != NULL);
3799 assert(refTable->table != NULL);
3800 assert(refTable->nextEntry != NULL);
3801 assert((uintptr_t)refTable->nextEntry >= (uintptr_t)refTable->table);
3802 assert(refTable->nextEntry - refTable->table <= refTable->maxEntries);
3803
3804 op = refTable->table;
3805 while ((uintptr_t)op < (uintptr_t)refTable->nextEntry) {
3806 dvmMarkObjectNonNull(*(op++));
3807 }
3808}
3809
Andy McFaddend5ab7262009-08-25 07:19:34 -07003810static void gcScanIndirectRefTable(IndirectRefTable* pRefTable)
3811{
3812 Object** op = pRefTable->table;
3813 int numEntries = dvmIndirectRefTableEntries(pRefTable);
3814 int i;
3815
3816 for (i = 0; i < numEntries; i++) {
3817 Object* obj = *op;
3818 if (obj != NULL)
3819 dvmMarkObjectNonNull(obj);
3820 op++;
3821 }
3822}
3823
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003824/*
3825 * Scan a Thread and mark any objects it references.
3826 */
3827static void gcScanThread(Thread *thread)
3828{
3829 assert(thread != NULL);
3830
3831 /*
3832 * The target thread must be suspended or in a state where it can't do
3833 * any harm (e.g. in Object.wait()). The only exception is the current
3834 * thread, which will still be active and in the "running" state.
3835 *
3836 * (Newly-created threads shouldn't be able to shift themselves to
3837 * RUNNING without a suspend-pending check, so this shouldn't cause
3838 * a false-positive.)
3839 */
Andy McFaddend40223e2009-12-07 15:35:51 -08003840 if (thread->status == THREAD_RUNNING && !thread->isSuspended &&
3841 thread != dvmThreadSelf())
3842 {
3843 Thread* self = dvmThreadSelf();
3844 LOGW("threadid=%d: BUG: GC scanning a running thread (%d)\n",
3845 self->threadId, thread->threadId);
3846 dvmDumpThread(thread, true);
3847 LOGW("Found by:\n");
3848 dvmDumpThread(self, false);
3849
3850 /* continue anyway? */
3851 dvmAbort();
3852 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003853
3854 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_THREAD_OBJECT, thread->threadId);
3855
3856 dvmMarkObject(thread->threadObj); // could be NULL, when constructing
3857
3858 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_NATIVE_STACK, thread->threadId);
3859
3860 dvmMarkObject(thread->exception); // usually NULL
3861 gcScanReferenceTable(&thread->internalLocalRefTable);
3862
3863 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_LOCAL, thread->threadId);
3864
Andy McFaddend5ab7262009-08-25 07:19:34 -07003865#ifdef USE_INDIRECT_REF
3866 gcScanIndirectRefTable(&thread->jniLocalRefTable);
3867#else
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003868 gcScanReferenceTable(&thread->jniLocalRefTable);
Andy McFaddend5ab7262009-08-25 07:19:34 -07003869#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003870
3871 if (thread->jniMonitorRefTable.table != NULL) {
3872 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_MONITOR, thread->threadId);
3873
3874 gcScanReferenceTable(&thread->jniMonitorRefTable);
3875 }
3876
3877 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JAVA_FRAME, thread->threadId);
3878
3879 gcScanInterpStackReferences(thread);
3880
3881 HPROF_CLEAR_GC_SCAN_STATE();
3882}
3883
3884static void gcScanAllThreads()
3885{
3886 Thread *thread;
3887
3888 /* Lock the thread list so we can safely use the
3889 * next/prev pointers.
3890 */
3891 dvmLockThreadList(dvmThreadSelf());
3892
3893 for (thread = gDvm.threadList; thread != NULL;
3894 thread = thread->next)
3895 {
3896 /* We need to scan our own stack, so don't special-case
3897 * the current thread.
3898 */
3899 gcScanThread(thread);
3900 }
3901
3902 dvmUnlockThreadList();
3903}
3904
3905void dvmGcScanRootThreadGroups()
3906{
3907 /* We scan the VM's list of threads instead of going
3908 * through the actual ThreadGroups, but it should be
3909 * equivalent.
3910 *
Jeff Hao97319a82009-08-12 16:57:15 -07003911 * This assumes that the ThreadGroup class object is in
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003912 * the root set, which should always be true; it's
3913 * loaded by the built-in class loader, which is part
3914 * of the root set.
3915 */
3916 gcScanAllThreads();
3917}