blob: 7c9df3e74f913731976ab7ab3e75bbb61c3912ca [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"
21
Jeff Hao97319a82009-08-12 16:57:15 -070022#include "interp/Jit.h" // need for self verification
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080023#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
33#if defined(HAVE_PRCTL)
34#include <sys/prctl.h>
35#endif
36
37/* desktop Linux needs a little help with gettid() */
38#if defined(HAVE_GETTID) && !defined(HAVE_ANDROID_OS)
39#define __KERNEL__
40# include <linux/unistd.h>
41#ifdef _syscall0
42_syscall0(pid_t,gettid)
43#else
44pid_t gettid() { return syscall(__NR_gettid);}
45#endif
46#undef __KERNEL__
47#endif
48
San Mehat256fc152009-04-21 14:03:06 -070049// Change this to enable logging on cgroup errors
50#define ENABLE_CGROUP_ERR_LOGGING 0
51
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080052// change this to LOGV/LOGD to debug thread activity
53#define LOG_THREAD LOGVV
54
55/*
56Notes on Threading
57
58All threads are native pthreads. All threads, except the JDWP debugger
59thread, are visible to code running in the VM and to the debugger. (We
60don't want the debugger to try to manipulate the thread that listens for
61instructions from the debugger.) Internal VM threads are in the "system"
62ThreadGroup, all others are in the "main" ThreadGroup, per convention.
63
64The GC only runs when all threads have been suspended. Threads are
65expected to suspend themselves, using a "safe point" mechanism. We check
66for a suspend request at certain points in the main interpreter loop,
67and on requests coming in from native code (e.g. all JNI functions).
68Certain debugger events may inspire threads to self-suspend.
69
70Native methods must use JNI calls to modify object references to avoid
71clashes with the GC. JNI doesn't provide a way for native code to access
72arrays of objects as such -- code must always get/set individual entries --
73so it should be possible to fully control access through JNI.
74
75Internal native VM threads, such as the finalizer thread, must explicitly
76check for suspension periodically. In most cases they will be sound
77asleep on a condition variable, and won't notice the suspension anyway.
78
79Threads may be suspended by the GC, debugger, or the SIGQUIT listener
80thread. The debugger may suspend or resume individual threads, while the
81GC always suspends all threads. Each thread has a "suspend count" that
82is incremented on suspend requests and decremented on resume requests.
83When the count is zero, the thread is runnable. This allows us to fulfill
84a debugger requirement: if the debugger suspends a thread, the thread is
85not allowed to run again until the debugger resumes it (or disconnects,
86in which case we must resume all debugger-suspended threads).
87
88Paused threads sleep on a condition variable, and are awoken en masse.
89Certain "slow" VM operations, such as starting up a new thread, will be
90done in a separate "VMWAIT" state, so that the rest of the VM doesn't
91freeze up waiting for the operation to finish. Threads must check for
92pending suspension when leaving VMWAIT.
93
94Because threads suspend themselves while interpreting code or when native
95code makes JNI calls, there is no risk of suspending while holding internal
96VM locks. All threads can enter a suspended (or native-code-only) state.
97Also, we don't have to worry about object references existing solely
98in hardware registers.
99
100We do, however, have to worry about objects that were allocated internally
101and aren't yet visible to anything else in the VM. If we allocate an
102object, and then go to sleep on a mutex after changing to a non-RUNNING
103state (e.g. while trying to allocate a second object), the first object
104could be garbage-collected out from under us while we sleep. To manage
105this, we automatically add all allocated objects to an internal object
106tracking list, and only remove them when we know we won't be suspended
107before the object appears in the GC root set.
108
109The debugger may choose to suspend or resume a single thread, which can
110lead to application-level deadlocks; this is expected behavior. The VM
111will only check for suspension of single threads when the debugger is
112active (the java.lang.Thread calls for this are deprecated and hence are
113not supported). Resumption of a single thread is handled by decrementing
114the thread's suspend count and sending a broadcast signal to the condition
115variable. (This will cause all threads to wake up and immediately go back
116to sleep, which isn't tremendously efficient, but neither is having the
117debugger attached.)
118
119The debugger is not allowed to resume threads suspended by the GC. This
120is trivially enforced by ignoring debugger requests while the GC is running
121(the JDWP thread is suspended during GC).
122
123The VM maintains a Thread struct for every pthread known to the VM. There
124is a java/lang/Thread object associated with every Thread. At present,
125there is no safe way to go from a Thread object to a Thread struct except by
126locking and scanning the list; this is necessary because the lifetimes of
127the two are not closely coupled. We may want to change this behavior,
128though at present the only performance impact is on the debugger (see
129threadObjToThread()). See also notes about dvmDetachCurrentThread().
130*/
131/*
132Alternate implementation (signal-based):
133
134Threads run without safe points -- zero overhead. The VM uses a signal
135(e.g. pthread_kill(SIGUSR1)) to notify threads of suspension or resumption.
136
137The trouble with using signals to suspend threads is that it means a thread
138can be in the middle of an operation when garbage collection starts.
139To prevent some sticky situations, we have to introduce critical sections
140to the VM code.
141
142Critical sections temporarily block suspension for a given thread.
143The thread must move to a non-blocked state (and self-suspend) after
144finishing its current task. If the thread blocks on a resource held
145by a suspended thread, we're hosed.
146
147One approach is to require that no blocking operations, notably
148acquisition of mutexes, can be performed within a critical section.
149This is too limiting. For example, if thread A gets suspended while
150holding the thread list lock, it will prevent the GC or debugger from
151being able to safely access the thread list. We need to wrap the critical
152section around the entire operation (enter critical, get lock, do stuff,
153release lock, exit critical).
154
155A better approach is to declare that certain resources can only be held
156within critical sections. A thread that enters a critical section and
157then gets blocked on the thread list lock knows that the thread it is
158waiting for is also in a critical section, and will release the lock
159before suspending itself. Eventually all threads will complete their
160operations and self-suspend. For this to work, the VM must:
161
162 (1) Determine the set of resources that may be accessed from the GC or
163 debugger threads. The mutexes guarding those go into the "critical
164 resource set" (CRS).
165 (2) Ensure that no resource in the CRS can be acquired outside of a
166 critical section. This can be verified with an assert().
167 (3) Ensure that only resources in the CRS can be held while in a critical
168 section. This is harder to enforce.
169
170If any of these conditions are not met, deadlock can ensue when grabbing
171resources in the GC or debugger (#1) or waiting for threads to suspend
172(#2,#3). (You won't actually deadlock in the GC, because if the semantics
173above are followed you don't need to lock anything in the GC. The risk is
174rather that the GC will access data structures in an intermediate state.)
175
176This approach requires more care and awareness in the VM than
177safe-pointing. Because the GC and debugger are fairly intrusive, there
178really aren't any internal VM resources that aren't shared. Thus, the
179enter/exit critical calls can be added to internal mutex wrappers, which
180makes it easy to get #1 and #2 right.
181
182An ordering should be established for all locks to avoid deadlocks.
183
184Monitor locks, which are also implemented with pthread calls, should not
185cause any problems here. Threads fighting over such locks will not be in
186critical sections and can be suspended freely.
187
188This can get tricky if we ever need exclusive access to VM and non-VM
189resources at the same time. It's not clear if this is a real concern.
190
191There are (at least) two ways to handle the incoming signals:
192
193 (a) Always accept signals. If we're in a critical section, the signal
194 handler just returns without doing anything (the "suspend level"
195 should have been incremented before the signal was sent). Otherwise,
196 if the "suspend level" is nonzero, we go to sleep.
197 (b) Block signals in critical sections. This ensures that we can't be
198 interrupted in a critical section, but requires pthread_sigmask()
199 calls on entry and exit.
200
201This is a choice between blocking the message and blocking the messenger.
202Because UNIX signals are unreliable (you can only know that you have been
203signaled, not whether you were signaled once or 10 times), the choice is
204not significant for correctness. The choice depends on the efficiency
205of pthread_sigmask() and the desire to actually block signals. Either way,
206it is best to ensure that there is only one indication of "blocked";
207having two (i.e. block signals and set a flag, then only send a signal
208if the flag isn't set) can lead to race conditions.
209
210The signal handler must take care to copy registers onto the stack (via
211setjmp), so that stack scans find all references. Because we have to scan
212native stacks, "exact" GC is not possible with this approach.
213
214Some other concerns with flinging signals around:
215 - Odd interactions with some debuggers (e.g. gdb on the Mac)
216 - Restrictions on some standard library calls during GC (e.g. don't
217 use printf on stdout to print GC debug messages)
218*/
219
220#define kMaxThreadId ((1<<15) - 1)
221#define kMainThreadId ((1<<1) | 1)
222
223
224static Thread* allocThread(int interpStackSize);
225static bool prepareThread(Thread* thread);
226static void setThreadSelf(Thread* thread);
227static void unlinkThread(Thread* thread);
228static void freeThread(Thread* thread);
229static void assignThreadId(Thread* thread);
230static bool createFakeEntryFrame(Thread* thread);
231static bool createFakeRunFrame(Thread* thread);
232static void* interpThreadStart(void* arg);
233static void* internalThreadStart(void* arg);
234static void threadExitUncaughtException(Thread* thread, Object* group);
235static void threadExitCheck(void* arg);
236static void waitForThreadSuspend(Thread* self, Thread* thread);
237static int getThreadPriorityFromSystem(void);
238
Bill Buzbee46cd5b62009-06-05 15:36:06 -0700239/*
240 * The JIT needs to know if any thread is suspended. We do this by
241 * maintaining a global sum of all threads' suspend counts. All suspendCount
242 * updates should go through this after aquiring threadSuspendCountLock.
243 */
244static inline void dvmAddToThreadSuspendCount(int *pSuspendCount, int delta)
245{
246 *pSuspendCount += delta;
247 gDvm.sumThreadSuspendCount += delta;
248}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800249
250/*
251 * Initialize thread list and main thread's environment. We need to set
252 * up some basic stuff so that dvmThreadSelf() will work when we start
253 * loading classes (e.g. to check for exceptions).
254 */
255bool dvmThreadStartup(void)
256{
257 Thread* thread;
258
259 /* allocate a TLS slot */
260 if (pthread_key_create(&gDvm.pthreadKeySelf, threadExitCheck) != 0) {
261 LOGE("ERROR: pthread_key_create failed\n");
262 return false;
263 }
264
265 /* test our pthread lib */
266 if (pthread_getspecific(gDvm.pthreadKeySelf) != NULL)
267 LOGW("WARNING: newly-created pthread TLS slot is not NULL\n");
268
269 /* prep thread-related locks and conditions */
270 dvmInitMutex(&gDvm.threadListLock);
271 pthread_cond_init(&gDvm.threadStartCond, NULL);
272 //dvmInitMutex(&gDvm.vmExitLock);
273 pthread_cond_init(&gDvm.vmExitCond, NULL);
274 dvmInitMutex(&gDvm._threadSuspendLock);
275 dvmInitMutex(&gDvm.threadSuspendCountLock);
276 pthread_cond_init(&gDvm.threadSuspendCountCond, NULL);
277#ifdef WITH_DEADLOCK_PREDICTION
278 dvmInitMutex(&gDvm.deadlockHistoryLock);
279#endif
280
281 /*
282 * Dedicated monitor for Thread.sleep().
283 * TODO: change this to an Object* so we don't have to expose this
284 * call, and we interact better with JDWP monitor calls. Requires
285 * deferring the object creation to much later (e.g. final "main"
286 * thread prep) or until first use.
287 */
288 gDvm.threadSleepMon = dvmCreateMonitor(NULL);
289
290 gDvm.threadIdMap = dvmAllocBitVector(kMaxThreadId, false);
291
292 thread = allocThread(gDvm.stackSize);
293 if (thread == NULL)
294 return false;
295
296 /* switch mode for when we run initializers */
297 thread->status = THREAD_RUNNING;
298
299 /*
300 * We need to assign the threadId early so we can lock/notify
301 * object monitors. We'll set the "threadObj" field later.
302 */
303 prepareThread(thread);
304 gDvm.threadList = thread;
305
306#ifdef COUNT_PRECISE_METHODS
307 gDvm.preciseMethods = dvmPointerSetAlloc(200);
308#endif
309
310 return true;
311}
312
313/*
314 * We're a little farther up now, and can load some basic classes.
315 *
316 * We're far enough along that we can poke at java.lang.Thread and friends,
317 * but should not assume that static initializers have run (or cause them
318 * to do so). That means no object allocations yet.
319 */
320bool dvmThreadObjStartup(void)
321{
322 /*
323 * Cache the locations of these classes. It's likely that we're the
324 * first to reference them, so they're being loaded now.
325 */
326 gDvm.classJavaLangThread =
327 dvmFindSystemClassNoInit("Ljava/lang/Thread;");
328 gDvm.classJavaLangVMThread =
329 dvmFindSystemClassNoInit("Ljava/lang/VMThread;");
330 gDvm.classJavaLangThreadGroup =
331 dvmFindSystemClassNoInit("Ljava/lang/ThreadGroup;");
332 if (gDvm.classJavaLangThread == NULL ||
333 gDvm.classJavaLangThreadGroup == NULL ||
334 gDvm.classJavaLangThreadGroup == NULL)
335 {
336 LOGE("Could not find one or more essential thread classes\n");
337 return false;
338 }
339
340 /*
341 * Cache field offsets. This makes things a little faster, at the
342 * expense of hard-coding non-public field names into the VM.
343 */
344 gDvm.offJavaLangThread_vmThread =
345 dvmFindFieldOffset(gDvm.classJavaLangThread,
346 "vmThread", "Ljava/lang/VMThread;");
347 gDvm.offJavaLangThread_group =
348 dvmFindFieldOffset(gDvm.classJavaLangThread,
349 "group", "Ljava/lang/ThreadGroup;");
350 gDvm.offJavaLangThread_daemon =
351 dvmFindFieldOffset(gDvm.classJavaLangThread, "daemon", "Z");
352 gDvm.offJavaLangThread_name =
353 dvmFindFieldOffset(gDvm.classJavaLangThread,
354 "name", "Ljava/lang/String;");
355 gDvm.offJavaLangThread_priority =
356 dvmFindFieldOffset(gDvm.classJavaLangThread, "priority", "I");
357
358 if (gDvm.offJavaLangThread_vmThread < 0 ||
359 gDvm.offJavaLangThread_group < 0 ||
360 gDvm.offJavaLangThread_daemon < 0 ||
361 gDvm.offJavaLangThread_name < 0 ||
362 gDvm.offJavaLangThread_priority < 0)
363 {
364 LOGE("Unable to find all fields in java.lang.Thread\n");
365 return false;
366 }
367
368 gDvm.offJavaLangVMThread_thread =
369 dvmFindFieldOffset(gDvm.classJavaLangVMThread,
370 "thread", "Ljava/lang/Thread;");
371 gDvm.offJavaLangVMThread_vmData =
372 dvmFindFieldOffset(gDvm.classJavaLangVMThread, "vmData", "I");
373 if (gDvm.offJavaLangVMThread_thread < 0 ||
374 gDvm.offJavaLangVMThread_vmData < 0)
375 {
376 LOGE("Unable to find all fields in java.lang.VMThread\n");
377 return false;
378 }
379
380 /*
381 * Cache the vtable offset for "run()".
382 *
383 * We don't want to keep the Method* because then we won't find see
384 * methods defined in subclasses.
385 */
386 Method* meth;
387 meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThread, "run", "()V");
388 if (meth == NULL) {
389 LOGE("Unable to find run() in java.lang.Thread\n");
390 return false;
391 }
392 gDvm.voffJavaLangThread_run = meth->methodIndex;
393
394 /*
395 * Cache vtable offsets for ThreadGroup methods.
396 */
397 meth = dvmFindVirtualMethodByDescriptor(gDvm.classJavaLangThreadGroup,
398 "removeThread", "(Ljava/lang/Thread;)V");
399 if (meth == NULL) {
400 LOGE("Unable to find removeThread(Thread) in java.lang.ThreadGroup\n");
401 return false;
402 }
403 gDvm.voffJavaLangThreadGroup_removeThread = meth->methodIndex;
404
405 return true;
406}
407
408/*
409 * All threads should be stopped by now. Clean up some thread globals.
410 */
411void dvmThreadShutdown(void)
412{
413 if (gDvm.threadList != NULL) {
Andy McFaddenf17638e2009-08-04 16:38:40 -0700414 /*
415 * If we walk through the thread list and try to free the
416 * lingering thread structures (which should only be for daemon
417 * threads), the daemon threads may crash if they execute before
418 * the process dies. Let them leak.
419 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800420 freeThread(gDvm.threadList);
421 gDvm.threadList = NULL;
422 }
423
424 dvmFreeBitVector(gDvm.threadIdMap);
425
426 dvmFreeMonitorList();
427
428 pthread_key_delete(gDvm.pthreadKeySelf);
429}
430
431
432/*
433 * Grab the suspend count global lock.
434 */
435static inline void lockThreadSuspendCount(void)
436{
437 /*
438 * Don't try to change to VMWAIT here. When we change back to RUNNING
439 * we have to check for a pending suspend, which results in grabbing
440 * this lock recursively. Doesn't work with "fast" pthread mutexes.
441 *
442 * This lock is always held for very brief periods, so as long as
443 * mutex ordering is respected we shouldn't stall.
444 */
445 int cc = pthread_mutex_lock(&gDvm.threadSuspendCountLock);
446 assert(cc == 0);
447}
448
449/*
450 * Release the suspend count global lock.
451 */
452static inline void unlockThreadSuspendCount(void)
453{
454 dvmUnlockMutex(&gDvm.threadSuspendCountLock);
455}
456
457/*
458 * Grab the thread list global lock.
459 *
460 * This is held while "suspend all" is trying to make everybody stop. If
461 * the shutdown is in progress, and somebody tries to grab the lock, they'll
462 * have to wait for the GC to finish. Therefore it's important that the
463 * thread not be in RUNNING mode.
464 *
465 * We don't have to check to see if we should be suspended once we have
466 * the lock. Nobody can suspend all threads without holding the thread list
467 * lock while they do it, so by definition there isn't a GC in progress.
Andy McFadden44860362009-08-06 17:56:14 -0700468 *
469 * TODO: consider checking for suspend after acquiring the lock, and
470 * backing off if set. As stated above, it can't happen during normal
471 * execution, but it *can* happen during shutdown when daemon threads
472 * are being suspended.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800473 */
474void dvmLockThreadList(Thread* self)
475{
476 ThreadStatus oldStatus;
477
478 if (self == NULL) /* try to get it from TLS */
479 self = dvmThreadSelf();
480
481 if (self != NULL) {
482 oldStatus = self->status;
483 self->status = THREAD_VMWAIT;
484 } else {
Andy McFadden44860362009-08-06 17:56:14 -0700485 /* happens during VM shutdown */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800486 //LOGW("NULL self in dvmLockThreadList\n");
487 oldStatus = -1; // shut up gcc
488 }
489
490 int cc = pthread_mutex_lock(&gDvm.threadListLock);
491 assert(cc == 0);
492
493 if (self != NULL)
494 self->status = oldStatus;
495}
496
497/*
498 * Release the thread list global lock.
499 */
500void dvmUnlockThreadList(void)
501{
502 int cc = pthread_mutex_unlock(&gDvm.threadListLock);
503 assert(cc == 0);
504}
505
The Android Open Source Project99409882009-03-18 22:20:24 -0700506/*
507 * Convert SuspendCause to a string.
508 */
509static const char* getSuspendCauseStr(SuspendCause why)
510{
511 switch (why) {
512 case SUSPEND_NOT: return "NOT?";
513 case SUSPEND_FOR_GC: return "gc";
514 case SUSPEND_FOR_DEBUG: return "debug";
515 case SUSPEND_FOR_DEBUG_EVENT: return "debug-event";
516 case SUSPEND_FOR_STACK_DUMP: return "stack-dump";
517 default: return "UNKNOWN";
518 }
519}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800520
521/*
522 * Grab the "thread suspend" lock. This is required to prevent the
523 * GC and the debugger from simultaneously suspending all threads.
524 *
525 * If we fail to get the lock, somebody else is trying to suspend all
526 * threads -- including us. If we go to sleep on the lock we'll deadlock
527 * the VM. Loop until we get it or somebody puts us to sleep.
528 */
529static void lockThreadSuspend(const char* who, SuspendCause why)
530{
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800531 const int kSpinSleepTime = 3*1000*1000; /* 3s */
532 u8 startWhen = 0; // init req'd to placate gcc
533 int sleepIter = 0;
534 int cc;
Jeff Hao97319a82009-08-12 16:57:15 -0700535
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800536 do {
537 cc = pthread_mutex_trylock(&gDvm._threadSuspendLock);
538 if (cc != 0) {
539 if (!dvmCheckSuspendPending(NULL)) {
540 /*
Andy McFadden2aa43612009-06-17 16:29:30 -0700541 * Could be that a resume-all is in progress, and something
542 * grabbed the CPU when the wakeup was broadcast. The thread
543 * performing the resume hasn't had a chance to release the
Andy McFaddene8059be2009-06-04 14:34:14 -0700544 * thread suspend lock. (We release before the broadcast,
545 * so this should be a narrow window.)
Andy McFadden2aa43612009-06-17 16:29:30 -0700546 *
547 * Could be we hit the window as a suspend was started,
548 * and the lock has been grabbed but the suspend counts
549 * haven't been incremented yet.
The Android Open Source Project99409882009-03-18 22:20:24 -0700550 *
551 * Could be an unusual JNI thread-attach thing.
552 *
553 * Could be the debugger telling us to resume at roughly
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800554 * the same time we're posting an event.
555 */
The Android Open Source Project99409882009-03-18 22:20:24 -0700556 LOGI("threadid=%d ODD: want thread-suspend lock (%s:%s),"
557 " it's held, no suspend pending\n",
558 dvmThreadSelf()->threadId, who, getSuspendCauseStr(why));
559 } else {
560 /* we suspended; reset timeout */
561 sleepIter = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800562 }
563
564 /* give the lock-holder a chance to do some work */
565 if (sleepIter == 0)
566 startWhen = dvmGetRelativeTimeUsec();
567 if (!dvmIterativeSleep(sleepIter++, kSpinSleepTime, startWhen)) {
The Android Open Source Project99409882009-03-18 22:20:24 -0700568 LOGE("threadid=%d: couldn't get thread-suspend lock (%s:%s),"
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800569 " bailing\n",
The Android Open Source Project99409882009-03-18 22:20:24 -0700570 dvmThreadSelf()->threadId, who, getSuspendCauseStr(why));
Andy McFadden2aa43612009-06-17 16:29:30 -0700571 /* threads are not suspended, thread dump could crash */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800572 dvmDumpAllThreads(false);
573 dvmAbort();
574 }
575 }
576 } while (cc != 0);
577 assert(cc == 0);
578}
579
580/*
581 * Release the "thread suspend" lock.
582 */
583static inline void unlockThreadSuspend(void)
584{
585 int cc = pthread_mutex_unlock(&gDvm._threadSuspendLock);
586 assert(cc == 0);
587}
588
589
590/*
591 * Kill any daemon threads that still exist. All of ours should be
592 * stopped, so these should be Thread objects or JNI-attached threads
593 * started by the application. Actively-running threads are likely
594 * to crash the process if they continue to execute while the VM
595 * shuts down, so we really need to kill or suspend them. (If we want
596 * the VM to restart within this process, we need to kill them, but that
597 * leaves open the possibility of orphaned resources.)
598 *
599 * Waiting for the thread to suspend may be unwise at this point, but
600 * if one of these is wedged in a critical section then we probably
601 * would've locked up on the last GC attempt.
602 *
603 * It's possible for this function to get called after a failed
604 * initialization, so be careful with assumptions about the environment.
Andy McFadden44860362009-08-06 17:56:14 -0700605 *
606 * This will be called from whatever thread calls DestroyJavaVM, usually
607 * but not necessarily the main thread. It's likely, but not guaranteed,
608 * that the current thread has already been cleaned up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800609 */
610void dvmSlayDaemons(void)
611{
Andy McFadden44860362009-08-06 17:56:14 -0700612 Thread* self = dvmThreadSelf(); // may be null
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800613 Thread* target;
Andy McFadden44860362009-08-06 17:56:14 -0700614 int threadId = 0;
615 bool doWait = false;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800616
617 //dvmEnterCritical(self);
618 dvmLockThreadList(self);
619
Andy McFadden44860362009-08-06 17:56:14 -0700620 if (self != NULL)
621 threadId = self->threadId;
622
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800623 target = gDvm.threadList;
624 while (target != NULL) {
625 if (target == self) {
626 target = target->next;
627 continue;
628 }
629
630 if (!dvmGetFieldBoolean(target->threadObj,
631 gDvm.offJavaLangThread_daemon))
632 {
Andy McFadden44860362009-08-06 17:56:14 -0700633 /* should never happen; suspend it with the rest */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800634 LOGW("threadid=%d: non-daemon id=%d still running at shutdown?!\n",
Andy McFadden44860362009-08-06 17:56:14 -0700635 threadId, target->threadId);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800636 }
637
Andy McFadden44860362009-08-06 17:56:14 -0700638 char* threadName = dvmGetThreadName(target);
639 LOGD("threadid=%d: suspending daemon id=%d name='%s'\n",
640 threadId, target->threadId, threadName);
641 free(threadName);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800642
Andy McFadden44860362009-08-06 17:56:14 -0700643 /* mark as suspended */
644 lockThreadSuspendCount();
645 dvmAddToThreadSuspendCount(&target->suspendCount, 1);
646 unlockThreadSuspendCount();
647 doWait = true;
648
649 target = target->next;
650 }
651
652 //dvmDumpAllThreads(false);
653
654 /*
655 * Unlock the thread list, relocking it later if necessary. It's
656 * possible a thread is in VMWAIT after calling dvmLockThreadList,
657 * and that function *doesn't* check for pending suspend after
658 * acquiring the lock. We want to let them finish their business
659 * and see the pending suspend before we continue here.
660 *
661 * There's no guarantee of mutex fairness, so this might not work.
662 * (The alternative is to have dvmLockThreadList check for suspend
663 * after acquiring the lock and back off, something we should consider.)
664 */
665 dvmUnlockThreadList();
666
667 if (doWait) {
668 usleep(200 * 1000);
669
670 dvmLockThreadList(self);
671
672 /*
673 * Sleep for a bit until the threads have suspended. We're trying
674 * to exit, so don't wait for too long.
675 */
676 int i;
677 for (i = 0; i < 10; i++) {
678 bool allSuspended = true;
679
680 target = gDvm.threadList;
681 while (target != NULL) {
682 if (target == self) {
683 target = target->next;
684 continue;
685 }
686
687 if (target->status == THREAD_RUNNING && !target->isSuspended) {
688 LOGD("threadid=%d not ready yet\n", target->threadId);
689 allSuspended = false;
690 break;
691 }
692
693 target = target->next;
694 }
695
696 if (allSuspended) {
697 LOGD("threadid=%d: all daemons have suspended\n", threadId);
698 break;
699 } else {
700 LOGD("threadid=%d: waiting for daemons to suspend\n", threadId);
701 }
702
703 usleep(200 * 1000);
704 }
705 dvmUnlockThreadList();
706 }
707
708#if 0 /* bad things happen if they come out of JNI or "spuriously" wake up */
709 /*
710 * Abandon the threads and recover their resources.
711 */
712 target = gDvm.threadList;
713 while (target != NULL) {
714 Thread* nextTarget = target->next;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800715 unlinkThread(target);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800716 freeThread(target);
717 target = nextTarget;
718 }
Andy McFadden44860362009-08-06 17:56:14 -0700719#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800720
Andy McFadden44860362009-08-06 17:56:14 -0700721 //dvmDumpAllThreads(true);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800722}
723
724
725/*
726 * Finish preparing the parts of the Thread struct required to support
727 * JNI registration.
728 */
729bool dvmPrepMainForJni(JNIEnv* pEnv)
730{
731 Thread* self;
732
733 /* main thread is always first in list at this point */
734 self = gDvm.threadList;
735 assert(self->threadId == kMainThreadId);
736
737 /* create a "fake" JNI frame at the top of the main thread interp stack */
738 if (!createFakeEntryFrame(self))
739 return false;
740
741 /* fill these in, since they weren't ready at dvmCreateJNIEnv time */
742 dvmSetJniEnvThreadId(pEnv, self);
743 dvmSetThreadJNIEnv(self, (JNIEnv*) pEnv);
744
745 return true;
746}
747
748
749/*
750 * Finish preparing the main thread, allocating some objects to represent
751 * it. As part of doing so, we finish initializing Thread and ThreadGroup.
Andy McFaddena1a7a342009-05-04 13:29:30 -0700752 * This will execute some interpreted code (e.g. class initializers).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800753 */
754bool dvmPrepMainThread(void)
755{
756 Thread* thread;
757 Object* groupObj;
758 Object* threadObj;
759 Object* vmThreadObj;
760 StringObject* threadNameStr;
761 Method* init;
762 JValue unused;
763
764 LOGV("+++ finishing prep on main VM thread\n");
765
766 /* main thread is always first in list at this point */
767 thread = gDvm.threadList;
768 assert(thread->threadId == kMainThreadId);
769
770 /*
771 * Make sure the classes are initialized. We have to do this before
772 * we create an instance of them.
773 */
774 if (!dvmInitClass(gDvm.classJavaLangClass)) {
775 LOGE("'Class' class failed to initialize\n");
776 return false;
777 }
778 if (!dvmInitClass(gDvm.classJavaLangThreadGroup) ||
779 !dvmInitClass(gDvm.classJavaLangThread) ||
780 !dvmInitClass(gDvm.classJavaLangVMThread))
781 {
782 LOGE("thread classes failed to initialize\n");
783 return false;
784 }
785
786 groupObj = dvmGetMainThreadGroup();
787 if (groupObj == NULL)
788 return false;
789
790 /*
791 * Allocate and construct a Thread with the internal-creation
792 * constructor.
793 */
794 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_DEFAULT);
795 if (threadObj == NULL) {
796 LOGE("unable to allocate main thread object\n");
797 return false;
798 }
799 dvmReleaseTrackedAlloc(threadObj, NULL);
800
801 threadNameStr = dvmCreateStringFromCstr("main", ALLOC_DEFAULT);
802 if (threadNameStr == NULL)
803 return false;
804 dvmReleaseTrackedAlloc((Object*)threadNameStr, NULL);
805
806 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
807 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
808 assert(init != NULL);
809 dvmCallMethod(thread, init, threadObj, &unused, groupObj, threadNameStr,
810 THREAD_NORM_PRIORITY, false);
811 if (dvmCheckException(thread)) {
812 LOGE("exception thrown while constructing main thread object\n");
813 return false;
814 }
815
816 /*
817 * Allocate and construct a VMThread.
818 */
819 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
820 if (vmThreadObj == NULL) {
821 LOGE("unable to allocate main vmthread object\n");
822 return false;
823 }
824 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
825
826 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangVMThread, "<init>",
827 "(Ljava/lang/Thread;)V");
828 dvmCallMethod(thread, init, vmThreadObj, &unused, threadObj);
829 if (dvmCheckException(thread)) {
830 LOGE("exception thrown while constructing main vmthread object\n");
831 return false;
832 }
833
834 /* set the VMThread.vmData field to our Thread struct */
835 assert(gDvm.offJavaLangVMThread_vmData != 0);
836 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)thread);
837
838 /*
839 * Stuff the VMThread back into the Thread. From this point on, other
Andy McFaddena1a7a342009-05-04 13:29:30 -0700840 * Threads will see that this Thread is running (at least, they would,
841 * if there were any).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800842 */
843 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread,
844 vmThreadObj);
845
846 thread->threadObj = threadObj;
847
848 /*
Andy McFaddena1a7a342009-05-04 13:29:30 -0700849 * Set the context class loader. This invokes a ClassLoader method,
850 * which could conceivably call Thread.currentThread(), so we want the
851 * Thread to be fully configured before we do this.
852 */
853 Object* systemLoader = dvmGetSystemClassLoader();
854 if (systemLoader == NULL) {
855 LOGW("WARNING: system class loader is NULL (setting main ctxt)\n");
856 /* keep going */
857 }
858 int ctxtClassLoaderOffset = dvmFindFieldOffset(gDvm.classJavaLangThread,
859 "contextClassLoader", "Ljava/lang/ClassLoader;");
860 if (ctxtClassLoaderOffset < 0) {
861 LOGE("Unable to find contextClassLoader field in Thread\n");
862 return false;
863 }
864 dvmSetFieldObject(threadObj, ctxtClassLoaderOffset, systemLoader);
865
866 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800867 * Finish our thread prep.
868 */
869
870 /* include self in non-daemon threads (mainly for AttachCurrentThread) */
871 gDvm.nonDaemonThreadCount++;
872
873 return true;
874}
875
876
877/*
878 * Alloc and initialize a Thread struct.
879 *
880 * "threadObj" is the java.lang.Thread object. It will be NULL for the
881 * main VM thread, but non-NULL for everything else.
882 *
883 * Does not create any objects, just stuff on the system (malloc) heap. (If
884 * this changes, we need to use ALLOC_NO_GC. And also verify that we're
885 * ready to load classes at the time this is called.)
886 */
887static Thread* allocThread(int interpStackSize)
888{
889 Thread* thread;
890 u1* stackBottom;
891
892 thread = (Thread*) calloc(1, sizeof(Thread));
893 if (thread == NULL)
894 return NULL;
895
Jeff Hao97319a82009-08-12 16:57:15 -0700896#if defined(WITH_SELF_VERIFICATION)
897 if (dvmSelfVerificationShadowSpaceAlloc(thread) == NULL)
898 return NULL;
899#endif
900
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800901 assert(interpStackSize >= kMinStackSize && interpStackSize <=kMaxStackSize);
902
903 thread->status = THREAD_INITIALIZING;
904 thread->suspendCount = 0;
905
906#ifdef WITH_ALLOC_LIMITS
907 thread->allocLimit = -1;
908#endif
909
910 /*
911 * Allocate and initialize the interpreted code stack. We essentially
912 * "lose" the alloc pointer, which points at the bottom of the stack,
913 * but we can get it back later because we know how big the stack is.
914 *
915 * The stack must be aligned on a 4-byte boundary.
916 */
917#ifdef MALLOC_INTERP_STACK
918 stackBottom = (u1*) malloc(interpStackSize);
919 if (stackBottom == NULL) {
Jeff Hao97319a82009-08-12 16:57:15 -0700920#if defined(WITH_SELF_VERIFICATION)
921 dvmSelfVerificationShadowSpaceFree(thread);
922#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800923 free(thread);
924 return NULL;
925 }
926 memset(stackBottom, 0xc5, interpStackSize); // stop valgrind complaints
927#else
928 stackBottom = mmap(NULL, interpStackSize, PROT_READ | PROT_WRITE,
929 MAP_PRIVATE | MAP_ANON, -1, 0);
930 if (stackBottom == MAP_FAILED) {
Jeff Hao97319a82009-08-12 16:57:15 -0700931#if defined(WITH_SELF_VERIFICATION)
932 dvmSelfVerificationShadowSpaceFree(thread);
933#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800934 free(thread);
935 return NULL;
936 }
937#endif
938
939 assert(((u4)stackBottom & 0x03) == 0); // looks like our malloc ensures this
940 thread->interpStackSize = interpStackSize;
941 thread->interpStackStart = stackBottom + interpStackSize;
942 thread->interpStackEnd = stackBottom + STACK_OVERFLOW_RESERVE;
943
944 /* give the thread code a chance to set things up */
945 dvmInitInterpStack(thread, interpStackSize);
946
947 return thread;
948}
949
950/*
951 * Get a meaningful thread ID. At present this only has meaning under Linux,
952 * where getpid() and gettid() sometimes agree and sometimes don't depending
953 * on your thread model (try "export LD_ASSUME_KERNEL=2.4.19").
954 */
955pid_t dvmGetSysThreadId(void)
956{
957#ifdef HAVE_GETTID
958 return gettid();
959#else
960 return getpid();
961#endif
962}
963
964/*
965 * Finish initialization of a Thread struct.
966 *
967 * This must be called while executing in the new thread, but before the
968 * thread is added to the thread list.
969 *
970 * *** NOTE: The threadListLock must be held by the caller (needed for
971 * assignThreadId()).
972 */
973static bool prepareThread(Thread* thread)
974{
975 assignThreadId(thread);
976 thread->handle = pthread_self();
977 thread->systemTid = dvmGetSysThreadId();
978
979 //LOGI("SYSTEM TID IS %d (pid is %d)\n", (int) thread->systemTid,
980 // (int) getpid());
981 setThreadSelf(thread);
982
983 LOGV("threadid=%d: interp stack at %p\n",
984 thread->threadId, thread->interpStackStart - thread->interpStackSize);
985
986 /*
987 * Initialize invokeReq.
988 */
989 pthread_mutex_init(&thread->invokeReq.lock, NULL);
990 pthread_cond_init(&thread->invokeReq.cv, NULL);
991
992 /*
993 * Initialize our reference tracking tables.
994 *
995 * The JNI local ref table *must* be fixed-size because we keep pointers
996 * into the table in our stack frames.
997 *
998 * Most threads won't use jniMonitorRefTable, so we clear out the
999 * structure but don't call the init function (which allocs storage).
1000 */
1001 if (!dvmInitReferenceTable(&thread->jniLocalRefTable,
1002 kJniLocalRefMax, kJniLocalRefMax))
1003 return false;
1004 if (!dvmInitReferenceTable(&thread->internalLocalRefTable,
1005 kInternalRefDefault, kInternalRefMax))
1006 return false;
1007
1008 memset(&thread->jniMonitorRefTable, 0, sizeof(thread->jniMonitorRefTable));
1009
1010 return true;
1011}
1012
1013/*
1014 * Remove a thread from the internal list.
1015 * Clear out the links to make it obvious that the thread is
1016 * no longer on the list. Caller must hold gDvm.threadListLock.
1017 */
1018static void unlinkThread(Thread* thread)
1019{
1020 LOG_THREAD("threadid=%d: removing from list\n", thread->threadId);
1021 if (thread == gDvm.threadList) {
1022 assert(thread->prev == NULL);
1023 gDvm.threadList = thread->next;
1024 } else {
1025 assert(thread->prev != NULL);
1026 thread->prev->next = thread->next;
1027 }
1028 if (thread->next != NULL)
1029 thread->next->prev = thread->prev;
1030 thread->prev = thread->next = NULL;
1031}
1032
1033/*
1034 * Free a Thread struct, and all the stuff allocated within.
1035 */
1036static void freeThread(Thread* thread)
1037{
1038 if (thread == NULL)
1039 return;
1040
1041 /* thread->threadId is zero at this point */
1042 LOGVV("threadid=%d: freeing\n", thread->threadId);
1043
1044 if (thread->interpStackStart != NULL) {
1045 u1* interpStackBottom;
1046
1047 interpStackBottom = thread->interpStackStart;
1048 interpStackBottom -= thread->interpStackSize;
1049#ifdef MALLOC_INTERP_STACK
1050 free(interpStackBottom);
1051#else
1052 if (munmap(interpStackBottom, thread->interpStackSize) != 0)
1053 LOGW("munmap(thread stack) failed\n");
1054#endif
1055 }
1056
1057 dvmClearReferenceTable(&thread->jniLocalRefTable);
1058 dvmClearReferenceTable(&thread->internalLocalRefTable);
1059 if (&thread->jniMonitorRefTable.table != NULL)
1060 dvmClearReferenceTable(&thread->jniMonitorRefTable);
1061
Jeff Hao97319a82009-08-12 16:57:15 -07001062#if defined(WITH_SELF_VERIFICATION)
1063 dvmSelfVerificationShadowSpaceFree(thread);
1064#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001065 free(thread);
1066}
1067
1068/*
1069 * Like pthread_self(), but on a Thread*.
1070 */
1071Thread* dvmThreadSelf(void)
1072{
1073 return (Thread*) pthread_getspecific(gDvm.pthreadKeySelf);
1074}
1075
1076/*
1077 * Explore our sense of self. Stuffs the thread pointer into TLS.
1078 */
1079static void setThreadSelf(Thread* thread)
1080{
1081 int cc;
1082
1083 cc = pthread_setspecific(gDvm.pthreadKeySelf, thread);
1084 if (cc != 0) {
1085 /*
1086 * Sometimes this fails under Bionic with EINVAL during shutdown.
1087 * This can happen if the timing is just right, e.g. a thread
1088 * fails to attach during shutdown, but the "fail" path calls
1089 * here to ensure we clean up after ourselves.
1090 */
1091 if (thread != NULL) {
1092 LOGE("pthread_setspecific(%p) failed, err=%d\n", thread, cc);
1093 dvmAbort(); /* the world is fundamentally hosed */
1094 }
1095 }
1096}
1097
1098/*
1099 * This is associated with the pthreadKeySelf key. It's called by the
1100 * pthread library when a thread is exiting and the "self" pointer in TLS
1101 * is non-NULL, meaning the VM hasn't had a chance to clean up. In normal
1102 * operation this should never be called.
1103 *
1104 * This is mainly of use to ensure that we don't leak resources if, for
1105 * example, a thread attaches itself to us with AttachCurrentThread and
1106 * then exits without notifying the VM.
Andy McFadden34e25bb2009-04-15 13:27:12 -07001107 *
1108 * We could do the detach here instead of aborting, but this will lead to
1109 * portability problems. Other implementations do not do this check and
1110 * will simply be unaware that the thread has exited, leading to resource
1111 * leaks (and, if this is a non-daemon thread, an infinite hang when the
1112 * VM tries to shut down).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001113 */
1114static void threadExitCheck(void* arg)
1115{
1116 Thread* thread = (Thread*) arg;
1117
1118 LOGI("In threadExitCheck %p\n", arg);
1119 assert(thread != NULL);
1120
1121 if (thread->status != THREAD_ZOMBIE) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001122 LOGE("Native thread exited without telling us\n");
1123 dvmAbort();
1124 }
1125}
1126
1127
1128/*
1129 * Assign the threadId. This needs to be a small integer so that our
1130 * "thin" locks fit in a small number of bits.
1131 *
1132 * We reserve zero for use as an invalid ID.
1133 *
1134 * This must be called with threadListLock held (unless we're still
1135 * initializing the system).
1136 */
1137static void assignThreadId(Thread* thread)
1138{
1139 /* Find a small unique integer. threadIdMap is a vector of
1140 * kMaxThreadId bits; dvmAllocBit() returns the index of a
1141 * bit, meaning that it will always be < kMaxThreadId.
1142 *
1143 * The thin locking magic requires that the low bit is always
1144 * set, so we do it once, here.
1145 */
1146 int num = dvmAllocBit(gDvm.threadIdMap);
1147 if (num < 0) {
1148 LOGE("Ran out of thread IDs\n");
1149 dvmAbort(); // TODO: make this a non-fatal error result
1150 }
1151
1152 thread->threadId = ((num + 1) << 1) | 1;
1153
1154 assert(thread->threadId != 0);
1155 assert(thread->threadId != DVM_LOCK_INITIAL_THIN_VALUE);
1156}
1157
1158/*
1159 * Give back the thread ID.
1160 */
1161static void releaseThreadId(Thread* thread)
1162{
1163 assert(thread->threadId > 0);
1164 dvmClearBit(gDvm.threadIdMap, (thread->threadId >> 1) - 1);
1165 thread->threadId = 0;
1166}
1167
1168
1169/*
1170 * Add a stack frame that makes it look like the native code in the main
1171 * thread was originally invoked from interpreted code. This gives us a
1172 * place to hang JNI local references. The VM spec says (v2 5.2) that the
1173 * VM begins by executing "main" in a class, so in a way this brings us
1174 * closer to the spec.
1175 */
1176static bool createFakeEntryFrame(Thread* thread)
1177{
1178 assert(thread->threadId == kMainThreadId); // main thread only
1179
1180 /* find the method on first use */
1181 if (gDvm.methFakeNativeEntry == NULL) {
1182 ClassObject* nativeStart;
1183 Method* mainMeth;
1184
1185 nativeStart = dvmFindSystemClassNoInit(
1186 "Ldalvik/system/NativeStart;");
1187 if (nativeStart == NULL) {
1188 LOGE("Unable to find dalvik.system.NativeStart class\n");
1189 return false;
1190 }
1191
1192 /*
1193 * Because we are creating a frame that represents application code, we
1194 * want to stuff the application class loader into the method's class
1195 * loader field, even though we're using the system class loader to
1196 * load it. This makes life easier over in JNI FindClass (though it
1197 * could bite us in other ways).
1198 *
1199 * Unfortunately this is occurring too early in the initialization,
1200 * of necessity coming before JNI is initialized, and we're not quite
1201 * ready to set up the application class loader.
1202 *
1203 * So we save a pointer to the method in gDvm.methFakeNativeEntry
1204 * and check it in FindClass. The method is private so nobody else
1205 * can call it.
1206 */
1207 //nativeStart->classLoader = dvmGetSystemClassLoader();
1208
1209 mainMeth = dvmFindDirectMethodByDescriptor(nativeStart,
1210 "main", "([Ljava/lang/String;)V");
1211 if (mainMeth == NULL) {
1212 LOGE("Unable to find 'main' in dalvik.system.NativeStart\n");
1213 return false;
1214 }
1215
1216 gDvm.methFakeNativeEntry = mainMeth;
1217 }
1218
1219 return dvmPushJNIFrame(thread, gDvm.methFakeNativeEntry);
1220}
1221
1222
1223/*
1224 * Add a stack frame that makes it look like the native thread has been
1225 * executing interpreted code. This gives us a place to hang JNI local
1226 * references.
1227 */
1228static bool createFakeRunFrame(Thread* thread)
1229{
1230 ClassObject* nativeStart;
1231 Method* runMeth;
1232
1233 assert(thread->threadId != 1); // not for main thread
1234
1235 nativeStart =
1236 dvmFindSystemClassNoInit("Ldalvik/system/NativeStart;");
1237 if (nativeStart == NULL) {
1238 LOGE("Unable to find dalvik.system.NativeStart class\n");
1239 return false;
1240 }
1241
1242 runMeth = dvmFindVirtualMethodByDescriptor(nativeStart, "run", "()V");
1243 if (runMeth == NULL) {
1244 LOGE("Unable to find 'run' in dalvik.system.NativeStart\n");
1245 return false;
1246 }
1247
1248 return dvmPushJNIFrame(thread, runMeth);
1249}
1250
1251/*
1252 * Helper function to set the name of the current thread
1253 */
1254static void setThreadName(const char *threadName)
1255{
1256#if defined(HAVE_PRCTL)
1257 int hasAt = 0;
1258 int hasDot = 0;
1259 const char *s = threadName;
1260 while (*s) {
1261 if (*s == '.') hasDot = 1;
1262 else if (*s == '@') hasAt = 1;
1263 s++;
1264 }
1265 int len = s - threadName;
1266 if (len < 15 || hasAt || !hasDot) {
1267 s = threadName;
1268 } else {
1269 s = threadName + len - 15;
1270 }
1271 prctl(PR_SET_NAME, (unsigned long) s, 0, 0, 0);
1272#endif
1273}
1274
1275/*
1276 * Create a thread as a result of java.lang.Thread.start().
1277 *
1278 * We do have to worry about some concurrency problems, e.g. programs
1279 * that try to call Thread.start() on the same object from multiple threads.
1280 * (This will fail for all but one, but we have to make sure that it succeeds
1281 * for exactly one.)
1282 *
1283 * Some of the complexity here arises from our desire to mimic the
1284 * Thread vs. VMThread class decomposition we inherited. We've been given
1285 * a Thread, and now we need to create a VMThread and then populate both
1286 * objects. We also need to create one of our internal Thread objects.
1287 *
1288 * Pass in a stack size of 0 to get the default.
1289 */
1290bool dvmCreateInterpThread(Object* threadObj, int reqStackSize)
1291{
1292 pthread_attr_t threadAttr;
1293 pthread_t threadHandle;
1294 Thread* self;
1295 Thread* newThread = NULL;
1296 Object* vmThreadObj = NULL;
1297 int stackSize;
1298
1299 assert(threadObj != NULL);
1300
1301 if(gDvm.zygote) {
1302 dvmThrowException("Ljava/lang/IllegalStateException;",
1303 "No new threads in -Xzygote mode");
1304
1305 goto fail;
1306 }
1307
1308 self = dvmThreadSelf();
1309 if (reqStackSize == 0)
1310 stackSize = gDvm.stackSize;
1311 else if (reqStackSize < kMinStackSize)
1312 stackSize = kMinStackSize;
1313 else if (reqStackSize > kMaxStackSize)
1314 stackSize = kMaxStackSize;
1315 else
1316 stackSize = reqStackSize;
1317
1318 pthread_attr_init(&threadAttr);
1319 pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1320
1321 /*
1322 * To minimize the time spent in the critical section, we allocate the
1323 * vmThread object here.
1324 */
1325 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_DEFAULT);
1326 if (vmThreadObj == NULL)
1327 goto fail;
1328
1329 newThread = allocThread(stackSize);
1330 if (newThread == NULL)
1331 goto fail;
1332 newThread->threadObj = threadObj;
1333
1334 assert(newThread->status == THREAD_INITIALIZING);
1335
1336 /*
1337 * We need to lock out other threads while we test and set the
1338 * "vmThread" field in java.lang.Thread, because we use that to determine
1339 * if this thread has been started before. We use the thread list lock
1340 * because it's handy and we're going to need to grab it again soon
1341 * anyway.
1342 */
1343 dvmLockThreadList(self);
1344
1345 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
1346 dvmUnlockThreadList();
1347 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
1348 "thread has already been started");
1349 goto fail;
1350 }
1351
1352 /*
1353 * There are actually three data structures: Thread (object), VMThread
1354 * (object), and Thread (C struct). All of them point to at least one
1355 * other.
1356 *
1357 * As soon as "VMThread.vmData" is assigned, other threads can start
1358 * making calls into us (e.g. setPriority).
1359 */
1360 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)newThread);
1361 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
1362
1363 /*
1364 * Thread creation might take a while, so release the lock.
1365 */
1366 dvmUnlockThreadList();
1367
Andy McFadden2aa43612009-06-17 16:29:30 -07001368 int cc, oldStatus;
1369 oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
1370 cc = pthread_create(&threadHandle, &threadAttr, interpThreadStart,
1371 newThread);
1372 oldStatus = dvmChangeStatus(self, oldStatus);
1373
1374 if (cc != 0) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001375 /*
1376 * Failure generally indicates that we have exceeded system
1377 * resource limits. VirtualMachineError is probably too severe,
1378 * so use OutOfMemoryError.
1379 */
1380 LOGE("Thread creation failed (err=%s)\n", strerror(errno));
1381
1382 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, NULL);
1383
1384 dvmThrowException("Ljava/lang/OutOfMemoryError;",
1385 "thread creation failed");
1386 goto fail;
1387 }
1388
1389 /*
1390 * We need to wait for the thread to start. Otherwise, depending on
1391 * the whims of the OS scheduler, we could return and the code in our
1392 * thread could try to do operations on the new thread before it had
1393 * finished starting.
1394 *
1395 * The new thread will lock the thread list, change its state to
1396 * THREAD_STARTING, broadcast to gDvm.threadStartCond, and then sleep
1397 * on gDvm.threadStartCond (which uses the thread list lock). This
1398 * thread (the parent) will either see that the thread is already ready
1399 * after we grab the thread list lock, or will be awakened from the
1400 * condition variable on the broadcast.
1401 *
1402 * We don't want to stall the rest of the VM while the new thread
1403 * starts, which can happen if the GC wakes up at the wrong moment.
1404 * So, we change our own status to VMWAIT, and self-suspend if
1405 * necessary after we finish adding the new thread.
1406 *
1407 *
1408 * We have to deal with an odd race with the GC/debugger suspension
1409 * mechanism when creating a new thread. The information about whether
1410 * or not a thread should be suspended is contained entirely within
1411 * the Thread struct; this is usually cleaner to deal with than having
1412 * one or more globally-visible suspension flags. The trouble is that
1413 * we could create the thread while the VM is trying to suspend all
1414 * threads. The suspend-count won't be nonzero for the new thread,
1415 * so dvmChangeStatus(THREAD_RUNNING) won't cause a suspension.
1416 *
1417 * The easiest way to deal with this is to prevent the new thread from
1418 * running until the parent says it's okay. This results in the
Andy McFadden2aa43612009-06-17 16:29:30 -07001419 * following (correct) sequence of events for a "badly timed" GC
1420 * (where '-' is us, 'o' is the child, and '+' is some other thread):
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001421 *
1422 * - call pthread_create()
1423 * - lock thread list
1424 * - put self into THREAD_VMWAIT so GC doesn't wait for us
1425 * - sleep on condition var (mutex = thread list lock) until child starts
1426 * + GC triggered by another thread
1427 * + thread list locked; suspend counts updated; thread list unlocked
1428 * + loop waiting for all runnable threads to suspend
1429 * + success, start GC
1430 * o child thread wakes, signals condition var to wake parent
1431 * o child waits for parent ack on condition variable
1432 * - we wake up, locking thread list
1433 * - add child to thread list
1434 * - unlock thread list
1435 * - change our state back to THREAD_RUNNING; GC causes us to suspend
1436 * + GC finishes; all threads in thread list are resumed
1437 * - lock thread list
1438 * - set child to THREAD_VMWAIT, and signal it to start
1439 * - unlock thread list
1440 * o child resumes
1441 * o child changes state to THREAD_RUNNING
1442 *
1443 * The above shows the GC starting up during thread creation, but if
1444 * it starts anywhere after VMThread.create() is called it will
1445 * produce the same series of events.
1446 *
1447 * Once the child is in the thread list, it will be suspended and
1448 * resumed like any other thread. In the above scenario the resume-all
1449 * code will try to resume the new thread, which was never actually
1450 * suspended, and try to decrement the child's thread suspend count to -1.
1451 * We can catch this in the resume-all code.
1452 *
1453 * Bouncing back and forth between threads like this adds a small amount
1454 * of scheduler overhead to thread startup.
1455 *
1456 * One alternative to having the child wait for the parent would be
1457 * to have the child inherit the parents' suspension count. This
1458 * would work for a GC, since we can safely assume that the parent
1459 * thread didn't cause it, but we must only do so if the parent suspension
1460 * was caused by a suspend-all. If the parent was being asked to
1461 * suspend singly by the debugger, the child should not inherit the value.
1462 *
1463 * We could also have a global "new thread suspend count" that gets
1464 * picked up by new threads before changing state to THREAD_RUNNING.
1465 * This would be protected by the thread list lock and set by a
1466 * suspend-all.
1467 */
1468 dvmLockThreadList(self);
1469 assert(self->status == THREAD_RUNNING);
1470 self->status = THREAD_VMWAIT;
1471 while (newThread->status != THREAD_STARTING)
1472 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1473
1474 LOG_THREAD("threadid=%d: adding to list\n", newThread->threadId);
1475 newThread->next = gDvm.threadList->next;
1476 if (newThread->next != NULL)
1477 newThread->next->prev = newThread;
1478 newThread->prev = gDvm.threadList;
1479 gDvm.threadList->next = newThread;
1480
1481 if (!dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon))
1482 gDvm.nonDaemonThreadCount++; // guarded by thread list lock
1483
1484 dvmUnlockThreadList();
1485
1486 /* change status back to RUNNING, self-suspending if necessary */
1487 dvmChangeStatus(self, THREAD_RUNNING);
1488
1489 /*
1490 * Tell the new thread to start.
1491 *
1492 * We must hold the thread list lock before messing with another thread.
1493 * In the general case we would also need to verify that newThread was
1494 * still in the thread list, but in our case the thread has not started
1495 * executing user code and therefore has not had a chance to exit.
1496 *
1497 * We move it to VMWAIT, and it then shifts itself to RUNNING, which
1498 * comes with a suspend-pending check.
1499 */
1500 dvmLockThreadList(self);
1501
1502 assert(newThread->status == THREAD_STARTING);
1503 newThread->status = THREAD_VMWAIT;
1504 pthread_cond_broadcast(&gDvm.threadStartCond);
1505
1506 dvmUnlockThreadList();
1507
1508 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1509 return true;
1510
1511fail:
1512 freeThread(newThread);
1513 dvmReleaseTrackedAlloc(vmThreadObj, NULL);
1514 return false;
1515}
1516
1517/*
1518 * pthread entry function for threads started from interpreted code.
1519 */
1520static void* interpThreadStart(void* arg)
1521{
1522 Thread* self = (Thread*) arg;
1523
1524 char *threadName = dvmGetThreadName(self);
1525 setThreadName(threadName);
1526 free(threadName);
1527
1528 /*
1529 * Finish initializing the Thread struct.
1530 */
1531 prepareThread(self);
1532
1533 LOG_THREAD("threadid=%d: created from interp\n", self->threadId);
1534
1535 /*
1536 * Change our status and wake our parent, who will add us to the
1537 * thread list and advance our state to VMWAIT.
1538 */
1539 dvmLockThreadList(self);
1540 self->status = THREAD_STARTING;
1541 pthread_cond_broadcast(&gDvm.threadStartCond);
1542
1543 /*
1544 * Wait until the parent says we can go. Assuming there wasn't a
1545 * suspend pending, this will happen immediately. When it completes,
1546 * we're full-fledged citizens of the VM.
1547 *
1548 * We have to use THREAD_VMWAIT here rather than THREAD_RUNNING
1549 * because the pthread_cond_wait below needs to reacquire a lock that
1550 * suspend-all is also interested in. If we get unlucky, the parent could
1551 * change us to THREAD_RUNNING, then a GC could start before we get
1552 * signaled, and suspend-all will grab the thread list lock and then
1553 * wait for us to suspend. We'll be in the tail end of pthread_cond_wait
1554 * trying to get the lock.
1555 */
1556 while (self->status != THREAD_VMWAIT)
1557 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1558
1559 dvmUnlockThreadList();
1560
1561 /*
1562 * Add a JNI context.
1563 */
1564 self->jniEnv = dvmCreateJNIEnv(self);
1565
1566 /*
1567 * Change our state so the GC will wait for us from now on. If a GC is
1568 * in progress this call will suspend us.
1569 */
1570 dvmChangeStatus(self, THREAD_RUNNING);
1571
1572 /*
1573 * Notify the debugger & DDM. The debugger notification may cause
1574 * us to suspend ourselves (and others).
1575 */
1576 if (gDvm.debuggerConnected)
1577 dvmDbgPostThreadStart(self);
1578
1579 /*
1580 * Set the system thread priority according to the Thread object's
1581 * priority level. We don't usually need to do this, because both the
1582 * Thread object and system thread priorities inherit from parents. The
1583 * tricky case is when somebody creates a Thread object, calls
1584 * setPriority(), and then starts the thread. We could manage this with
1585 * a "needs priority update" flag to avoid the redundant call.
1586 */
Andy McFadden4879df92009-08-07 14:49:40 -07001587 int priority = dvmGetFieldInt(self->threadObj,
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001588 gDvm.offJavaLangThread_priority);
1589 dvmChangeThreadPriority(self, priority);
1590
1591 /*
1592 * Execute the "run" method.
1593 *
1594 * At this point our stack is empty, so somebody who comes looking for
1595 * stack traces right now won't have much to look at. This is normal.
1596 */
1597 Method* run = self->threadObj->clazz->vtable[gDvm.voffJavaLangThread_run];
1598 JValue unused;
1599
1600 LOGV("threadid=%d: calling run()\n", self->threadId);
1601 assert(strcmp(run->name, "run") == 0);
1602 dvmCallMethod(self, run, self->threadObj, &unused);
1603 LOGV("threadid=%d: exiting\n", self->threadId);
1604
1605 /*
1606 * Remove the thread from various lists, report its death, and free
1607 * its resources.
1608 */
1609 dvmDetachCurrentThread();
1610
1611 return NULL;
1612}
1613
1614/*
1615 * The current thread is exiting with an uncaught exception. The
1616 * Java programming language allows the application to provide a
1617 * thread-exit-uncaught-exception handler for the VM, for a specific
1618 * Thread, and for all threads in a ThreadGroup.
1619 *
1620 * Version 1.5 added the per-thread handler. We need to call
1621 * "uncaughtException" in the handler object, which is either the
1622 * ThreadGroup object or the Thread-specific handler.
1623 */
1624static void threadExitUncaughtException(Thread* self, Object* group)
1625{
1626 Object* exception;
1627 Object* handlerObj;
1628 ClassObject* throwable;
1629 Method* uncaughtHandler = NULL;
1630 InstField* threadHandler;
1631
1632 LOGW("threadid=%d: thread exiting with uncaught exception (group=%p)\n",
1633 self->threadId, group);
1634 assert(group != NULL);
1635
1636 /*
1637 * Get a pointer to the exception, then clear out the one in the
1638 * thread. We don't want to have it set when executing interpreted code.
1639 */
1640 exception = dvmGetException(self);
1641 dvmAddTrackedAlloc(exception, self);
1642 dvmClearException(self);
1643
1644 /*
1645 * Get the Thread's "uncaughtHandler" object. Use it if non-NULL;
1646 * else use "group" (which is an instance of UncaughtExceptionHandler).
1647 */
1648 threadHandler = dvmFindInstanceField(gDvm.classJavaLangThread,
1649 "uncaughtHandler", "Ljava/lang/Thread$UncaughtExceptionHandler;");
1650 if (threadHandler == NULL) {
1651 LOGW("WARNING: no 'uncaughtHandler' field in java/lang/Thread\n");
1652 goto bail;
1653 }
1654 handlerObj = dvmGetFieldObject(self->threadObj, threadHandler->byteOffset);
1655 if (handlerObj == NULL)
1656 handlerObj = group;
1657
1658 /*
1659 * Find the "uncaughtHandler" field in this object.
1660 */
1661 uncaughtHandler = dvmFindVirtualMethodHierByDescriptor(handlerObj->clazz,
1662 "uncaughtException", "(Ljava/lang/Thread;Ljava/lang/Throwable;)V");
1663
1664 if (uncaughtHandler != NULL) {
1665 //LOGI("+++ calling %s.uncaughtException\n",
1666 // handlerObj->clazz->descriptor);
1667 JValue unused;
1668 dvmCallMethod(self, uncaughtHandler, handlerObj, &unused,
1669 self->threadObj, exception);
1670 } else {
1671 /* restore it and dump a stack trace */
1672 LOGW("WARNING: no 'uncaughtException' method in class %s\n",
1673 handlerObj->clazz->descriptor);
1674 dvmSetException(self, exception);
1675 dvmLogExceptionStackTrace();
1676 }
1677
1678bail:
Bill Buzbee46cd5b62009-06-05 15:36:06 -07001679#if defined(WITH_JIT)
1680 /* Remove this thread's suspendCount from global suspendCount sum */
1681 lockThreadSuspendCount();
1682 dvmAddToThreadSuspendCount(&self->suspendCount, -self->suspendCount);
1683 unlockThreadSuspendCount();
1684#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001685 dvmReleaseTrackedAlloc(exception, self);
1686}
1687
1688
1689/*
1690 * Create an internal VM thread, for things like JDWP and finalizers.
1691 *
1692 * The easiest way to do this is create a new thread and then use the
1693 * JNI AttachCurrentThread implementation.
1694 *
1695 * This does not return until after the new thread has begun executing.
1696 */
1697bool dvmCreateInternalThread(pthread_t* pHandle, const char* name,
1698 InternalThreadStart func, void* funcArg)
1699{
1700 InternalStartArgs* pArgs;
1701 Object* systemGroup;
1702 pthread_attr_t threadAttr;
1703 volatile Thread* newThread = NULL;
1704 volatile int createStatus = 0;
1705
1706 systemGroup = dvmGetSystemThreadGroup();
1707 if (systemGroup == NULL)
1708 return false;
1709
1710 pArgs = (InternalStartArgs*) malloc(sizeof(*pArgs));
1711 pArgs->func = func;
1712 pArgs->funcArg = funcArg;
1713 pArgs->name = strdup(name); // storage will be owned by new thread
1714 pArgs->group = systemGroup;
1715 pArgs->isDaemon = true;
1716 pArgs->pThread = &newThread;
1717 pArgs->pCreateStatus = &createStatus;
1718
1719 pthread_attr_init(&threadAttr);
1720 //pthread_attr_setdetachstate(&threadAttr, PTHREAD_CREATE_DETACHED);
1721
1722 if (pthread_create(pHandle, &threadAttr, internalThreadStart,
1723 pArgs) != 0)
1724 {
1725 LOGE("internal thread creation failed\n");
1726 free(pArgs->name);
1727 free(pArgs);
1728 return false;
1729 }
1730
1731 /*
1732 * Wait for the child to start. This gives us an opportunity to make
1733 * sure that the thread started correctly, and allows our caller to
1734 * assume that the thread has started running.
1735 *
1736 * Because we aren't holding a lock across the thread creation, it's
1737 * possible that the child will already have completed its
1738 * initialization. Because the child only adjusts "createStatus" while
1739 * holding the thread list lock, the initial condition on the "while"
1740 * loop will correctly avoid the wait if this occurs.
1741 *
1742 * It's also possible that we'll have to wait for the thread to finish
1743 * being created, and as part of allocating a Thread object it might
1744 * need to initiate a GC. We switch to VMWAIT while we pause.
1745 */
1746 Thread* self = dvmThreadSelf();
1747 int oldStatus = dvmChangeStatus(self, THREAD_VMWAIT);
1748 dvmLockThreadList(self);
1749 while (createStatus == 0)
1750 pthread_cond_wait(&gDvm.threadStartCond, &gDvm.threadListLock);
1751
1752 if (newThread == NULL) {
1753 LOGW("internal thread create failed (createStatus=%d)\n", createStatus);
1754 assert(createStatus < 0);
1755 /* don't free pArgs -- if pthread_create succeeded, child owns it */
1756 dvmUnlockThreadList();
1757 dvmChangeStatus(self, oldStatus);
1758 return false;
1759 }
1760
1761 /* thread could be in any state now (except early init states) */
1762 //assert(newThread->status == THREAD_RUNNING);
1763
1764 dvmUnlockThreadList();
1765 dvmChangeStatus(self, oldStatus);
1766
1767 return true;
1768}
1769
1770/*
1771 * pthread entry function for internally-created threads.
1772 *
1773 * We are expected to free "arg" and its contents. If we're a daemon
1774 * thread, and we get cancelled abruptly when the VM shuts down, the
1775 * storage won't be freed. If this becomes a concern we can make a copy
1776 * on the stack.
1777 */
1778static void* internalThreadStart(void* arg)
1779{
1780 InternalStartArgs* pArgs = (InternalStartArgs*) arg;
1781 JavaVMAttachArgs jniArgs;
1782
1783 jniArgs.version = JNI_VERSION_1_2;
1784 jniArgs.name = pArgs->name;
1785 jniArgs.group = pArgs->group;
1786
1787 setThreadName(pArgs->name);
1788
1789 /* use local jniArgs as stack top */
1790 if (dvmAttachCurrentThread(&jniArgs, pArgs->isDaemon)) {
1791 /*
1792 * Tell the parent of our success.
1793 *
1794 * threadListLock is the mutex for threadStartCond.
1795 */
1796 dvmLockThreadList(dvmThreadSelf());
1797 *pArgs->pCreateStatus = 1;
1798 *pArgs->pThread = dvmThreadSelf();
1799 pthread_cond_broadcast(&gDvm.threadStartCond);
1800 dvmUnlockThreadList();
1801
1802 LOG_THREAD("threadid=%d: internal '%s'\n",
1803 dvmThreadSelf()->threadId, pArgs->name);
1804
1805 /* execute */
1806 (*pArgs->func)(pArgs->funcArg);
1807
1808 /* detach ourselves */
1809 dvmDetachCurrentThread();
1810 } else {
1811 /*
1812 * Tell the parent of our failure. We don't have a Thread struct,
1813 * so we can't be suspended, so we don't need to enter a critical
1814 * section.
1815 */
1816 dvmLockThreadList(dvmThreadSelf());
1817 *pArgs->pCreateStatus = -1;
1818 assert(*pArgs->pThread == NULL);
1819 pthread_cond_broadcast(&gDvm.threadStartCond);
1820 dvmUnlockThreadList();
1821
1822 assert(*pArgs->pThread == NULL);
1823 }
1824
1825 free(pArgs->name);
1826 free(pArgs);
1827 return NULL;
1828}
1829
1830/*
1831 * Attach the current thread to the VM.
1832 *
1833 * Used for internally-created threads and JNI's AttachCurrentThread.
1834 */
1835bool dvmAttachCurrentThread(const JavaVMAttachArgs* pArgs, bool isDaemon)
1836{
1837 Thread* self = NULL;
1838 Object* threadObj = NULL;
1839 Object* vmThreadObj = NULL;
1840 StringObject* threadNameStr = NULL;
1841 Method* init;
1842 bool ok, ret;
1843
1844 /* establish a basic sense of self */
1845 self = allocThread(gDvm.stackSize);
1846 if (self == NULL)
1847 goto fail;
1848 setThreadSelf(self);
1849
1850 /*
1851 * Create Thread and VMThread objects. We have to use ALLOC_NO_GC
1852 * because this thread is not yet visible to the VM. We could also
1853 * just grab the GC lock earlier, but that leaves us executing
1854 * interpreted code with the lock held, which is not prudent.
1855 *
1856 * The alloc calls will block if a GC is in progress, so we don't need
1857 * to check for global suspension here.
1858 *
1859 * It's also possible for the allocation calls to *cause* a GC.
1860 */
1861 //BUG: deadlock if a GC happens here during HeapWorker creation
1862 threadObj = dvmAllocObject(gDvm.classJavaLangThread, ALLOC_NO_GC);
1863 if (threadObj == NULL)
1864 goto fail;
1865 vmThreadObj = dvmAllocObject(gDvm.classJavaLangVMThread, ALLOC_NO_GC);
1866 if (vmThreadObj == NULL)
1867 goto fail;
1868
1869 self->threadObj = threadObj;
1870 dvmSetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData, (u4)self);
1871
1872 /*
1873 * Do some java.lang.Thread constructor prep before we lock stuff down.
1874 */
1875 if (pArgs->name != NULL) {
1876 threadNameStr = dvmCreateStringFromCstr(pArgs->name, ALLOC_NO_GC);
1877 if (threadNameStr == NULL) {
1878 assert(dvmCheckException(dvmThreadSelf()));
1879 goto fail;
1880 }
1881 }
1882
1883 init = dvmFindDirectMethodByDescriptor(gDvm.classJavaLangThread, "<init>",
1884 "(Ljava/lang/ThreadGroup;Ljava/lang/String;IZ)V");
1885 if (init == NULL) {
1886 assert(dvmCheckException(dvmThreadSelf()));
1887 goto fail;
1888 }
1889
1890 /*
1891 * Finish our thread prep. We need to do this before invoking any
1892 * interpreted code. prepareThread() requires that we hold the thread
1893 * list lock.
1894 */
1895 dvmLockThreadList(self);
1896 ok = prepareThread(self);
1897 dvmUnlockThreadList();
1898 if (!ok)
1899 goto fail;
1900
1901 self->jniEnv = dvmCreateJNIEnv(self);
1902 if (self->jniEnv == NULL)
1903 goto fail;
1904
1905 /*
1906 * Create a "fake" JNI frame at the top of the main thread interp stack.
1907 * It isn't really necessary for the internal threads, but it gives
1908 * the debugger something to show. It is essential for the JNI-attached
1909 * threads.
1910 */
1911 if (!createFakeRunFrame(self))
1912 goto fail;
1913
1914 /*
1915 * The native side of the thread is ready; add it to the list.
1916 */
1917 LOG_THREAD("threadid=%d: adding to list (attached)\n", self->threadId);
1918
1919 /* Start off in VMWAIT, because we may be about to block
1920 * on the heap lock, and we don't want any suspensions
1921 * to wait for us.
1922 */
1923 self->status = THREAD_VMWAIT;
1924
1925 /*
1926 * Add ourselves to the thread list. Once we finish here we are
1927 * visible to the debugger and the GC.
1928 */
1929 dvmLockThreadList(self);
1930
1931 self->next = gDvm.threadList->next;
1932 if (self->next != NULL)
1933 self->next->prev = self;
1934 self->prev = gDvm.threadList;
1935 gDvm.threadList->next = self;
1936 if (!isDaemon)
1937 gDvm.nonDaemonThreadCount++;
1938
1939 dvmUnlockThreadList();
1940
1941 /*
1942 * It's possible that a GC is currently running. Our thread
1943 * wasn't in the list when the GC started, so it's not properly
1944 * suspended in that case. Synchronize on the heap lock (held
1945 * when a GC is happening) to guarantee that any GCs from here
1946 * on will see this thread in the list.
1947 */
1948 dvmLockMutex(&gDvm.gcHeapLock);
1949 dvmUnlockMutex(&gDvm.gcHeapLock);
1950
1951 /*
1952 * Switch to the running state now that we're ready for
1953 * suspensions. This call may suspend.
1954 */
1955 dvmChangeStatus(self, THREAD_RUNNING);
1956
1957 /*
1958 * Now we're ready to run some interpreted code.
1959 *
1960 * We need to construct the Thread object and set the VMThread field.
1961 * Setting VMThread tells interpreted code that we're alive.
1962 *
1963 * Call the (group, name, priority, daemon) constructor on the Thread.
1964 * This sets the thread's name and adds it to the specified group, and
1965 * provides values for priority and daemon (which are normally inherited
1966 * from the current thread).
1967 */
1968 JValue unused;
1969 dvmCallMethod(self, init, threadObj, &unused, (Object*)pArgs->group,
1970 threadNameStr, getThreadPriorityFromSystem(), isDaemon);
1971 if (dvmCheckException(self)) {
1972 LOGE("exception thrown while constructing attached thread object\n");
1973 goto fail_unlink;
1974 }
1975 //if (isDaemon)
1976 // dvmSetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon, true);
1977
1978 /*
1979 * Set the VMThread field, which tells interpreted code that we're alive.
1980 *
1981 * The risk of a thread start collision here is very low; somebody
1982 * would have to be deliberately polling the ThreadGroup list and
1983 * trying to start threads against anything it sees, which would
1984 * generally cause problems for all thread creation. However, for
1985 * correctness we test "vmThread" before setting it.
1986 */
1987 if (dvmGetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread) != NULL) {
1988 dvmThrowException("Ljava/lang/IllegalThreadStateException;",
1989 "thread has already been started");
1990 /* We don't want to free anything associated with the thread
1991 * because someone is obviously interested in it. Just let
1992 * it go and hope it will clean itself up when its finished.
1993 * This case should never happen anyway.
1994 *
1995 * Since we're letting it live, we need to finish setting it up.
1996 * We just have to let the caller know that the intended operation
1997 * has failed.
1998 *
1999 * [ This seems strange -- stepping on the vmThread object that's
2000 * already present seems like a bad idea. TODO: figure this out. ]
2001 */
2002 ret = false;
2003 } else
2004 ret = true;
2005 dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, vmThreadObj);
2006
2007 /* These are now reachable from the thread groups. */
2008 dvmClearAllocFlags(threadObj, ALLOC_NO_GC);
2009 dvmClearAllocFlags(vmThreadObj, ALLOC_NO_GC);
2010
2011 /*
2012 * The thread is ready to go; let the debugger see it.
2013 */
2014 self->threadObj = threadObj;
2015
2016 LOG_THREAD("threadid=%d: attached from native, name=%s\n",
2017 self->threadId, pArgs->name);
2018
2019 /* tell the debugger & DDM */
2020 if (gDvm.debuggerConnected)
2021 dvmDbgPostThreadStart(self);
2022
2023 return ret;
2024
2025fail_unlink:
2026 dvmLockThreadList(self);
2027 unlinkThread(self);
2028 if (!isDaemon)
2029 gDvm.nonDaemonThreadCount--;
2030 dvmUnlockThreadList();
2031 /* fall through to "fail" */
2032fail:
2033 dvmClearAllocFlags(threadObj, ALLOC_NO_GC);
2034 dvmClearAllocFlags(vmThreadObj, ALLOC_NO_GC);
2035 if (self != NULL) {
2036 if (self->jniEnv != NULL) {
2037 dvmDestroyJNIEnv(self->jniEnv);
2038 self->jniEnv = NULL;
2039 }
2040 freeThread(self);
2041 }
2042 setThreadSelf(NULL);
2043 return false;
2044}
2045
2046/*
2047 * Detach the thread from the various data structures, notify other threads
2048 * that are waiting to "join" it, and free up all heap-allocated storage.
2049 *
2050 * Used for all threads.
2051 *
2052 * When we get here the interpreted stack should be empty. The JNI 1.6 spec
2053 * requires us to enforce this for the DetachCurrentThread call, probably
2054 * because it also says that DetachCurrentThread causes all monitors
2055 * associated with the thread to be released. (Because the stack is empty,
2056 * we only have to worry about explicit JNI calls to MonitorEnter.)
2057 *
2058 * THOUGHT:
2059 * We might want to avoid freeing our internal Thread structure until the
2060 * associated Thread/VMThread objects get GCed. Our Thread is impossible to
2061 * get to once the thread shuts down, but there is a small possibility of
2062 * an operation starting in another thread before this thread halts, and
2063 * finishing much later (perhaps the thread got stalled by a weird OS bug).
2064 * We don't want something like Thread.isInterrupted() crawling through
2065 * freed storage. Can do with a Thread finalizer, or by creating a
2066 * dedicated ThreadObject class for java/lang/Thread and moving all of our
2067 * state into that.
2068 */
2069void dvmDetachCurrentThread(void)
2070{
2071 Thread* self = dvmThreadSelf();
2072 Object* vmThread;
2073 Object* group;
2074
2075 /*
2076 * Make sure we're not detaching a thread that's still running. (This
2077 * could happen with an explicit JNI detach call.)
2078 *
2079 * A thread created by interpreted code will finish with a depth of
2080 * zero, while a JNI-attached thread will have the synthetic "stack
2081 * starter" native method at the top.
2082 */
2083 int curDepth = dvmComputeExactFrameDepth(self->curFrame);
2084 if (curDepth != 0) {
2085 bool topIsNative = false;
2086
2087 if (curDepth == 1) {
2088 /* not expecting a lingering break frame; just look at curFrame */
2089 assert(!dvmIsBreakFrame(self->curFrame));
2090 StackSaveArea* ssa = SAVEAREA_FROM_FP(self->curFrame);
2091 if (dvmIsNativeMethod(ssa->method))
2092 topIsNative = true;
2093 }
2094
2095 if (!topIsNative) {
2096 LOGE("ERROR: detaching thread with interp frames (count=%d)\n",
2097 curDepth);
2098 dvmDumpThread(self, false);
2099 dvmAbort();
2100 }
2101 }
2102
2103 group = dvmGetFieldObject(self->threadObj, gDvm.offJavaLangThread_group);
2104 LOG_THREAD("threadid=%d: detach (group=%p)\n", self->threadId, group);
2105
2106 /*
2107 * Release any held monitors. Since there are no interpreted stack
2108 * frames, the only thing left are the monitors held by JNI MonitorEnter
2109 * calls.
2110 */
2111 dvmReleaseJniMonitors(self);
2112
2113 /*
2114 * Do some thread-exit uncaught exception processing if necessary.
2115 */
2116 if (dvmCheckException(self))
2117 threadExitUncaughtException(self, group);
2118
2119 /*
2120 * Remove the thread from the thread group.
2121 */
2122 if (group != NULL) {
2123 Method* removeThread =
2124 group->clazz->vtable[gDvm.voffJavaLangThreadGroup_removeThread];
2125 JValue unused;
2126 dvmCallMethod(self, removeThread, group, &unused, self->threadObj);
2127 }
2128
2129 /*
2130 * Clear the vmThread reference in the Thread object. Interpreted code
2131 * will now see that this Thread is not running. As this may be the
2132 * only reference to the VMThread object that the VM knows about, we
2133 * have to create an internal reference to it first.
2134 */
2135 vmThread = dvmGetFieldObject(self->threadObj,
2136 gDvm.offJavaLangThread_vmThread);
2137 dvmAddTrackedAlloc(vmThread, self);
2138 dvmSetFieldObject(self->threadObj, gDvm.offJavaLangThread_vmThread, NULL);
2139
2140 /* clear out our struct Thread pointer, since it's going away */
2141 dvmSetFieldObject(vmThread, gDvm.offJavaLangVMThread_vmData, NULL);
2142
2143 /*
2144 * Tell the debugger & DDM. This may cause the current thread or all
2145 * threads to suspend.
2146 *
2147 * The JDWP spec is somewhat vague about when this happens, other than
2148 * that it's issued by the dying thread, which may still appear in
2149 * an "all threads" listing.
2150 */
2151 if (gDvm.debuggerConnected)
2152 dvmDbgPostThreadDeath(self);
2153
2154 /*
2155 * Thread.join() is implemented as an Object.wait() on the VMThread
2156 * object. Signal anyone who is waiting.
2157 */
2158 dvmLockObject(self, vmThread);
2159 dvmObjectNotifyAll(self, vmThread);
2160 dvmUnlockObject(self, vmThread);
2161
2162 dvmReleaseTrackedAlloc(vmThread, self);
2163 vmThread = NULL;
2164
2165 /*
2166 * We're done manipulating objects, so it's okay if the GC runs in
2167 * parallel with us from here out. It's important to do this if
2168 * profiling is enabled, since we can wait indefinitely.
2169 */
2170 self->status = THREAD_VMWAIT;
2171
2172#ifdef WITH_PROFILER
2173 /*
2174 * If we're doing method trace profiling, we don't want threads to exit,
2175 * because if they do we'll end up reusing thread IDs. This complicates
2176 * analysis and makes it impossible to have reasonable output in the
2177 * "threads" section of the "key" file.
2178 *
2179 * We need to do this after Thread.join() completes, or other threads
2180 * could get wedged. Since self->threadObj is still valid, the Thread
2181 * object will not get GCed even though we're no longer in the ThreadGroup
2182 * list (which is important since the profiling thread needs to get
2183 * the thread's name).
2184 */
2185 MethodTraceState* traceState = &gDvm.methodTrace;
2186
2187 dvmLockMutex(&traceState->startStopLock);
2188 if (traceState->traceEnabled) {
2189 LOGI("threadid=%d: waiting for method trace to finish\n",
2190 self->threadId);
2191 while (traceState->traceEnabled) {
2192 int cc;
2193 cc = pthread_cond_wait(&traceState->threadExitCond,
2194 &traceState->startStopLock);
2195 assert(cc == 0);
2196 }
2197 }
2198 dvmUnlockMutex(&traceState->startStopLock);
2199#endif
2200
2201 dvmLockThreadList(self);
2202
2203 /*
2204 * Lose the JNI context.
2205 */
2206 dvmDestroyJNIEnv(self->jniEnv);
2207 self->jniEnv = NULL;
2208
2209 self->status = THREAD_ZOMBIE;
2210
2211 /*
2212 * Remove ourselves from the internal thread list.
2213 */
2214 unlinkThread(self);
2215
2216 /*
2217 * If we're the last one standing, signal anybody waiting in
2218 * DestroyJavaVM that it's okay to exit.
2219 */
2220 if (!dvmGetFieldBoolean(self->threadObj, gDvm.offJavaLangThread_daemon)) {
2221 gDvm.nonDaemonThreadCount--; // guarded by thread list lock
2222
2223 if (gDvm.nonDaemonThreadCount == 0) {
2224 int cc;
2225
2226 LOGV("threadid=%d: last non-daemon thread\n", self->threadId);
2227 //dvmDumpAllThreads(false);
2228 // cond var guarded by threadListLock, which we already hold
2229 cc = pthread_cond_signal(&gDvm.vmExitCond);
2230 assert(cc == 0);
2231 }
2232 }
2233
2234 LOGV("threadid=%d: bye!\n", self->threadId);
2235 releaseThreadId(self);
2236 dvmUnlockThreadList();
2237
2238 setThreadSelf(NULL);
2239 freeThread(self);
2240}
2241
2242
2243/*
2244 * Suspend a single thread. Do not use to suspend yourself.
2245 *
2246 * This is used primarily for debugger/DDMS activity. Does not return
2247 * until the thread has suspended or is in a "safe" state (e.g. executing
2248 * native code outside the VM).
2249 *
2250 * The thread list lock should be held before calling here -- it's not
2251 * entirely safe to hang on to a Thread* from another thread otherwise.
2252 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2253 */
2254void dvmSuspendThread(Thread* thread)
2255{
2256 assert(thread != NULL);
2257 assert(thread != dvmThreadSelf());
2258 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2259
2260 lockThreadSuspendCount();
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002261 dvmAddToThreadSuspendCount(&thread->suspendCount, 1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002262 thread->dbgSuspendCount++;
2263
2264 LOG_THREAD("threadid=%d: suspend++, now=%d\n",
2265 thread->threadId, thread->suspendCount);
2266 unlockThreadSuspendCount();
2267
2268 waitForThreadSuspend(dvmThreadSelf(), thread);
2269}
2270
2271/*
2272 * Reduce the suspend count of a thread. If it hits zero, tell it to
2273 * resume.
2274 *
2275 * Used primarily for debugger/DDMS activity. The thread in question
2276 * might have been suspended singly or as part of a suspend-all operation.
2277 *
2278 * The thread list lock should be held before calling here -- it's not
2279 * entirely safe to hang on to a Thread* from another thread otherwise.
2280 * (We'd need to grab it here anyway to avoid clashing with a suspend-all.)
2281 */
2282void dvmResumeThread(Thread* thread)
2283{
2284 assert(thread != NULL);
2285 assert(thread != dvmThreadSelf());
2286 //assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2287
2288 lockThreadSuspendCount();
2289 if (thread->suspendCount > 0) {
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002290 dvmAddToThreadSuspendCount(&thread->suspendCount, -1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002291 thread->dbgSuspendCount--;
2292 } else {
2293 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2294 thread->threadId);
2295 }
2296
2297 LOG_THREAD("threadid=%d: suspend--, now=%d\n",
2298 thread->threadId, thread->suspendCount);
2299
2300 if (thread->suspendCount == 0) {
2301 int cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2302 assert(cc == 0);
2303 }
2304
2305 unlockThreadSuspendCount();
2306}
2307
2308/*
2309 * Suspend yourself, as a result of debugger activity.
2310 */
2311void dvmSuspendSelf(bool jdwpActivity)
2312{
2313 Thread* self = dvmThreadSelf();
2314
2315 /* debugger thread may not suspend itself due to debugger activity! */
2316 assert(gDvm.jdwpState != NULL);
2317 if (self->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2318 assert(false);
2319 return;
2320 }
2321
2322 /*
2323 * Collisions with other suspends aren't really interesting. We want
2324 * to ensure that we're the only one fiddling with the suspend count
2325 * though.
2326 */
2327 lockThreadSuspendCount();
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002328 dvmAddToThreadSuspendCount(&self->suspendCount, 1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002329 self->dbgSuspendCount++;
2330
2331 /*
2332 * Suspend ourselves.
2333 */
2334 assert(self->suspendCount > 0);
2335 self->isSuspended = true;
2336 LOG_THREAD("threadid=%d: self-suspending (dbg)\n", self->threadId);
2337
2338 /*
2339 * Tell JDWP that we've completed suspension. The JDWP thread can't
2340 * tell us to resume before we're fully asleep because we hold the
2341 * suspend count lock.
2342 *
2343 * If we got here via waitForDebugger(), don't do this part.
2344 */
2345 if (jdwpActivity) {
2346 //LOGI("threadid=%d: clearing wait-for-event (my handle=%08x)\n",
2347 // self->threadId, (int) self->handle);
2348 dvmJdwpClearWaitForEventThread(gDvm.jdwpState);
2349 }
2350
2351 while (self->suspendCount != 0) {
2352 int cc;
2353 cc = pthread_cond_wait(&gDvm.threadSuspendCountCond,
2354 &gDvm.threadSuspendCountLock);
2355 assert(cc == 0);
2356 if (self->suspendCount != 0) {
The Android Open Source Project99409882009-03-18 22:20:24 -07002357 /*
2358 * The condition was signaled but we're still suspended. This
2359 * can happen if the debugger lets go while a SIGQUIT thread
2360 * dump event is pending (assuming SignalCatcher was resumed for
2361 * just long enough to try to grab the thread-suspend lock).
2362 */
2363 LOGD("threadid=%d: still suspended after undo (sc=%d dc=%d s=%c)\n",
2364 self->threadId, self->suspendCount, self->dbgSuspendCount,
2365 self->isSuspended ? 'Y' : 'N');
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002366 }
2367 }
2368 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
2369 self->isSuspended = false;
2370 LOG_THREAD("threadid=%d: self-reviving (dbg), status=%d\n",
2371 self->threadId, self->status);
2372
2373 unlockThreadSuspendCount();
2374}
2375
2376
2377#ifdef HAVE_GLIBC
2378# define NUM_FRAMES 20
2379# include <execinfo.h>
2380/*
2381 * glibc-only stack dump function. Requires link with "--export-dynamic".
2382 *
2383 * TODO: move this into libs/cutils and make it work for all platforms.
2384 */
2385static void printBackTrace(void)
2386{
2387 void* array[NUM_FRAMES];
2388 size_t size;
2389 char** strings;
2390 size_t i;
2391
2392 size = backtrace(array, NUM_FRAMES);
2393 strings = backtrace_symbols(array, size);
2394
2395 LOGW("Obtained %zd stack frames.\n", size);
2396
2397 for (i = 0; i < size; i++)
2398 LOGW("%s\n", strings[i]);
2399
2400 free(strings);
2401}
2402#else
2403static void printBackTrace(void) {}
2404#endif
2405
2406/*
2407 * Dump the state of the current thread and that of another thread that
2408 * we think is wedged.
2409 */
2410static void dumpWedgedThread(Thread* thread)
2411{
2412 char exePath[1024];
2413
2414 /*
2415 * The "executablepath" function in libutils is host-side only.
2416 */
2417 strcpy(exePath, "-");
2418#ifdef HAVE_GLIBC
2419 {
2420 char proc[100];
2421 sprintf(proc, "/proc/%d/exe", getpid());
2422 int len;
Jeff Hao97319a82009-08-12 16:57:15 -07002423
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002424 len = readlink(proc, exePath, sizeof(exePath)-1);
2425 exePath[len] = '\0';
2426 }
2427#endif
2428
2429 LOGW("dumping state: process %s %d\n", exePath, getpid());
2430 dvmDumpThread(dvmThreadSelf(), false);
2431 printBackTrace();
2432
2433 // dumping a running thread is risky, but could be useful
2434 dvmDumpThread(thread, true);
2435
2436
2437 // stop now and get a core dump
2438 //abort();
2439}
2440
2441
2442/*
2443 * Wait for another thread to see the pending suspension and stop running.
2444 * It can either suspend itself or go into a non-running state such as
2445 * VMWAIT or NATIVE in which it cannot interact with the GC.
2446 *
2447 * If we're running at a higher priority, sched_yield() may not do anything,
2448 * so we need to sleep for "long enough" to guarantee that the other
2449 * thread has a chance to finish what it's doing. Sleeping for too short
2450 * a period (e.g. less than the resolution of the sleep clock) might cause
2451 * the scheduler to return immediately, so we want to start with a
2452 * "reasonable" value and expand.
2453 *
2454 * This does not return until the other thread has stopped running.
2455 * Eventually we time out and the VM aborts.
2456 *
2457 * This does not try to detect the situation where two threads are
2458 * waiting for each other to suspend. In normal use this is part of a
2459 * suspend-all, which implies that the suspend-all lock is held, or as
2460 * part of a debugger action in which the JDWP thread is always the one
2461 * doing the suspending. (We may need to re-evaluate this now that
2462 * getThreadStackTrace is implemented as suspend-snapshot-resume.)
2463 *
2464 * TODO: track basic stats about time required to suspend VM.
2465 */
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002466#define FIRST_SLEEP (250*1000) /* 0.25s */
2467#define MORE_SLEEP (750*1000) /* 0.75s */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002468static void waitForThreadSuspend(Thread* self, Thread* thread)
2469{
2470 const int kMaxRetries = 10;
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002471 int spinSleepTime = FIRST_SLEEP;
Andy McFadden2aa43612009-06-17 16:29:30 -07002472 bool complained = false;
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002473 bool needPriorityReset = false;
2474 int savedThreadPrio = -500;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002475
2476 int sleepIter = 0;
2477 int retryCount = 0;
2478 u8 startWhen = 0; // init req'd to placate gcc
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002479 u8 firstStartWhen = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002480
2481 while (thread->status == THREAD_RUNNING && !thread->isSuspended) {
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002482 if (sleepIter == 0) { // get current time on first iteration
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002483 startWhen = dvmGetRelativeTimeUsec();
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002484 if (firstStartWhen == 0) // first iteration of first attempt
2485 firstStartWhen = startWhen;
2486
2487 /*
2488 * After waiting for a bit, check to see if the target thread is
2489 * running at a reduced priority. If so, bump it up temporarily
2490 * to give it more CPU time.
2491 *
2492 * getpriority() returns the "nice" value, so larger numbers
2493 * indicate lower priority.
2494 *
2495 * (Not currently changing the cgroup. Wasn't necessary in some
2496 * simple experiments.)
2497 */
2498 if (retryCount == 2) {
2499 assert(thread->systemTid != 0);
2500 errno = 0;
2501 int threadPrio = getpriority(PRIO_PROCESS, thread->systemTid);
2502 if (errno == 0 && threadPrio > 0) {
2503 const int kHigher = 0;
2504 if (setpriority(PRIO_PROCESS, thread->systemTid, kHigher) < 0)
2505 {
2506 LOGW("Couldn't raise priority on tid %d to %d\n",
2507 thread->systemTid, kHigher);
2508 } else {
2509 savedThreadPrio = threadPrio;
2510 needPriorityReset = true;
2511 LOGD("Temporarily raising priority on tid %d (%d -> %d)\n",
2512 thread->systemTid, threadPrio, kHigher);
2513 }
2514 }
2515 }
2516 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002517
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002518#if defined (WITH_JIT)
2519 /*
2520 * If we're still waiting after the first timeout,
2521 * unchain all translations.
2522 */
2523 if (gDvmJit.pJitEntryTable && retryCount > 0) {
2524 LOGD("JIT unchain all attempt #%d",retryCount);
2525 dvmJitUnchainAll();
2526 }
2527#endif
2528
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002529 /*
2530 * Sleep briefly. This returns false if we've exceeded the total
2531 * time limit for this round of sleeping.
2532 */
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002533 if (!dvmIterativeSleep(sleepIter++, spinSleepTime, startWhen)) {
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002534 LOGW("threadid=%d: spin on suspend #%d threadid=%d (h=%d)\n",
2535 self->threadId, retryCount,
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002536 thread->threadId, (int)thread->handle);
2537 dumpWedgedThread(thread);
Andy McFadden2aa43612009-06-17 16:29:30 -07002538 complained = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002539
2540 // keep going; could be slow due to valgrind
2541 sleepIter = 0;
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002542 spinSleepTime = MORE_SLEEP;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002543
2544 if (retryCount++ == kMaxRetries) {
2545 LOGE("threadid=%d: stuck on threadid=%d, giving up\n",
2546 self->threadId, thread->threadId);
2547 dvmDumpAllThreads(false);
2548 dvmAbort();
2549 }
2550 }
2551 }
Andy McFadden2aa43612009-06-17 16:29:30 -07002552
2553 if (complained) {
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002554 LOGW("threadid=%d: spin on suspend resolved in %lld msec\n",
2555 self->threadId,
2556 (dvmGetRelativeTimeUsec() - firstStartWhen) / 1000);
Andy McFadden2aa43612009-06-17 16:29:30 -07002557 //dvmDumpThread(thread, false); /* suspended, so dump is safe */
2558 }
Andy McFadden7ce9bd72009-08-07 11:41:35 -07002559 if (needPriorityReset) {
2560 if (setpriority(PRIO_PROCESS, thread->systemTid, savedThreadPrio) < 0) {
2561 LOGW("NOTE: couldn't reset priority on thread %d to %d\n",
2562 thread->systemTid, savedThreadPrio);
2563 } else {
2564 LOGV("Restored priority on %d to %d\n",
2565 thread->systemTid, savedThreadPrio);
2566 }
2567 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002568}
2569
2570/*
2571 * Suspend all threads except the current one. This is used by the GC,
2572 * the debugger, and by any thread that hits a "suspend all threads"
2573 * debugger event (e.g. breakpoint or exception).
2574 *
2575 * If thread N hits a "suspend all threads" breakpoint, we don't want it
2576 * to suspend the JDWP thread. For the GC, we do, because the debugger can
2577 * create objects and even execute arbitrary code. The "why" argument
2578 * allows the caller to say why the suspension is taking place.
2579 *
2580 * This can be called when a global suspend has already happened, due to
2581 * various debugger gymnastics, so keeping an "everybody is suspended" flag
2582 * doesn't work.
2583 *
2584 * DO NOT grab any locks before calling here. We grab & release the thread
2585 * lock and suspend lock here (and we're not using recursive threads), and
2586 * we might have to self-suspend if somebody else beats us here.
2587 *
2588 * The current thread may not be attached to the VM. This can happen if
2589 * we happen to GC as the result of an allocation of a Thread object.
2590 */
2591void dvmSuspendAllThreads(SuspendCause why)
2592{
2593 Thread* self = dvmThreadSelf();
2594 Thread* thread;
2595
2596 assert(why != 0);
2597
2598 /*
2599 * Start by grabbing the thread suspend lock. If we can't get it, most
2600 * likely somebody else is in the process of performing a suspend or
2601 * resume, so lockThreadSuspend() will cause us to self-suspend.
2602 *
2603 * We keep the lock until all other threads are suspended.
2604 */
2605 lockThreadSuspend("susp-all", why);
2606
2607 LOG_THREAD("threadid=%d: SuspendAll starting\n", self->threadId);
2608
2609 /*
2610 * This is possible if the current thread was in VMWAIT mode when a
2611 * suspend-all happened, and then decided to do its own suspend-all.
2612 * This can happen when a couple of threads have simultaneous events
2613 * of interest to the debugger.
2614 */
2615 //assert(self->suspendCount == 0);
2616
2617 /*
2618 * Increment everybody's suspend count (except our own).
2619 */
2620 dvmLockThreadList(self);
2621
2622 lockThreadSuspendCount();
2623 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2624 if (thread == self)
2625 continue;
2626
2627 /* debugger events don't suspend JDWP thread */
2628 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2629 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2630 continue;
2631
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002632 dvmAddToThreadSuspendCount(&thread->suspendCount, 1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002633 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2634 thread->dbgSuspendCount++;
2635 }
2636 unlockThreadSuspendCount();
2637
2638 /*
2639 * Wait for everybody in THREAD_RUNNING state to stop. Other states
2640 * indicate the code is either running natively or sleeping quietly.
2641 * Any attempt to transition back to THREAD_RUNNING will cause a check
2642 * for suspension, so it should be impossible for anything to execute
2643 * interpreted code or modify objects (assuming native code plays nicely).
2644 *
2645 * It's also okay if the thread transitions to a non-RUNNING state.
2646 *
2647 * Note we released the threadSuspendCountLock before getting here,
2648 * so if another thread is fiddling with its suspend count (perhaps
2649 * self-suspending for the debugger) it won't block while we're waiting
2650 * in here.
2651 */
2652 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2653 if (thread == self)
2654 continue;
2655
2656 /* debugger events don't suspend JDWP thread */
2657 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2658 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
2659 continue;
2660
2661 /* wait for the other thread to see the pending suspend */
2662 waitForThreadSuspend(self, thread);
2663
Jeff Hao97319a82009-08-12 16:57:15 -07002664 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 -08002665 self->threadId,
2666 thread->threadId, thread->status, thread->suspendCount,
2667 thread->dbgSuspendCount, thread->isSuspended);
2668 }
2669
2670 dvmUnlockThreadList();
2671 unlockThreadSuspend();
2672
2673 LOG_THREAD("threadid=%d: SuspendAll complete\n", self->threadId);
2674}
2675
2676/*
2677 * Resume all threads that are currently suspended.
2678 *
2679 * The "why" must match with the previous suspend.
2680 */
2681void dvmResumeAllThreads(SuspendCause why)
2682{
2683 Thread* self = dvmThreadSelf();
2684 Thread* thread;
2685 int cc;
2686
2687 lockThreadSuspend("res-all", why); /* one suspend/resume at a time */
2688 LOG_THREAD("threadid=%d: ResumeAll starting\n", self->threadId);
2689
2690 /*
2691 * Decrement the suspend counts for all threads. No need for atomic
2692 * writes, since nobody should be moving until we decrement the count.
2693 * We do need to hold the thread list because of JNI attaches.
2694 */
2695 dvmLockThreadList(self);
2696 lockThreadSuspendCount();
2697 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2698 if (thread == self)
2699 continue;
2700
2701 /* debugger events don't suspend JDWP thread */
2702 if ((why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT) &&
2703 thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState))
Andy McFadden2aa43612009-06-17 16:29:30 -07002704 {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002705 continue;
Andy McFadden2aa43612009-06-17 16:29:30 -07002706 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002707
2708 if (thread->suspendCount > 0) {
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002709 dvmAddToThreadSuspendCount(&thread->suspendCount, -1);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002710 if (why == SUSPEND_FOR_DEBUG || why == SUSPEND_FOR_DEBUG_EVENT)
2711 thread->dbgSuspendCount--;
2712 } else {
2713 LOG_THREAD("threadid=%d: suspendCount already zero\n",
2714 thread->threadId);
2715 }
2716 }
2717 unlockThreadSuspendCount();
2718 dvmUnlockThreadList();
2719
2720 /*
Andy McFadden2aa43612009-06-17 16:29:30 -07002721 * In some ways it makes sense to continue to hold the thread-suspend
2722 * lock while we issue the wakeup broadcast. It allows us to complete
2723 * one operation before moving on to the next, which simplifies the
2724 * thread activity debug traces.
2725 *
2726 * This approach caused us some difficulty under Linux, because the
2727 * condition variable broadcast not only made the threads runnable,
2728 * but actually caused them to execute, and it was a while before
2729 * the thread performing the wakeup had an opportunity to release the
2730 * thread-suspend lock.
2731 *
2732 * This is a problem because, when a thread tries to acquire that
2733 * lock, it times out after 3 seconds. If at some point the thread
2734 * is told to suspend, the clock resets; but since the VM is still
2735 * theoretically mid-resume, there's no suspend pending. If, for
2736 * example, the GC was waking threads up while the SIGQUIT handler
2737 * was trying to acquire the lock, we would occasionally time out on
2738 * a busy system and SignalCatcher would abort.
2739 *
2740 * We now perform the unlock before the wakeup broadcast. The next
2741 * suspend can't actually start until the broadcast completes and
2742 * returns, because we're holding the thread-suspend-count lock, but the
2743 * suspending thread is now able to make progress and we avoid the abort.
2744 *
2745 * (Technically there is a narrow window between when we release
2746 * the thread-suspend lock and grab the thread-suspend-count lock.
2747 * This could cause us to send a broadcast to threads with nonzero
2748 * suspend counts, but this is expected and they'll all just fall
2749 * right back to sleep. It's probably safe to grab the suspend-count
2750 * lock before releasing thread-suspend, since we're still following
2751 * the correct order of acquisition, but it feels weird.)
2752 */
2753
2754 LOG_THREAD("threadid=%d: ResumeAll waking others\n", self->threadId);
2755 unlockThreadSuspend();
2756
2757 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002758 * Broadcast a notification to all suspended threads, some or all of
2759 * which may choose to wake up. No need to wait for them.
2760 */
2761 lockThreadSuspendCount();
2762 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2763 assert(cc == 0);
2764 unlockThreadSuspendCount();
2765
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002766 LOG_THREAD("threadid=%d: ResumeAll complete\n", self->threadId);
2767}
2768
2769/*
2770 * Undo any debugger suspensions. This is called when the debugger
2771 * disconnects.
2772 */
2773void dvmUndoDebuggerSuspensions(void)
2774{
2775 Thread* self = dvmThreadSelf();
2776 Thread* thread;
2777 int cc;
2778
2779 lockThreadSuspend("undo", SUSPEND_FOR_DEBUG);
2780 LOG_THREAD("threadid=%d: UndoDebuggerSusp starting\n", self->threadId);
2781
2782 /*
2783 * Decrement the suspend counts for all threads. No need for atomic
2784 * writes, since nobody should be moving until we decrement the count.
2785 * We do need to hold the thread list because of JNI attaches.
2786 */
2787 dvmLockThreadList(self);
2788 lockThreadSuspendCount();
2789 for (thread = gDvm.threadList; thread != NULL; thread = thread->next) {
2790 if (thread == self)
2791 continue;
2792
2793 /* debugger events don't suspend JDWP thread */
2794 if (thread->handle == dvmJdwpGetDebugThread(gDvm.jdwpState)) {
2795 assert(thread->dbgSuspendCount == 0);
2796 continue;
2797 }
2798
2799 assert(thread->suspendCount >= thread->dbgSuspendCount);
Bill Buzbee46cd5b62009-06-05 15:36:06 -07002800 dvmAddToThreadSuspendCount(&thread->suspendCount,
2801 -thread->dbgSuspendCount);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002802 thread->dbgSuspendCount = 0;
2803 }
2804 unlockThreadSuspendCount();
2805 dvmUnlockThreadList();
2806
2807 /*
2808 * Broadcast a notification to all suspended threads, some or all of
2809 * which may choose to wake up. No need to wait for them.
2810 */
2811 lockThreadSuspendCount();
2812 cc = pthread_cond_broadcast(&gDvm.threadSuspendCountCond);
2813 assert(cc == 0);
2814 unlockThreadSuspendCount();
2815
2816 unlockThreadSuspend();
2817
2818 LOG_THREAD("threadid=%d: UndoDebuggerSusp complete\n", self->threadId);
2819}
2820
2821/*
2822 * Determine if a thread is suspended.
2823 *
2824 * As with all operations on foreign threads, the caller should hold
2825 * the thread list lock before calling.
2826 */
2827bool dvmIsSuspended(Thread* thread)
2828{
2829 /*
2830 * The thread could be:
2831 * (1) Running happily. status is RUNNING, isSuspended is false,
2832 * suspendCount is zero. Return "false".
2833 * (2) Pending suspend. status is RUNNING, isSuspended is false,
2834 * suspendCount is nonzero. Return "false".
2835 * (3) Suspended. suspendCount is nonzero, and either (status is
2836 * RUNNING and isSuspended is true) OR (status is !RUNNING).
2837 * Return "true".
2838 * (4) Waking up. suspendCount is zero, status is RUNNING and
2839 * isSuspended is true. Return "false" (since it could change
2840 * out from under us, unless we hold suspendCountLock).
2841 */
2842
2843 return (thread->suspendCount != 0 &&
2844 ((thread->status == THREAD_RUNNING && thread->isSuspended) ||
2845 (thread->status != THREAD_RUNNING)));
2846}
2847
2848/*
2849 * Wait until another thread self-suspends. This is specifically for
2850 * synchronization between the JDWP thread and a thread that has decided
2851 * to suspend itself after sending an event to the debugger.
2852 *
2853 * Threads that encounter "suspend all" events work as well -- the thread
2854 * in question suspends everybody else and then itself.
2855 *
2856 * We can't hold a thread lock here or in the caller, because we could
2857 * get here just before the to-be-waited-for-thread issues a "suspend all".
2858 * There's an opportunity for badness if the thread we're waiting for exits
2859 * and gets cleaned up, but since the thread in question is processing a
2860 * debugger event, that's not really a possibility. (To avoid deadlock,
2861 * it's important that we not be in THREAD_RUNNING while we wait.)
2862 */
2863void dvmWaitForSuspend(Thread* thread)
2864{
2865 Thread* self = dvmThreadSelf();
2866
2867 LOG_THREAD("threadid=%d: waiting for threadid=%d to sleep\n",
2868 self->threadId, thread->threadId);
2869
2870 assert(thread->handle != dvmJdwpGetDebugThread(gDvm.jdwpState));
2871 assert(thread != self);
2872 assert(self->status != THREAD_RUNNING);
2873
2874 waitForThreadSuspend(self, thread);
2875
2876 LOG_THREAD("threadid=%d: threadid=%d is now asleep\n",
2877 self->threadId, thread->threadId);
2878}
2879
2880/*
2881 * Check to see if we need to suspend ourselves. If so, go to sleep on
2882 * a condition variable.
2883 *
2884 * Takes "self" as an argument as an optimization. Pass in NULL to have
2885 * it do the lookup.
2886 *
2887 * Returns "true" if we suspended ourselves.
2888 */
2889bool dvmCheckSuspendPending(Thread* self)
2890{
2891 bool didSuspend;
2892
2893 if (self == NULL)
2894 self = dvmThreadSelf();
2895
2896 /* fast path: if count is zero, bail immediately */
2897 if (self->suspendCount == 0)
2898 return false;
2899
2900 lockThreadSuspendCount(); /* grab gDvm.threadSuspendCountLock */
2901
2902 assert(self->suspendCount >= 0); /* XXX: valid? useful? */
2903
2904 didSuspend = (self->suspendCount != 0);
2905 self->isSuspended = true;
2906 LOG_THREAD("threadid=%d: self-suspending\n", self->threadId);
2907 while (self->suspendCount != 0) {
2908 /* wait for wakeup signal; releases lock */
2909 int cc;
2910 cc = pthread_cond_wait(&gDvm.threadSuspendCountCond,
2911 &gDvm.threadSuspendCountLock);
2912 assert(cc == 0);
2913 }
2914 assert(self->suspendCount == 0 && self->dbgSuspendCount == 0);
2915 self->isSuspended = false;
2916 LOG_THREAD("threadid=%d: self-reviving, status=%d\n",
2917 self->threadId, self->status);
2918
2919 unlockThreadSuspendCount();
2920
2921 return didSuspend;
2922}
2923
2924/*
2925 * Update our status.
2926 *
2927 * The "self" argument, which may be NULL, is accepted as an optimization.
2928 *
2929 * Returns the old status.
2930 */
2931ThreadStatus dvmChangeStatus(Thread* self, ThreadStatus newStatus)
2932{
2933 ThreadStatus oldStatus;
2934
2935 if (self == NULL)
2936 self = dvmThreadSelf();
2937
2938 LOGVV("threadid=%d: (status %d -> %d)\n",
2939 self->threadId, self->status, newStatus);
2940
2941 oldStatus = self->status;
2942
2943 if (newStatus == THREAD_RUNNING) {
2944 /*
2945 * Change our status to THREAD_RUNNING. The transition requires
2946 * that we check for pending suspension, because the VM considers
2947 * us to be "asleep" in all other states.
2948 *
2949 * We need to do the "suspend pending" check FIRST, because it grabs
2950 * a lock that could be held by something that wants us to suspend.
2951 * If we're in RUNNING it will wait for us, and we'll be waiting
2952 * for the lock it holds.
2953 */
2954 assert(self->status != THREAD_RUNNING);
2955
2956 dvmCheckSuspendPending(self);
2957 self->status = THREAD_RUNNING;
2958 } else {
2959 /*
2960 * Change from one state to another, neither of which is
2961 * THREAD_RUNNING. This is most common during system or thread
2962 * initialization.
2963 */
2964 self->status = newStatus;
2965 }
2966
2967 return oldStatus;
2968}
2969
2970/*
2971 * Get a statically defined thread group from a field in the ThreadGroup
2972 * Class object. Expected arguments are "mMain" and "mSystem".
2973 */
2974static Object* getStaticThreadGroup(const char* fieldName)
2975{
2976 StaticField* groupField;
2977 Object* groupObj;
2978
2979 groupField = dvmFindStaticField(gDvm.classJavaLangThreadGroup,
2980 fieldName, "Ljava/lang/ThreadGroup;");
2981 if (groupField == NULL) {
2982 LOGE("java.lang.ThreadGroup does not have an '%s' field\n", fieldName);
2983 dvmThrowException("Ljava/lang/IncompatibleClassChangeError;", NULL);
2984 return NULL;
2985 }
2986 groupObj = dvmGetStaticFieldObject(groupField);
2987 if (groupObj == NULL) {
2988 LOGE("java.lang.ThreadGroup.%s not initialized\n", fieldName);
2989 dvmThrowException("Ljava/lang/InternalError;", NULL);
2990 return NULL;
2991 }
2992
2993 return groupObj;
2994}
2995Object* dvmGetSystemThreadGroup(void)
2996{
2997 return getStaticThreadGroup("mSystem");
2998}
2999Object* dvmGetMainThreadGroup(void)
3000{
3001 return getStaticThreadGroup("mMain");
3002}
3003
3004/*
3005 * Given a VMThread object, return the associated Thread*.
3006 *
3007 * NOTE: if the thread detaches, the struct Thread will disappear, and
3008 * we will be touching invalid data. For safety, lock the thread list
3009 * before calling this.
3010 */
3011Thread* dvmGetThreadFromThreadObject(Object* vmThreadObj)
3012{
3013 int vmData;
3014
3015 vmData = dvmGetFieldInt(vmThreadObj, gDvm.offJavaLangVMThread_vmData);
Andy McFadden44860362009-08-06 17:56:14 -07003016
3017 if (false) {
3018 Thread* thread = gDvm.threadList;
3019 while (thread != NULL) {
3020 if ((Thread*)vmData == thread)
3021 break;
3022
3023 thread = thread->next;
3024 }
3025
3026 if (thread == NULL) {
3027 LOGW("WARNING: vmThreadObj=%p has thread=%p, not in thread list\n",
3028 vmThreadObj, (Thread*)vmData);
3029 vmData = 0;
3030 }
3031 }
3032
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003033 return (Thread*) vmData;
3034}
3035
3036
3037/*
3038 * Conversion map for "nice" values.
3039 *
3040 * We use Android thread priority constants to be consistent with the rest
3041 * of the system. In some cases adjacent entries may overlap.
3042 */
3043static const int kNiceValues[10] = {
3044 ANDROID_PRIORITY_LOWEST, /* 1 (MIN_PRIORITY) */
3045 ANDROID_PRIORITY_BACKGROUND + 6,
3046 ANDROID_PRIORITY_BACKGROUND + 3,
3047 ANDROID_PRIORITY_BACKGROUND,
3048 ANDROID_PRIORITY_NORMAL, /* 5 (NORM_PRIORITY) */
3049 ANDROID_PRIORITY_NORMAL - 2,
3050 ANDROID_PRIORITY_NORMAL - 4,
3051 ANDROID_PRIORITY_URGENT_DISPLAY + 3,
3052 ANDROID_PRIORITY_URGENT_DISPLAY + 2,
3053 ANDROID_PRIORITY_URGENT_DISPLAY /* 10 (MAX_PRIORITY) */
3054};
3055
3056/*
Andy McFaddend62c0b52009-08-04 15:02:12 -07003057 * Change the scheduler cgroup of the current thread.
3058 *
3059 * Returns 0 on success.
San Mehat256fc152009-04-21 14:03:06 -07003060 */
3061int dvmChangeThreadSchedulerGroup(const char *cgroup)
3062{
3063#ifdef HAVE_ANDROID_OS
Andy McFaddend62c0b52009-08-04 15:02:12 -07003064 int fd;
San Mehat256fc152009-04-21 14:03:06 -07003065 char path[255];
San Mehat256fc152009-04-21 14:03:06 -07003066
Andy McFaddend62c0b52009-08-04 15:02:12 -07003067 snprintf(path, sizeof(path), "/dev/cpuctl/%s/tasks", (cgroup ? cgroup :""));
San Mehat256fc152009-04-21 14:03:06 -07003068
Andy McFaddend62c0b52009-08-04 15:02:12 -07003069 if ((fd = open(path, O_WRONLY)) < 0) {
3070 int err = errno;
San Mehat256fc152009-04-21 14:03:06 -07003071#if ENABLE_CGROUP_ERR_LOGGING
Andy McFaddend62c0b52009-08-04 15:02:12 -07003072 LOGW("Unable to open %s (%s)\n", path, strerror(err));
San Mehat256fc152009-04-21 14:03:06 -07003073#endif
Andy McFaddend62c0b52009-08-04 15:02:12 -07003074 return -err;
San Mehat256fc152009-04-21 14:03:06 -07003075 }
3076
Andy McFaddend62c0b52009-08-04 15:02:12 -07003077 if (write(fd, "0", 1) < 0) {
3078 int err = errno;
San Mehat256fc152009-04-21 14:03:06 -07003079#if ENABLE_CGROUP_ERR_LOGGING
Andy McFaddend62c0b52009-08-04 15:02:12 -07003080 LOGW("Unable to move tid %d to cgroup %s (%s)\n",
3081 dvmThreadSelf()->systemTid,
3082 (cgroup ? cgroup : "<default>"), strerror(err));
San Mehat256fc152009-04-21 14:03:06 -07003083#endif
Andy McFaddend62c0b52009-08-04 15:02:12 -07003084 close(fd);
3085 return -err;
San Mehat256fc152009-04-21 14:03:06 -07003086 }
Andy McFaddend62c0b52009-08-04 15:02:12 -07003087 close(fd);
San Mehat256fc152009-04-21 14:03:06 -07003088
Andy McFaddend62c0b52009-08-04 15:02:12 -07003089 return 0;
3090
San Mehat256fc152009-04-21 14:03:06 -07003091#else // HAVE_ANDROID_OS
3092 return 0;
3093#endif
3094}
3095
3096/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003097 * Change the priority of a system thread to match that of the Thread object.
3098 *
3099 * We map a priority value from 1-10 to Linux "nice" values, where lower
3100 * numbers indicate higher priority.
3101 */
3102void dvmChangeThreadPriority(Thread* thread, int newPriority)
3103{
3104 pid_t pid = thread->systemTid;
3105 int newNice;
3106
3107 if (newPriority < 1 || newPriority > 10) {
3108 LOGW("bad priority %d\n", newPriority);
3109 newPriority = 5;
3110 }
3111 newNice = kNiceValues[newPriority-1];
3112
Andy McFaddend62c0b52009-08-04 15:02:12 -07003113 if (newNice >= ANDROID_PRIORITY_BACKGROUND) {
San Mehat256fc152009-04-21 14:03:06 -07003114 dvmChangeThreadSchedulerGroup("bg_non_interactive");
San Mehat3e371e22009-06-26 08:36:16 -07003115 } else if (getpriority(PRIO_PROCESS, pid) >= ANDROID_PRIORITY_BACKGROUND) {
San Mehat256fc152009-04-21 14:03:06 -07003116 dvmChangeThreadSchedulerGroup(NULL);
3117 }
3118
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003119 if (setpriority(PRIO_PROCESS, pid, newNice) != 0) {
3120 char* str = dvmGetThreadName(thread);
3121 LOGI("setPriority(%d) '%s' to prio=%d(n=%d) failed: %s\n",
3122 pid, str, newPriority, newNice, strerror(errno));
3123 free(str);
3124 } else {
3125 LOGV("setPriority(%d) to prio=%d(n=%d)\n",
3126 pid, newPriority, newNice);
3127 }
3128}
3129
3130/*
3131 * Get the thread priority for the current thread by querying the system.
3132 * This is useful when attaching a thread through JNI.
3133 *
3134 * Returns a value from 1 to 10 (compatible with java.lang.Thread values).
3135 */
3136static int getThreadPriorityFromSystem(void)
3137{
3138 int i, sysprio, jprio;
3139
3140 errno = 0;
3141 sysprio = getpriority(PRIO_PROCESS, 0);
3142 if (sysprio == -1 && errno != 0) {
3143 LOGW("getpriority() failed: %s\n", strerror(errno));
3144 return THREAD_NORM_PRIORITY;
3145 }
3146
3147 jprio = THREAD_MIN_PRIORITY;
3148 for (i = 0; i < NELEM(kNiceValues); i++) {
3149 if (sysprio >= kNiceValues[i])
3150 break;
3151 jprio++;
3152 }
3153 if (jprio > THREAD_MAX_PRIORITY)
3154 jprio = THREAD_MAX_PRIORITY;
3155
3156 return jprio;
3157}
3158
3159
3160/*
3161 * Return true if the thread is on gDvm.threadList.
3162 * Caller should not hold gDvm.threadListLock.
3163 */
3164bool dvmIsOnThreadList(const Thread* thread)
3165{
3166 bool ret = false;
3167
3168 dvmLockThreadList(NULL);
3169 if (thread == gDvm.threadList) {
3170 ret = true;
3171 } else {
3172 ret = thread->prev != NULL || thread->next != NULL;
3173 }
3174 dvmUnlockThreadList();
3175
3176 return ret;
3177}
3178
3179/*
3180 * Dump a thread to the log file -- just calls dvmDumpThreadEx() with an
3181 * output target.
3182 */
3183void dvmDumpThread(Thread* thread, bool isRunning)
3184{
3185 DebugOutputTarget target;
3186
3187 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
3188 dvmDumpThreadEx(&target, thread, isRunning);
3189}
3190
3191/*
Andy McFaddend62c0b52009-08-04 15:02:12 -07003192 * Try to get the scheduler group.
3193 *
3194 * The data from /proc/<pid>/cgroup looks like:
3195 * 2:cpu:/bg_non_interactive
3196 *
3197 * We return the part after the "/", which will be an empty string for
3198 * the default cgroup. If the string is longer than "bufLen", the string
3199 * will be truncated.
3200 */
3201static bool getSchedulerGroup(Thread* thread, char* buf, size_t bufLen)
3202{
3203#ifdef HAVE_ANDROID_OS
3204 char pathBuf[32];
3205 char readBuf[256];
3206 ssize_t count;
3207 int fd;
3208
3209 snprintf(pathBuf, sizeof(pathBuf), "/proc/%d/cgroup", thread->systemTid);
3210 if ((fd = open(pathBuf, O_RDONLY)) < 0) {
3211 LOGV("open(%s) failed: %s\n", pathBuf, strerror(errno));
3212 return false;
3213 }
3214
3215 count = read(fd, readBuf, sizeof(readBuf));
3216 if (count <= 0) {
3217 LOGV("read(%s) failed (%d): %s\n",
3218 pathBuf, (int) count, strerror(errno));
3219 close(fd);
3220 return false;
3221 }
3222 close(fd);
3223
3224 readBuf[--count] = '\0'; /* remove the '\n', now count==strlen */
3225
3226 char* cp = strchr(readBuf, '/');
3227 if (cp == NULL) {
3228 readBuf[sizeof(readBuf)-1] = '\0';
3229 LOGV("no '/' in '%s' (file=%s count=%d)\n",
3230 readBuf, pathBuf, (int) count);
3231 return false;
3232 }
3233
3234 memcpy(buf, cp+1, count); /* count-1 for cp+1, count+1 for NUL */
3235 return true;
3236#else
3237 return false;
3238#endif
3239}
3240
3241/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003242 * Print information about the specified thread.
3243 *
3244 * Works best when the thread in question is "self" or has been suspended.
3245 * When dumping a separate thread that's still running, set "isRunning" to
3246 * use a more cautious thread dump function.
3247 */
3248void dvmDumpThreadEx(const DebugOutputTarget* target, Thread* thread,
3249 bool isRunning)
3250{
3251 /* tied to ThreadStatus enum */
3252 static const char* kStatusNames[] = {
3253 "ZOMBIE", "RUNNABLE", "TIMED_WAIT", "MONITOR", "WAIT",
3254 "INITIALIZING", "STARTING", "NATIVE", "VMWAIT"
3255 };
3256 Object* threadObj;
3257 Object* groupObj;
3258 StringObject* nameStr;
3259 char* threadName = NULL;
3260 char* groupName = NULL;
Andy McFaddend62c0b52009-08-04 15:02:12 -07003261 char schedulerGroupBuf[32];
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003262 bool isDaemon;
3263 int priority; // java.lang.Thread priority
3264 int policy; // pthread policy
3265 struct sched_param sp; // pthread scheduling parameters
3266
3267 threadObj = thread->threadObj;
3268 if (threadObj == NULL) {
3269 LOGW("Can't dump thread %d: threadObj not set\n", thread->threadId);
3270 return;
3271 }
3272 nameStr = (StringObject*) dvmGetFieldObject(threadObj,
3273 gDvm.offJavaLangThread_name);
3274 threadName = dvmCreateCstrFromString(nameStr);
3275
3276 priority = dvmGetFieldInt(threadObj, gDvm.offJavaLangThread_priority);
3277 isDaemon = dvmGetFieldBoolean(threadObj, gDvm.offJavaLangThread_daemon);
3278
3279 if (pthread_getschedparam(pthread_self(), &policy, &sp) != 0) {
3280 LOGW("Warning: pthread_getschedparam failed\n");
3281 policy = -1;
3282 sp.sched_priority = -1;
3283 }
Andy McFaddend62c0b52009-08-04 15:02:12 -07003284 if (!getSchedulerGroup(thread, schedulerGroupBuf,sizeof(schedulerGroupBuf)))
3285 {
3286 strcpy(schedulerGroupBuf, "unknown");
3287 } else if (schedulerGroupBuf[0] == '\0') {
3288 strcpy(schedulerGroupBuf, "default");
3289 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003290
3291 /* a null value for group is not expected, but deal with it anyway */
3292 groupObj = (Object*) dvmGetFieldObject(threadObj,
3293 gDvm.offJavaLangThread_group);
3294 if (groupObj != NULL) {
3295 int offset = dvmFindFieldOffset(gDvm.classJavaLangThreadGroup,
3296 "name", "Ljava/lang/String;");
3297 if (offset < 0) {
3298 LOGW("Unable to find 'name' field in ThreadGroup\n");
3299 } else {
3300 nameStr = (StringObject*) dvmGetFieldObject(groupObj, offset);
3301 groupName = dvmCreateCstrFromString(nameStr);
3302 }
3303 }
3304 if (groupName == NULL)
3305 groupName = strdup("(BOGUS GROUP)");
3306
3307 assert(thread->status < NELEM(kStatusNames));
3308 dvmPrintDebugMessage(target,
3309 "\"%s\"%s prio=%d tid=%d %s\n",
3310 threadName, isDaemon ? " daemon" : "",
3311 priority, thread->threadId, kStatusNames[thread->status]);
3312 dvmPrintDebugMessage(target,
Andy McFadden2aa43612009-06-17 16:29:30 -07003313 " | group=\"%s\" sCount=%d dsCount=%d s=%c obj=%p self=%p\n",
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003314 groupName, thread->suspendCount, thread->dbgSuspendCount,
Andy McFadden2aa43612009-06-17 16:29:30 -07003315 thread->isSuspended ? 'Y' : 'N', thread->threadObj, thread);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003316 dvmPrintDebugMessage(target,
Andy McFaddend62c0b52009-08-04 15:02:12 -07003317 " | sysTid=%d nice=%d sched=%d/%d cgrp=%s handle=%d\n",
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003318 thread->systemTid, getpriority(PRIO_PROCESS, thread->systemTid),
Andy McFaddend62c0b52009-08-04 15:02:12 -07003319 policy, sp.sched_priority, schedulerGroupBuf, (int)thread->handle);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003320
3321#ifdef WITH_MONITOR_TRACKING
3322 if (!isRunning) {
3323 LockedObjectData* lod = thread->pLockedObjects;
3324 if (lod != NULL)
3325 dvmPrintDebugMessage(target, " | monitors held:\n");
3326 else
3327 dvmPrintDebugMessage(target, " | monitors held: <none>\n");
3328 while (lod != NULL) {
3329 dvmPrintDebugMessage(target, " > %p[%d] (%s)\n",
3330 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
3331 lod = lod->next;
3332 }
3333 }
3334#endif
3335
3336 if (isRunning)
3337 dvmDumpRunningThreadStack(target, thread);
3338 else
3339 dvmDumpThreadStack(target, thread);
3340
3341 free(threadName);
3342 free(groupName);
3343
3344}
3345
3346/*
3347 * Get the name of a thread.
3348 *
3349 * For correctness, the caller should hold the thread list lock to ensure
3350 * that the thread doesn't go away mid-call.
3351 *
3352 * Returns a newly-allocated string, or NULL if the Thread doesn't have a name.
3353 */
3354char* dvmGetThreadName(Thread* thread)
3355{
3356 StringObject* nameObj;
3357
3358 if (thread->threadObj == NULL) {
3359 LOGW("threadObj is NULL, name not available\n");
3360 return strdup("-unknown-");
3361 }
3362
3363 nameObj = (StringObject*)
3364 dvmGetFieldObject(thread->threadObj, gDvm.offJavaLangThread_name);
3365 return dvmCreateCstrFromString(nameObj);
3366}
3367
3368/*
3369 * Dump all threads to the log file -- just calls dvmDumpAllThreadsEx() with
3370 * an output target.
3371 */
3372void dvmDumpAllThreads(bool grabLock)
3373{
3374 DebugOutputTarget target;
3375
3376 dvmCreateLogOutputTarget(&target, ANDROID_LOG_INFO, LOG_TAG);
3377 dvmDumpAllThreadsEx(&target, grabLock);
3378}
3379
3380/*
3381 * Print information about all known threads. Assumes they have been
3382 * suspended (or are in a non-interpreting state, e.g. WAIT or NATIVE).
3383 *
3384 * If "grabLock" is true, we grab the thread lock list. This is important
3385 * to do unless the caller already holds the lock.
3386 */
3387void dvmDumpAllThreadsEx(const DebugOutputTarget* target, bool grabLock)
3388{
3389 Thread* thread;
3390
3391 dvmPrintDebugMessage(target, "DALVIK THREADS:\n");
3392
3393 if (grabLock)
3394 dvmLockThreadList(dvmThreadSelf());
3395
3396 thread = gDvm.threadList;
3397 while (thread != NULL) {
3398 dvmDumpThreadEx(target, thread, false);
3399
3400 /* verify link */
3401 assert(thread->next == NULL || thread->next->prev == thread);
3402
3403 thread = thread->next;
3404 }
3405
3406 if (grabLock)
3407 dvmUnlockThreadList();
3408}
3409
3410#ifdef WITH_MONITOR_TRACKING
3411/*
3412 * Count up the #of locked objects in the current thread.
3413 */
3414static int getThreadObjectCount(const Thread* self)
3415{
3416 LockedObjectData* lod;
3417 int count = 0;
3418
3419 lod = self->pLockedObjects;
3420 while (lod != NULL) {
3421 count++;
3422 lod = lod->next;
3423 }
3424 return count;
3425}
3426
3427/*
3428 * Add the object to the thread's locked object list if it doesn't already
3429 * exist. The most recently added object is the most likely to be released
3430 * next, so we insert at the head of the list.
3431 *
3432 * If it already exists, we increase the recursive lock count.
3433 *
3434 * The object's lock may be thin or fat.
3435 */
3436void dvmAddToMonitorList(Thread* self, Object* obj, bool withTrace)
3437{
3438 LockedObjectData* newLod;
3439 LockedObjectData* lod;
3440 int* trace;
3441 int depth;
3442
3443 lod = self->pLockedObjects;
3444 while (lod != NULL) {
3445 if (lod->obj == obj) {
3446 lod->recursionCount++;
3447 LOGV("+++ +recursive lock %p -> %d\n", obj, lod->recursionCount);
3448 return;
3449 }
3450 lod = lod->next;
3451 }
3452
3453 newLod = (LockedObjectData*) calloc(1, sizeof(LockedObjectData));
3454 if (newLod == NULL) {
3455 LOGE("malloc failed on %d bytes\n", sizeof(LockedObjectData));
3456 return;
3457 }
3458 newLod->obj = obj;
3459 newLod->recursionCount = 0;
3460
3461 if (withTrace) {
3462 trace = dvmFillInStackTraceRaw(self, &depth);
3463 newLod->rawStackTrace = trace;
3464 newLod->stackDepth = depth;
3465 }
3466
3467 newLod->next = self->pLockedObjects;
3468 self->pLockedObjects = newLod;
3469
3470 LOGV("+++ threadid=%d: added %p, now %d\n",
3471 self->threadId, newLod, getThreadObjectCount(self));
3472}
3473
3474/*
3475 * Remove the object from the thread's locked object list. If the entry
3476 * has a nonzero recursion count, we just decrement the count instead.
3477 */
3478void dvmRemoveFromMonitorList(Thread* self, Object* obj)
3479{
3480 LockedObjectData* lod;
3481 LockedObjectData* prevLod;
3482
3483 lod = self->pLockedObjects;
3484 prevLod = NULL;
3485 while (lod != NULL) {
3486 if (lod->obj == obj) {
3487 if (lod->recursionCount > 0) {
3488 lod->recursionCount--;
3489 LOGV("+++ -recursive lock %p -> %d\n",
3490 obj, lod->recursionCount);
3491 return;
3492 } else {
3493 break;
3494 }
3495 }
3496 prevLod = lod;
3497 lod = lod->next;
3498 }
3499
3500 if (lod == NULL) {
3501 LOGW("BUG: object %p not found in thread's lock list\n", obj);
3502 return;
3503 }
3504 if (prevLod == NULL) {
3505 /* first item in list */
3506 assert(self->pLockedObjects == lod);
3507 self->pLockedObjects = lod->next;
3508 } else {
3509 /* middle/end of list */
3510 prevLod->next = lod->next;
3511 }
3512
3513 LOGV("+++ threadid=%d: removed %p, now %d\n",
3514 self->threadId, lod, getThreadObjectCount(self));
3515 free(lod->rawStackTrace);
3516 free(lod);
3517}
3518
3519/*
3520 * If the specified object is already in the thread's locked object list,
3521 * return the LockedObjectData struct. Otherwise return NULL.
3522 */
3523LockedObjectData* dvmFindInMonitorList(const Thread* self, const Object* obj)
3524{
3525 LockedObjectData* lod;
3526
3527 lod = self->pLockedObjects;
3528 while (lod != NULL) {
3529 if (lod->obj == obj)
3530 return lod;
3531 lod = lod->next;
3532 }
3533 return NULL;
3534}
3535#endif /*WITH_MONITOR_TRACKING*/
3536
3537
3538/*
3539 * GC helper functions
3540 */
3541
The Android Open Source Project99409882009-03-18 22:20:24 -07003542/*
3543 * Add the contents of the registers from the interpreted call stack.
3544 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003545static void gcScanInterpStackReferences(Thread *thread)
3546{
3547 const u4 *framePtr;
The Android Open Source Project99409882009-03-18 22:20:24 -07003548#if WITH_EXTRA_GC_CHECKS > 1
3549 bool first = true;
3550#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003551
3552 framePtr = (const u4 *)thread->curFrame;
3553 while (framePtr != NULL) {
3554 const StackSaveArea *saveArea;
3555 const Method *method;
3556
3557 saveArea = SAVEAREA_FROM_FP(framePtr);
3558 method = saveArea->method;
The Android Open Source Project99409882009-03-18 22:20:24 -07003559 if (method != NULL && !dvmIsNativeMethod(method)) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003560#ifdef COUNT_PRECISE_METHODS
3561 /* the GC is running, so no lock required */
The Android Open Source Project99409882009-03-18 22:20:24 -07003562 if (dvmPointerSetAddEntry(gDvm.preciseMethods, method))
3563 LOGI("PGC: added %s.%s %p\n",
3564 method->clazz->descriptor, method->name, method);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003565#endif
The Android Open Source Project99409882009-03-18 22:20:24 -07003566#if WITH_EXTRA_GC_CHECKS > 1
3567 /*
3568 * May also want to enable the memset() in the "invokeMethod"
3569 * goto target in the portable interpreter. That sets the stack
3570 * to a pattern that makes referring to uninitialized data
3571 * very obvious.
3572 */
3573
3574 if (first) {
3575 /*
3576 * First frame, isn't native, check the "alternate" saved PC
3577 * as a sanity check.
3578 *
3579 * It seems like we could check the second frame if the first
3580 * is native, since the PCs should be the same. It turns out
3581 * this doesn't always work. The problem is that we could
3582 * have calls in the sequence:
3583 * interp method #2
3584 * native method
3585 * interp method #1
3586 *
3587 * and then GC while in the native method after returning
3588 * from interp method #2. The currentPc on the stack is
3589 * for interp method #1, but thread->currentPc2 is still
3590 * set for the last thing interp method #2 did.
3591 *
3592 * This can also happen in normal execution:
3593 * - sget-object on not-yet-loaded class
3594 * - class init updates currentPc2
3595 * - static field init is handled by parsing annotations;
3596 * static String init requires creation of a String object,
3597 * which can cause a GC
3598 *
3599 * Essentially, any pattern that involves executing
3600 * interpreted code and then causes an allocation without
3601 * executing instructions in the original method will hit
3602 * this. These are rare enough that the test still has
3603 * some value.
3604 */
3605 if (saveArea->xtra.currentPc != thread->currentPc2) {
3606 LOGW("PGC: savedPC(%p) != current PC(%p), %s.%s ins=%p\n",
3607 saveArea->xtra.currentPc, thread->currentPc2,
3608 method->clazz->descriptor, method->name, method->insns);
3609 if (saveArea->xtra.currentPc != NULL)
3610 LOGE(" pc inst = 0x%04x\n", *saveArea->xtra.currentPc);
3611 if (thread->currentPc2 != NULL)
3612 LOGE(" pc2 inst = 0x%04x\n", *thread->currentPc2);
3613 dvmDumpThread(thread, false);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003614 }
The Android Open Source Project99409882009-03-18 22:20:24 -07003615 } else {
3616 /*
3617 * It's unusual, but not impossible, for a non-first frame
3618 * to be at something other than a method invocation. For
3619 * example, if we do a new-instance on a nonexistent class,
3620 * we'll have a lot of class loader activity on the stack
3621 * above the frame with the "new" operation. Could also
3622 * happen while we initialize a Throwable when an instruction
3623 * fails.
3624 *
3625 * So there's not much we can do here to verify the PC,
3626 * except to verify that it's a GC point.
3627 */
3628 }
3629 assert(saveArea->xtra.currentPc != NULL);
3630#endif
3631
3632 const RegisterMap* pMap;
3633 const u1* regVector;
3634 int i;
3635
Andy McFaddencf8b55c2009-04-13 15:26:03 -07003636 Method* nonConstMethod = (Method*) method; // quiet gcc
3637 pMap = dvmGetExpandedRegisterMap(nonConstMethod);
The Android Open Source Project99409882009-03-18 22:20:24 -07003638 if (pMap != NULL) {
3639 /* found map, get registers for this address */
3640 int addr = saveArea->xtra.currentPc - method->insns;
Andy McFaddend45a8872009-03-24 20:41:52 -07003641 regVector = dvmRegisterMapGetLine(pMap, addr);
The Android Open Source Project99409882009-03-18 22:20:24 -07003642 if (regVector == NULL) {
3643 LOGW("PGC: map but no entry for %s.%s addr=0x%04x\n",
3644 method->clazz->descriptor, method->name, addr);
3645 } else {
3646 LOGV("PGC: found map for %s.%s 0x%04x (t=%d)\n",
3647 method->clazz->descriptor, method->name, addr,
3648 thread->threadId);
3649 }
3650 } else {
3651 /*
3652 * No map found. If precise GC is disabled this is
3653 * expected -- we don't create pointers to the map data even
3654 * if it's present -- but if it's enabled it means we're
3655 * unexpectedly falling back on a conservative scan, so it's
3656 * worth yelling a little.
The Android Open Source Project99409882009-03-18 22:20:24 -07003657 */
3658 if (gDvm.preciseGc) {
Andy McFaddena66a01a2009-08-18 15:11:35 -07003659 LOGVV("PGC: no map for %s.%s\n",
The Android Open Source Project99409882009-03-18 22:20:24 -07003660 method->clazz->descriptor, method->name);
3661 }
3662 regVector = NULL;
3663 }
3664
3665 if (regVector == NULL) {
3666 /* conservative scan */
3667 for (i = method->registersSize - 1; i >= 0; i--) {
3668 u4 rval = *framePtr++;
3669 if (rval != 0 && (rval & 0x3) == 0) {
3670 dvmMarkIfObject((Object *)rval);
3671 }
3672 }
3673 } else {
3674 /*
3675 * Precise scan. v0 is at the lowest address on the
3676 * interpreted stack, and is the first bit in the register
3677 * vector, so we can walk through the register map and
3678 * memory in the same direction.
3679 *
3680 * A '1' bit indicates a live reference.
3681 */
3682 u2 bits = 1 << 1;
3683 for (i = method->registersSize - 1; i >= 0; i--) {
3684 u4 rval = *framePtr++;
3685
3686 bits >>= 1;
3687 if (bits == 1) {
3688 /* set bit 9 so we can tell when we're empty */
3689 bits = *regVector++ | 0x0100;
3690 LOGVV("loaded bits: 0x%02x\n", bits & 0xff);
3691 }
3692
3693 if (rval != 0 && (bits & 0x01) != 0) {
3694 /*
3695 * Non-null, register marked as live reference. This
3696 * should always be a valid object.
3697 */
3698#if WITH_EXTRA_GC_CHECKS > 0
3699 if ((rval & 0x3) != 0 ||
3700 !dvmIsValidObject((Object*) rval))
3701 {
3702 /* this is very bad */
3703 LOGE("PGC: invalid ref in reg %d: 0x%08x\n",
3704 method->registersSize-1 - i, rval);
3705 } else
3706#endif
3707 {
3708 dvmMarkObjectNonNull((Object *)rval);
3709 }
3710 } else {
3711 /*
3712 * Null or non-reference, do nothing at all.
3713 */
3714#if WITH_EXTRA_GC_CHECKS > 1
3715 if (dvmIsValidObject((Object*) rval)) {
3716 /* this is normal, but we feel chatty */
3717 LOGD("PGC: ignoring valid ref in reg %d: 0x%08x\n",
3718 method->registersSize-1 - i, rval);
3719 }
3720#endif
3721 }
3722 }
3723 dvmReleaseRegisterMapLine(pMap, regVector);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003724 }
3725 }
The Android Open Source Project99409882009-03-18 22:20:24 -07003726 /* else this is a break frame and there is nothing to mark, or
3727 * this is a native method and the registers are just the "ins",
3728 * copied from various registers in the caller's set.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003729 */
3730
The Android Open Source Project99409882009-03-18 22:20:24 -07003731#if WITH_EXTRA_GC_CHECKS > 1
3732 first = false;
3733#endif
3734
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003735 /* Don't fall into an infinite loop if things get corrupted.
3736 */
3737 assert((uintptr_t)saveArea->prevFrame > (uintptr_t)framePtr ||
3738 saveArea->prevFrame == NULL);
3739 framePtr = saveArea->prevFrame;
3740 }
3741}
3742
3743static void gcScanReferenceTable(ReferenceTable *refTable)
3744{
3745 Object **op;
3746
3747 //TODO: these asserts are overkill; turn them off when things stablize.
3748 assert(refTable != NULL);
3749 assert(refTable->table != NULL);
3750 assert(refTable->nextEntry != NULL);
3751 assert((uintptr_t)refTable->nextEntry >= (uintptr_t)refTable->table);
3752 assert(refTable->nextEntry - refTable->table <= refTable->maxEntries);
3753
3754 op = refTable->table;
3755 while ((uintptr_t)op < (uintptr_t)refTable->nextEntry) {
3756 dvmMarkObjectNonNull(*(op++));
3757 }
3758}
3759
3760/*
3761 * Scan a Thread and mark any objects it references.
3762 */
3763static void gcScanThread(Thread *thread)
3764{
3765 assert(thread != NULL);
3766
3767 /*
3768 * The target thread must be suspended or in a state where it can't do
3769 * any harm (e.g. in Object.wait()). The only exception is the current
3770 * thread, which will still be active and in the "running" state.
3771 *
3772 * (Newly-created threads shouldn't be able to shift themselves to
3773 * RUNNING without a suspend-pending check, so this shouldn't cause
3774 * a false-positive.)
3775 */
3776 assert(thread->status != THREAD_RUNNING || thread->isSuspended ||
3777 thread == dvmThreadSelf());
3778
3779 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_THREAD_OBJECT, thread->threadId);
3780
3781 dvmMarkObject(thread->threadObj); // could be NULL, when constructing
3782
3783 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_NATIVE_STACK, thread->threadId);
3784
3785 dvmMarkObject(thread->exception); // usually NULL
3786 gcScanReferenceTable(&thread->internalLocalRefTable);
3787
3788 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_LOCAL, thread->threadId);
3789
3790 gcScanReferenceTable(&thread->jniLocalRefTable);
3791
3792 if (thread->jniMonitorRefTable.table != NULL) {
3793 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JNI_MONITOR, thread->threadId);
3794
3795 gcScanReferenceTable(&thread->jniMonitorRefTable);
3796 }
3797
3798 HPROF_SET_GC_SCAN_STATE(HPROF_ROOT_JAVA_FRAME, thread->threadId);
3799
3800 gcScanInterpStackReferences(thread);
3801
3802 HPROF_CLEAR_GC_SCAN_STATE();
3803}
3804
3805static void gcScanAllThreads()
3806{
3807 Thread *thread;
3808
3809 /* Lock the thread list so we can safely use the
3810 * next/prev pointers.
3811 */
3812 dvmLockThreadList(dvmThreadSelf());
3813
3814 for (thread = gDvm.threadList; thread != NULL;
3815 thread = thread->next)
3816 {
3817 /* We need to scan our own stack, so don't special-case
3818 * the current thread.
3819 */
3820 gcScanThread(thread);
3821 }
3822
3823 dvmUnlockThreadList();
3824}
3825
3826void dvmGcScanRootThreadGroups()
3827{
3828 /* We scan the VM's list of threads instead of going
3829 * through the actual ThreadGroups, but it should be
3830 * equivalent.
3831 *
Jeff Hao97319a82009-08-12 16:57:15 -07003832 * This assumes that the ThreadGroup class object is in
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08003833 * the root set, which should always be true; it's
3834 * loaded by the built-in class loader, which is part
3835 * of the root set.
3836 */
3837 gcScanAllThreads();
3838}