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