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