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