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