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