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